[Tex/LaTex] How to make \titlespacing not omit the top spacing

page-breakingsectioningspacingtitlesec

In a multicols*{2} environment for 12pt linehight text, I use

\titlespacing*{\subsection}{0pt}{12pt}{12pt}

To create exactly 12pt of space before and after subsections. Together with a line height of 12pt for the subsection font this creates 36pt-height subsections, which covers 3 lines of ordinary text.

This works fine anywhere on the page but not if a subsections happens to be on the top of a column, where the top-spacing is automatically omitted. I want to enforce 36pt total height wherever the section happens to be.

How can I make \titlespacing not omit the top spacing at the top of a column?

Update 2:

I edited the question to use 12pt, as the suggested solutions seem to not cover all cases so far or introduce slightly wrong gaps (+/- ~2pt) that are not easily visible if too artificial pointsizes are used. The following MWE now uses 12pt lines and covers all three relevant cases: headline within column, on top of column 1 and on to on column 2.

\documentclass[12pt]{article}

\usepackage{lipsum} 
\usepackage{multicol} 

\usepackage[compact]{titlesec}  

\titleformat{\subsection}
  {\fontsize{10pt plus 0pt minus 0pt}{12pt plus 0pt minus 0pt}\selectfont\bf} % format
  {} % label
  {0pt} %sep
  {} %after

\titlespacing*{\subsection}{0pt}{12pt}{12pt}

\begin{document}

\fontsize{10pt}{12pt}\selectfont

\begin{multicols}{2}\raggedcolumns

\subsection*{Bad Section}
\lipsum[1-2]
\columnbreak
\lipsum[1]
\subsection*{Good Section}
\lipsum[2]

\end{multicols}

\newpage

\begin{multicols}{2}\raggedcolumns

\lipsum[1]
\subsection*{Good Section}
\lipsum[2]
\columnbreak
\subsection*{Bad Section}
\lipsum[1-2]

\end{multicols}

\end{document}

Best Answer

You may add \vspace{-1cm}\vspace*{1cm} in the proper argument of \titleformat -- the two spaces will offset each other except at the top of a page. This is simpler than tohecz's "box" solution and, unlike egreg's solution, will not result in additional vertical space between a \section and a directly adjoining \subsection. (Note that in this case the \section's "after" space will override the \subsection's "before" space.)

EDIT: For whatever reason, it seems one must also subtract \baselineskip in \vspace*(and re-add it in \vspace).

EDIT2: This is the best I can come up with (a hack for which I lack an explanation):

  1. Within \titleformat, the difference between fonsize and \baselineskip (in your revised example: 2pt) must be subtracted with \vspace and re-added with \vspace*.

  2. For any \subsection immediately after \begin{multicols}, the value of \baselineskip (12pt) must be subtracted with \vspace* in the document body.


\documentclass[12pt]{article}

\usepackage{lipsum} 
\usepackage{multicol} 

\usepackage[compact]{titlesec}  

\titleformat{\subsection}
  {\vspace{\dimexpr -12pt+10pt}\vspace*{\dimexpr 12pt-10pt}%
  \fontsize{10pt plus 0pt minus 0pt}{12pt plus 0pt minus 0pt}\selectfont\bf} % format
  {} % label
  {0pt} %sep
  {} %after

\titlespacing*{\subsection}{0pt}{12pt}{12pt}

\begin{document}

\fontsize{10pt}{12pt}\selectfont

\begin{multicols}{2}\raggedcolumns

\vspace*{-12pt}

\subsection*{Bad Section}
\lipsum[1-2]
\columnbreak
\lipsum[1]
\subsection*{Good Section}
\lipsum[2]

\end{multicols}

\newpage

\begin{multicols}{2}\raggedcolumns

\lipsum[1]
\subsection*{Good Section}
\lipsum[2]
\columnbreak
\subsection*{Bad Section}
\lipsum[1-2]

\end{multicols}

\end{document}
Related Question