[Tex/LaTex] Using fixed space aroung headings to get text in sync with baseline grid

grid-typesettingsectioningtitlesec

In order to make my text stay in sync with the baseline grid, I've set the vertical spacing before and after \section headings to integer multiples of \baselineskip (using the titlesec package). A \section heading, in this example, is preceded by exactly two, and followed by exactly one blank line (as suggested by Robert Bringhurst). TeX's vertical stretching and shrinking might have its advantages, but those are less relevant to this particular project, which consists of no vertical material but plain text and headings, and which requires proper grid-typesetting. Oh, and there's only one font size throughout the entire book.

Now, \subsection headings I'd like to be preceded by 1.5\baselineskip, and followed by 0.5\baselineskip. Consider the MWE below. Everything's fine as long as the start of a new \subsection doesn't coincide with a new page — in which case the 1.5\baselineskip gets gobbled, causing the remaining text to fall out of sync with the grid. Of course, that's what you'd expect, but I'm wondering if there's a way to change it; to make 0.5 of these 1.5\baselineskip indigestible, in order to have the heading fall between two lines, but have the first line of the text be in sync again.

All I've come up with so far is a workaround, or rather a somewhat dirty hack, which inserts a thick white rule before the heading. Besides being somewhat dirty, though, it has the drawback of (1) relying on a number determined by trial & error (0.6\baselineskip), which might be wrong when other factors change and (2) not working properly when a subsection does not start at the top of a new page (it un-syncs the text on page 3).

Any other ideas are appreciated, thanks in advance! They don't have to rely on titlesec by the way, which is something I've been living without so far.

\documentclass[paper=a5,pagesize]{scrartcl}
\usepackage{blindtext,xcolor,tikz,eso-pic,titlesec}

\setkomafont{section}{\normalsize}

% baseline grid
\AddToShipoutPicture{%
\AtTextLowerLeft{
    \begin{tikzpicture}[overlay,remember picture]%
        \draw[red!10!white,thin]%
             (current page.south west) grid[step=\baselineskip]%
             (current page.north east);%
    \end{tikzpicture}%
    }%
}

% spacing for headings
\titlespacing*{\section}{0em}{2\baselineskip}{\baselineskip}
\titlespacing*{\subsection}{0em}{1.5\baselineskip}{0.5\baselineskip}
\titlespacing*{\subsubsection}{0em}{\baselineskip}{0em}

%% workaround
%\titlespacing*{\subsection}{0em}{1\baselineskip}{0.5\baselineskip}
%\titleformat{\subsection}{\sectfont{\color{white}\titlerule[0.6\baselineskip]}}{\thesubsection}{1ex}{}


\begin{document}
\section{Lorem Ipsum}
\Blindtext
\subsection{Lorem Ipsum}
\Blindtext\newpage
\subsection{Lorem Ipsum}
\Blindtext
\subsubsection{Lorem Ipsum}
\Blindtext
\end{document}

edit/update

What follows is a second improvement of the workaround (but a workaround it remains nevertheless), now in a complete MWE:

\documentclass[paper=a5,pagesize]{scrartcl}
\usepackage{xcolor,tikz,eso-pic,titlesec,blindtext}
\setkomafont{section}{\normalfont}
\setkomafont{subsection}{\normalfont}
\setkomafont{subsubsection}{\normalfont}

% baseline grid
\AddToShipoutPicture{%
\AtTextLowerLeft{
\begin{tikzpicture}[overlay,remember picture]%
\draw[red!10!white,thin]%
 (current page.south west) grid[step=\baselineskip]%
 (current page.north east);%
 \end{tikzpicture}%
 }%
}

% spacing for headings
\titlespacing*{\section}{0em}{2\baselineskip}{\baselineskip}
\titlespacing*{\subsection}{0em}{1\baselineskip}{0.5\baselineskip}
\titlespacing*{\subsubsection}{0em}{\baselineskip}{0em}

%% workaround
\titleformat{\subsection}{\vspace{0.85\baselineskip}\vspace*{-0.35\baselineskip}}{\thesubsection}{1ex}{}

\begin{document}
\section{Lorem Ipsum}
\Blindtext
\subsection{Lorem Ipsum}
\Blindtext\newpage
\subsection{Lorem Ipsum}
\Blindtext
\subsubsection{Lorem Ipsum}
\Blindtext
\end{document}

heading lowered by ca. 0.5\baselineskip

update, Feb 21

(in reply to Hendrik's answer)
sorry, I was a bit too sloppy in testing your solution, Hendrik. The \topskip trick does work fine if the page break that comes before the new subsection is a manual one (as in the example), but if the page breaks automatically (as it does in real life when the page preceding the heading is full), the heading is on the first baseline rather than offset by 0.5\baselineskip — the space gets eaten as usual. See here:

\begin{document}
\section{Lorem Ipsum}
\Blindtext
\subsection{Lorem Ipsum}
\Blindtext\newpage
\subsection{Lorem Ipsum}
\Blindtext
\subsection{Lorem Ipsum}
\blindtext\blindtext\blindtext\blindtext
\subsection{Lorem Ipsum} % <---------------- !
\blindtext
\end{document}

I'm not saying the \topskip approach is a bad idea; I currently just don't have a idea how to improve it.

Best Answer

(Posting this as a separate answer as it offers a completely different solution.)

There's a very simple solution to your problem that should also work in more complex situations involving footnotes and other stuff: put one \baselineskip before and after the subsection heading (so that everything is on the grid), and use \raisebox to lower both the number and the title by 0.5\baselineskip.

text is on the grid

Note the optional arguments [0pt][0pt] to \raisebox: they make the height and in particular the depth of the heading zero so that the subsequent lines stay on the grid.

\documentclass[paper=a5,pagesize]{scrartcl}
\usepackage{blindtext,xcolor,tikz,eso-pic,titlesec}
\setkomafont{section}{\normalsize}
% baseline grid
\AddToShipoutPicture{%
\AtTextLowerLeft{
    \begin{tikzpicture}[overlay,remember picture]%
        \draw[red!10!white,very thin]%
             (current page.south west) grid[step=\baselineskip]%
             (current page.north east);%
    \end{tikzpicture}%
    }%
}
% spacing for headings
\titlespacing*{\section}{0em}{2\baselineskip}{\baselineskip}
\titlespacing*{\subsection}{0em}{\baselineskip}{\baselineskip}
\titlespacing*{\subsubsection}{0em}{\baselineskip}{0em}
\titleformat{\subsection}
            {\sffamily\bfseries}
            {\raisebox{-0.5\baselineskip}[0pt][0pt]{\thesubsection}}
            {1ex}
            {\raisebox{-0.5\baselineskip}[0pt][0pt]} % raise the title
\begin{document}
\section{Lorem Ipsum}
\Blindtext\newpage
\subsection{Lorem Ipsum}
\Blindtext
\subsection{Lorem Ipsum}
\blindtext\blindtext\blindtext\blindtext
\subsection{Lorem Ipsum} % Works now!
\blindtext
\end{document}