Avoiding page breaks shortly after section/subsection headings

There may be a generalisable mechanism: Using e-TeX and its \clubpenalties command. In the following example, patching \@afterheading seems to do the trick.

\documentclass{article}

\usepackage{etex}

\usepackage{etoolbox}
\makeatletter
\patchcmd{\@afterheading}%
    {\clubpenalty \@M}{\clubpenalties 3 \@M \@M 0}{}{}
\patchcmd{\@afterheading}%
    {\clubpenalty \@clubpenalty}{\clubpenalties 2 \@clubpenalty 0}{}{}
\makeatother

\usepackage{blindtext}

\textheight 480pt

\begin{document}

\section{bla}

\blindtext[3]

\section{blubb}

\blindtext

\clearpage

\section{foo}

\blindtext[3]

An extra line.

\section{bar}

\blindtext

\end{document}

UPDATE: egreg has written a detailed explanation of \widowpenalties and \clubpenalties.


I solved this with the needspace and titlesec packages, as in:

\usepackage{titlesec}
\usepackage{needspace}
...
\titleformat{\section}
{\needspace{1in}\Large\bfseries}{\thesection}{1em}{}

Hardcoding 1in is crude -- should probably be a multiple of line height. At any rate, this works great in my documents without the need for hand tuning each section.


You could use needspace. With a bit calculations and tests it shouldn't be too difficult to find sensible values:

\documentclass{article}
\usepackage{lipsum,needspace}

\begin{document}
\lipsum[1] \vspace{27\baselineskip}

\Needspace{7\baselineskip}
\section{Blubb}
\lipsum[1]

\newpage
\lipsum[1] \vspace{28\baselineskip}

\Needspace{7\baselineskip}
\section{Blabb}
\lipsum[1]

\end{document}