2

I'm using a variant of Example 5 – complex example with TikZ from the mdframed manual in a scrbook document. The goal is to include easily distinguishable boxes that contain exercises, definitions, etc. in a text book.

The style I have adopted from the manual makes the mdframed boxes run into the space that scrbook reserves for its header. This happens only when the mdframed element is being produced as the first box on a new page. I think the problem is caused by the inclusion of an element that is 10mm in height at the node (P-|O), so it runs about 5mm into the header.

I tried to understand how mdframed defines nodes like (P) or (P-|O), but have a hard time figuring them out. Also, I think the solution would be an extension of the element's bounding box. Although I think that I understand the concept of a bounding box, I don't know how I could extend the mdframed element's bounding box by -5mm (nor of any other node, for that matter).

Here's an screenshot of the problem, together with some MWE code. The screenshot contains a Screen Ruler for convenience.

(Btw, I think that the problem also occurs with the Example 5 code from the mdframed manual, only that it's more visible in my adaptation since the original vertical space is much smaller).

enter image description here

\documentclass{scrbook}
\usepackage[papersize={170mm,240mm}
            ,top=25mm
            ,inner=20mm
            ,outer=25mm
            ,marginparwidth=50pt
            ]{geometry}
\usepackage[framemethod=tikz]{mdframed}
            \mdfsetup{skipabove=2\baselineskip,skipbelow=2\baselineskip,frametitlefont=\sffamily\bfseries\Large, needspace=4\baselineskip, splittopskip=1.5\baselineskip}
            \mdfsetup{apptotikzsetting={\tikzset{mdfbackground/.append style={draw=none}}}} 
            \mdfdefinestyle{greyexercise}{%
            everyline=true,ignorelastdescenders=true,
            linewidth=0pt,backgroundcolor=black!20,
            innerleftmargin=5mm, innerrightmargin=5mm, innerbottommargin=5mm, innertopmargin=5mm,
            frametitleaboveskip=15mm, frametitlebelowskip=5mm,frametitlerule=false, repeatframetitle=false,
            firstextra={\useasboundingbox (P) rectangle (P);\node[xshift=5mm,right,draw=black!20, line width=1.5pt,rectangle, minimum size=10mm, fill=white] at (P-|O) {\color{black!20}%\includegraphics[width=10mm]{.pdf}
                };},
            singleextra={\useasboundingbox (P) rectangle (P);\node[xshift=5mm,right,draw=black!20, line width=1.5pt,rectangle, minimum size=10mm, fill=white] at (P-|O) {\color{black!20}%\includegraphics[width=10mm]{.pdf}
                };}
            }
\usepackage{lipsum,xcolor}  

\begin{document}

\chapter{Witchcraft in Transylvania}
\section{Origins 1840--1843}
\lipsum[1-7]
\begin{mdframed}[style=greyexercise,frametitle=Exercises]
        \lipsum[1]
\end{mdframed}
\end{document}  

Edit

A user suggested removing \useasboundingbox. While this nicely resolves the header distance issue, it may lead mdframed's page breaking algorithm to disfunction (see screenshot). This appears to happen in cases of rather big mdframed boxes (the box in the screenshot has content \lipsum[1-6].enter image description here

  • Are you sticking to mdframed or will tcolorbox be an alternative? – user31729 Mar 17 '18 at 21:35
  • @ChristianHupfer I would be willing to use tcolorbox instead. Are you sure that the problem is unique to mdframed? Also, will tcolorbox be able to provide a generic solution? This is a key requirement to me, since the text book contains several dozens of boxes. – Felix Emanuel Mar 18 '18 at 16:14
  • I cannot promise that tcolorbox is better here. It's the package I know much better than mdframed. What do you mean with generic solution? – user31729 Mar 18 '18 at 16:15
  • By ``generic'' I mean a solution which requires few to none user inputs, especially concerning the spacing above the box. So a solution that would add the missing space by manual inputs outside the mdframed elements (e.g. a \vspace) would be working theoretically, but would require me checking every greyexercise instance. – Felix Emanuel Mar 18 '18 at 16:26
3

Your \useasboundingbox is hiding the height of the inset square. Just remove it, or make a better choice of bounding box size. Removing it gives

Sample output

\documentclass{scrbook}
\usepackage[papersize={170mm,240mm}
            ,top=25mm
            ,inner=20mm
            ,outer=25mm
            ,marginparwidth=50pt
            ]{geometry}
\usepackage[framemethod=tikz]{mdframed}

\mdfsetup{skipabove=2\baselineskip,skipbelow=2\baselineskip,frametitlefont=\sffamily\bfseries\Large, needspace=4\baselineskip, splittopskip=1.5\baselineskip}
\mdfsetup{apptotikzsetting={\tikzset{mdfbackground/.append style={draw=none}}}}
\mdfdefinestyle{greyexercise}{%
  everyline=true,ignorelastdescenders=true,
  linewidth=0pt,backgroundcolor=black!20,
  innerleftmargin=5mm, innerrightmargin=5mm, innerbottommargin=5mm,
  innertopmargin=5mm,
  frametitleaboveskip=15mm,
  frametitlebelowskip=5mm,frametitlerule=false,
  repeatframetitle=false,
  firstextra={\node[xshift=5mm,right,draw=black!20, line width=1.5pt,rectangle, minimum size=10mm, fill=white] at (P-|O) {\color{black!20}%\includegraphics[width=10mm]{.pdf}
  };},
  singleextra={\node[xshift=5mm,right,draw=black!20, line width=1.5pt,rectangle, minimum size=10mm, fill=white] at (P-|O) {\color{black!20}%\includegraphics[width=10mm]{.pdf}
  };}
}
\usepackage{lipsum,xcolor}

\begin{document}

\chapter{Witchcraft in Transylvania}
\section{Origins 1840--1843}
\lipsum[1-7]
\begin{mdframed}[style=greyexercise,frametitle=Exercises]
  \lipsum[1]
\end{mdframed}
  \lipsum[2-3]
\begin{mdframed}[style=greyexercise,frametitle=Further exercises]
  \lipsum[1]
\end{mdframed}
\end{document}

The combination \useasboundingbox (P) rectangle (P) is producing a rectangle with bottom left corner at (P) and top right corner at the same point (P), so of zero height and width. You can make a box of height 1cm based at (P) with

 \useasboundingbox (P) rectangle +(0,1);

However, you note that long versions of such framed environments have bad breaks. This is because of the linewidth not matching the extra space required by the new bounding box. One approach is to add

middlelinewidth=0pt,linecolor=white,outerlinewidth=5mm,
leftline=false,rightline=false,bottomline=false,

adding at top line of width 5mm corresponding to the part of the box extending above the environment.

New sample

Second sample

\documentclass{scrbook}
\usepackage[papersize={170mm,240mm}
            ,top=25mm
            ,inner=20mm
            ,outer=25mm
            ,marginparwidth=50pt
            ]{geometry}
\usepackage{xcolor}
\usepackage[framemethod=tikz]{mdframed}

\mdfsetup{skipabove=2\baselineskip,
  skipbelow=2\baselineskip,
  frametitlefont=\sffamily\bfseries\Large,
  needspace=4\baselineskip,
  splittopskip=1.5\baselineskip}

\mdfsetup{apptotikzsetting={\tikzset{mdfbackground/.append style={draw=none}}}}

\mdfdefinestyle{greyexercise}{%
  everyline=true,
  ignorelastdescenders=true,
  middlelinewidth=0pt,linecolor=white,outerlinewidth=5mm,
  leftline=false,rightline=false,bottomline=false,
  backgroundcolor=black!20,
  innerleftmargin=5mm, innerrightmargin=5mm,
  innerbottommargin=5mm,
  innertopmargin=5mm,
  frametitleaboveskip=15mm,
  frametitlebelowskip=5mm,frametitlerule=false,
  repeatframetitle=false,
  firstextra={\node[xshift=5mm,right,draw=black!20, line width=1.5pt,rectangle, minimum size=10mm, fill=white] at (P-|O) {\color{black!20}%\includegraphics[width=10mm]{.pdf}
  };},
  singleextra={\node[xshift=5mm,right,draw=black!20, line width=1.5pt,rectangle, minimum size=10mm, fill=white] at (P-|O) {\color{black!20}%\includegraphics[width=10mm]{.pdf}
  };}
}
\usepackage{lipsum}

\begin{document}

\chapter{Witchcraft in Transylvania}
\section{Origins 1840--1843}
\lipsum[1-7]
\begin{mdframed}[style=greyexercise,frametitle=Exercises]
  \lipsum[1]
\end{mdframed}
  \lipsum[2-3]
\begin{mdframed}[style=greyexercise,frametitle=Further exercises]
  \lipsum[1-10]
\end{mdframed}

\end{document}

Just for fun here is an implementation using tcolorbox instead of mdframed. The initial impression is that this behaves better:

tcolor at page break

tcolor broken

\documentclass{scrbook}
\usepackage[papersize={170mm,240mm}
            ,top=25mm
            ,inner=20mm
            ,outer=25mm
            ,marginparwidth=50pt
            ]{geometry}

\usepackage{xcolor}

\usepackage{tcolorbox}
\tcbuselibrary{breakable,skins}

\newcommand{\nodecode}{\path (frame.north west)
  node[xshift=10mm, yshift=0mm, right, draw=black!20,
  line width=1.5pt, rectangle, minimum size=10mm,
  fill=white] {};}

\newtcolorbox{greyexercise}[1]{title=#1,
  enhanced, breakable, frame hidden,
  before={\par\vfill\penalty-200\vfilneg},
  fonttitle=\sffamily\Large\bfseries,
  coltitle=black, colbacktitle=black!20, colback=black!20,
  detach title, before upper={\vspace{5mm}\tcbtitle\par\vspace{10mm}},
  sharp corners,
  boxsep=5mm, enlarge top initially by=5mm,
  overlay first={\nodecode},
  overlay unbroken={\nodecode},
  lines before break=5
  }

\usepackage{lipsum}

\begin{document}
\chapter{Witchcraft in Transylvania}
\section{Origins 1840--1843}
\lipsum[1-7]
\begin{greyexercise}{Exercises}
  \lipsum[1]
\end{greyexercise}
  \lipsum[2-3]
\begin{greyexercise}{Further exercises}
  \lipsum[1-10]
\end{greyexercise}

\end{document}
  • Thank you! Unfortunately, this breaks mdframed's page breaking algorithm (see edit) – Felix Emanuel Apr 5 '18 at 10:34
  • 1
    Yes, I see the problem. It looks like the discussion of tex.stackexchange.com/q/50877/15925 . Setting (middle/outer/inner) linewidth to a large enough to include space for the header number and putting its color to white, resolves the page breaking problem, but does not give the layout you request. – Andrew Swann Apr 6 '18 at 6:50
  • Attempt now uploaded. – Andrew Swann Apr 6 '18 at 16:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.