\selectlanguage pushes section to new page
Your guess is right. At the end of \end{itemize}
, an instruction
\addvspace{<skip 1>}
is issued and \section
issues
\addvspace{<skip 2>}
so, in normal situations, only the greater skip results in the output. However, as you observe, the \write
instruction that's part of \selectlanguage
makes it impossible for the second \addvspace
to know the amount of <skip 1>
, because the last item in the vertical list is no longer a vertical skip.
You can manually fix this with
\setlength{\skip0}{\lastskip}
\addvspace{-\skip0}
\selectlanguage{ngerman}
\addvspace{\skip0}
which works for the particular situation.
Output without the four above lines
Note the correct English hyphenation of “representation”.
Output with the four lines above
Note the incorrect English hyphenation of “representation” (due to using German hyphenation rules).
hyperref
tries quite hard to avoid such side effects. You could steal its commands:
\documentclass{article}
\usepackage{kantlipsum}
\usepackage[ngerman,english]{babel}
\usepackage{hyperref}
\begin{document}
\section{Foo}
\kant[1]
\begin{itemize}
\item
\item
\item
\item
\item
\end{itemize}
\kant[2]
\begin{itemize}
\item
\item
\item
\item
\end{itemize}
\makeatletter
\Hy@SaveLastskip
\selectlanguage{english}
\Hy@RestoreLastskip
\makeatother
\section{Baz}
\kant[1]
\end{document}
(It is not perfect, in some cases it then suppress a break point).