[Tex/LaTex] Package mdframed vertical space difference

mdframed

In the example below I used mdframed to surround my text with a box. The problem is that the vertical space above is different than the space below the box. I found one way to solve it with \vspace*{} but I wonder if this is the correct way.

Is there a better way to do it? Also why the space below the box is bigger than the space above?

(The version of mdframed is 1.9b)

\documentclass[12pt,a4paper]{article}
\usepackage[utf8x]{inputenc}

\usepackage[framemethod=TikZ]{mdframed}
\parindent0mm

\begin{document}

test1
\begin{mdframed}[skipabove=0pt,skipbelow=0pt]
  Das ist ein toller satz
\end{mdframed}
%\vspace*{-16pt}
test2 test test 

\end{document}

Best Answer

Part of the problem can be resolved by placing an \unskip after the environment. But that still leaves a small gap (see follow-up explanation). Note also that the \vspace "fix" that you employ will work when a tall letter appears on the next line; however, a line of short letters, aaaa, will still show a gap, and something as tall as a \strut will overlap the bottom of the framed environment. That is to say, the \vspace fix is not universal, but depends on the content following the frame.

But, to basically automate what you were already doing, I redefined the end of the mdframed environment to add an \unskip followed by a 6pt negative \vspace.

\documentclass[12pt,a4paper]{article}
\usepackage[utf8x]{inputenc}

\usepackage[framemethod=TikZ]{mdframed}
\parindent0mm
\let\svendmdframed\endmdframed
\makeatletter
\def\endmdframed{\svendmdframed\unskip\vspace{-6pt}}
\makeatother
\begin{document}

test1
\begin{mdframed}[skipabove=0pt,skipbelow=0pt]
  Das ist ein toller satz
\end{mdframed}
test2 test test

\end{document}

In the "FURTHER EXPLANATION" below, I argue that the amount of \vspace needs to depend on the height of what follows the frame. So here, I have created an MWE to do that, where the line that follows is passed to \adjustframe, so that the proper \vspace adjustment can be made. Note though, that this will only work if the line that follows is less than the strut height, because various interline glues come into play beyond that point.

\documentclass[12pt,a4paper]{article}
\usepackage[utf8x]{inputenc}
\usepackage[framemethod=TikZ]{mdframed}
\parindent0mm
\let\svendmdframed\endmdframed
\def\endmdframed{\svendmdframed\unskip}
\newcommand\adjustframe[1]{\setbox0=\hbox{#1}%
  \vspace{\dimexpr-\baselineskip+\ht0}#1}
\begin{document}
\fboxsep=0pt
\fboxrule=.2pt
test1g
\begin{mdframed}[skipabove=0pt,skipbelow=0pt]
  Das ist ein toller satz
\end{mdframed}
\adjustframe{test2 test test}
\begin{mdframed}[skipabove=0pt,skipbelow=0pt]
  Das ist ein toller satz
\end{mdframed}
\adjustframe{aaaaaa}

\begin{mdframed}[skipabove=0pt,skipbelow=0pt]
  Das ist ein toller satz
\end{mdframed}
\adjustframe{\rule{1ex}{2.7ex}xyz}
\end{document}

enter image description here


FURTHER EXPLANATION:

To take a closer look at things, consider the solution with the \unskip, but without the \vspace, and an extra paragraph added at the end:

enter image description here

The blank space below the frame is the same as the blank space between paragraphs. This is as you would expect with no "additional" space added. The gap above the frame can be shrunk to zero, because the frame can "know" the lower extent of the prior row. On the other hand, when the frame ends, and a new baseline must be set, LaTeX doesn't yet have a clue how high the text/object in the coming line will be. I think a \vspace is the only viable option, though as I've said, it will have to be tailored based on what appears on the subsequent line.

If what appears on the coming line is actually tall enough, then the interline spacing is not a factor and the gap shrinks to nothing (+/- some glue), as in this image, where I add a tall \rule to the beginning of the line following the frame:

enter image description here

Finally, the actual proper amount of the \vspace is -\baselineskip plus the height of the tallest item to appear on the next line (but must remain non-positive). If I hardwire that, knowing a "2" to be the tallest item on the next line, by way of

\def\endmdframed{\svendmdframed\unskip\setbox0=\hbox{2}%
  \vspace{\dimexpr-\baselineskip+\ht0}}

the result is what you desire:

enter image description here

BOTTOM LINE: The adjustment of the gap below the frame will inevitably require some sort of assumption on how tall that line's content will be.