# tcolorbox overlays and space needed

I'm moving from mdframed to using tcolorbox, and I'm almost where I want to be.

Using mdframed, I can use the singleextra and firstextra parameters to add nodes to my frame, and this changes the height of the frame as a whole (i.e. if my new node sticks out above the frame, the height of the entire thing is increased; ditto if my new node sticks out below the frame). This makes my life easy.

Using tcolorbox, I can use the overlay parameter to add nodes to the frame, but the size does not adjust automatically. There is, if you include \tcbuselibrary{hooks,skins} (not sure which one exactly does it) an enlarge top by parameter that will add space needed so thew node that sticks out above the frame doesn't overlap previous content.

The MWE below shows the use of an overlay and enlarge top by.

\documentclass{article}
\usepackage{tcolorbox}
\tcbuselibrary{skins,hooks}
\usepackage{lipsum}

\tcbset{
frogbox/.style={
enhanced,
colback=green!10,
colframe=green!65!black,
enlarge top by=5.5mm,
overlay={
\foreach \x in {2cm,3.5cm} {
\begin{scope}[shift={([xshift=\x]frame.north west)}]
\path[draw=green!65!black,fill=green!10,line width=1mm] (0,0) arc (0:180:5mm);
\path[fill=black] (-0.2,0) arc (0:180:1mm);
\end{scope}
}
}
}
}

\tcbset{
app/.style={
overlay app={%
\draw(frame.north)--(frame.south);
}
}
}

\begin{document}

\lipsum[1]
\begin{tcolorbox}[frogbox,title=My title]
This is a \textbf{tcolorbox}.
\end{tcolorbox}

\lipsum[2]
\begin{tcolorbox}[frogbox,app,title=My title]
This is a \textbf{tcolorbox}.\par
Here, we apply a second overlay.
\end{tcolorbox}
\end{document}


Because of the enlarge top by, the eyes don't overlap the text above the frogbox. Remove the enlarge top by, and the eyes do overlap the text above the frogbox.

That all said, is there an alternative to overlay that will account for potentially increased size of the frame+nodes? Is there an easier way to manage this than examining every node that might be added [it's not a static list for every frame of this type, they're markers regarding meta information] to see if the space allocated for the frame needs to be increased?

I could simply assume the new nodes will be present and allocate space for them, and it does look kind of nice to see the frames aligning at the top of the page whether the extra nodes are present or not (my current strategy), but I'd like to explore a more sophisticated presentation, where the extra space is present or not depending on whether the nodes are present. What's an easy way to do this?

• May I ask why you are switching from mdframed, which does what you want, to tcolorbox, which (possibly) does not? – cfr Jan 16 '17 at 1:11
• mdframed does what I want, as far as this point is concerned, and tcolorbox seems to offer capabilities I don't have in mdframed. I thought I'd give it a try. – Keith Davies Jan 16 '17 at 2:25
• tcolorbox takes some efforts to replace the bounding box tracking of tikz by its own mechanism. For your intended use, one would need to reset this to the tikz tracking. Today, I do not have the time to investigate this matter further, but I will try another day. – Thomas F. Sturm Jan 25 '17 at 13:42
• Ah, of course, that would would explain it. I've got a simple workaround in this case because I know how big the additional content is, but I'd welcome your thoughts on a more general solution, @ThomasF.Sturm – Keith Davies Jan 25 '17 at 16:51

I experimented a little bit how to achieve the return to the bounding box tracking of tikz. The solution is quite simple. If you add

\tikzset{overlay=false}


to your overlay code, the tracking is re-established.

Note: No effect in tcolorbox/TikZ that ships with TeX Live 2013. Updating to TeX Live 2106 fixes. Stay current! --kjd

The full code is:

\documentclass{article}
\usepackage{tcolorbox}
\tcbuselibrary{skins,hooks}
\usepackage{lipsum}

\tcbset{
frogbox/.style={
enhanced,
colback=green!10,
colframe=green!65!black,
enlarge top by=5.5mm,
overlay={
\tikzset{overlay=false}%< -----------------------
\foreach \x in {2cm,3.5cm} {
\begin{scope}[shift={([xshift=\x]frame.north west)}]
\path[draw=green!65!black,fill=green!10,line width=1mm] (0,0) arc (0:180:5mm);
\path[fill=black] (-0.2,0) arc (0:180:1mm);
\end{scope}
}
}
}
}

\tcbset{
app/.style={
overlay app={%
\draw([yshift=2cm]frame.north)--(frame.south);
}
}
}

\begin{document}

\lipsum[1]
\begin{tcolorbox}[frogbox,title=My title]
This is a \textbf{tcolorbox}.
\end{tcolorbox}

\lipsum[2]
\begin{tcolorbox}[frogbox,app,title=My title]
This is a \textbf{tcolorbox}.\par
Here, we apply a second overlay.
\end{tcolorbox}
\end{document}


Please, note that I do not expect that this will do any good for breakable boxes. The calculated size will not be identical to the real size and breaking will not look correct.

For unbreakable boxes, this should work, but will interfere with bounding box settings like enlarge top by etc.

• ... it would never have occurred to me to do overlay={\tikzset{overlay=false}}. For my purposes this only applies to boxes that won't be broken, so while it's good to know the restriction, it doesn't apply to my problem. Come to that, I'm using it in a place I've gone to great lengths to not only prevent breaks in the frame, but breaks within some distance after the frame. – Keith Davies Jan 26 '17 at 16:21
• And now confirmed, removed my kludgy solution and added yours, looks like it not only did what I wanted but did it better (see 'kludgy'). – Keith Davies Jan 26 '17 at 16:22
• @KeithDavies I'm glad that this was helpful. Also, while scanning through the tikz sources, I learned something for myself :-) – Thomas F. Sturm Jan 27 '17 at 7:00
• Something for everyone! – Keith Davies Jan 27 '17 at 15:07
• I just found this does not work with the version of tcolorbox/TikZ (not sure which, or if it's the combination) that shipped with TeX Live 2013. Updated to 2016 and it works. – Keith Davies Jan 27 '17 at 17:18