4

This is a followup question to Controlling indent and vertical space at top of a tcolorbox.

@egreg provided a nice solution to the original problem, but there is one side effect when certain environments (probably anything based on a trivlist) appear in the tcolorbox. The spacing above the first environment is missing.

How can I adjust @egreg's answer so that these environments are spaced correctly?

MWE

\documentclass{article}

\usepackage{tcolorbox}

\tcbset{mybox/.style={colback=white, colframe=blue, left=2mm, right=2mm,
  fonttitle=\bfseries}, fontupper=\small,
  before upper=\setlength{\parindent}{1em}\everypar{{\setbox0\lastbox}\everypar{}},
}

\newtcolorbox{mybox}[1][]{mybox,#1}

\begin{document}
\begin{mybox}
  This line should not be indented.

  This line should be indented.

  \begin{center}
    This line should be centred. The spacing above is wrong.
  \end{center}

  This line should be indented.

  \begin{center}
    This line should be centred. The spacing above is right.
  \end{center}

  This line should be indented.
\end{mybox}

\begin{mybox}
  \section{Should not have gap above this heading}
\end{mybox}
\end{document}

MWE output

1 Answer 1

4

The missing vertical space in the inner center environment is because \@item uses \addvspace\@topsep to insert the space you want to have when leaving a blank line before \begin{center}, and \addvspace doesn't add this space when in vertical mode and \if@minipage is true—which is the case inside your mybox. So, in order to have this space inserted, you can set \@minipagefalse in the before upper option of your tcolorbox.

The vertical gap between the two boxes is essentially due to the default for /tcb/noparskip (see documentation of /tcb/autoparskip in the tcolorbox manual). If you set before=\par\noindent, you remove the added \smallskip:

\documentclass{article}
\usepackage{tcolorbox}

\makeatletter

\tcbset{mybox/.style={colback=white, colframe=blue, left=2mm, right=2mm,
  fonttitle=\bfseries}, fontupper=\small,
  before upper={\setlength{\parindent}{1em}%
                \everypar{{\setbox0\lastbox}\@minipagefalse\everypar{}}},
  before=\par\noindent, after=\par
}

\makeatother

\newtcolorbox{mybox}[1][]{mybox,#1}

\begin{document}
\begin{mybox}
  This line should not be indented.

  This line should be indented.

  \begin{center}
    This line should be centered. The spacing above is correct.
  \end{center}

  This line should be indented.

  \begin{center}
    This line should be centered. The spacing above is right.
  \end{center}

  This line should be indented.
\end{mybox}

\begin{mybox}
  \section{Should not have gap above this heading}
\end{mybox}
\end{document}

Screenshot

If you really want to get rid of all the gap, suppress all vertical glue between the two boxes of interest here that are appended to the main vertical list. You can do this using \nointerlineskip, which is correctly used in vertical mode because of the after=\par we set:

\documentclass{article}
\usepackage{tcolorbox}

\makeatletter

\tcbset{mybox/.style={colback=white, colframe=blue, left=2mm, right=2mm,
  fonttitle=\bfseries}, fontupper=\small,
  before upper={\setlength{\parindent}{1em}%
                \everypar{{\setbox0\lastbox}\@minipagefalse\everypar{}}},
  before=\par\noindent, after=\par
}

\makeatother

\newtcolorbox{mybox}[1][]{mybox,#1}

\begin{document}
\begin{mybox}
  This line should not be indented.

  This line should be indented.

  \begin{center}
    This line should be centered. The spacing above is correct.
  \end{center}

  This line should be indented.

  \begin{center}
    This line should be centered. The spacing above is right.
  \end{center}

  This line should be indented.
\end{mybox}
\nointerlineskip
\begin{mybox}
  \section{Should not have gap above this heading}
\end{mybox}
\end{document}

enter image description here

Note: I set the \@minipagefalse inside the temporary \everypar in order not to have extra vertical space inside the box if it starts with a center environment. But if you set it directly at the beginning of before upper, like this:

\tcbset{mybox/.style={colback=white, colframe=blue, left=2mm, right=2mm,
  fonttitle=\bfseries}, fontupper=\small,
  before upper={\@minipagefalse\setlength{\parindent}{1em}%
                \everypar{{\setbox0\lastbox}\everypar{}}},
  before=\par\noindent, after=\par
}

and start your box with a center environment:

\begin{mybox}
  \begin{center}
    This line should be centered. The spacing above is correct.
  \end{center}

  This line should be indented.

  \begin{center}
    This line should be centered. The spacing above is correct.
  \end{center}
...
\end{mybox}

you'll get the extra space at the top of your box, like this:

enter image description here

4
  • Thanks! The space between the boxes is fine. The heading was related to the previous question. I finally see what was causing me grief! I had before upper=\setlength{\parindent}{1em} in my box settings and this doesn't cause the spacing difference. I see now that it does occur in the default tcolorbox :/ My bad. Aug 8, 2019 at 12:26
  • 1
    Glad to see this solves your issue. I added a precision regarding inside spacing at the top of the box.
    – frougon
    Aug 8, 2019 at 12:34
  • Thanks for the clarification. Putting \@minipagefalse inside \everypar{} does what I want. (I think). Aug 8, 2019 at 12:55
  • This literally saved my life after updating tcolorbox and seeing the vertical space. I'm not sure why it wasn't happening before, but the \@minipagefalse did the trick! Aug 24, 2022 at 5:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .