# Multicols inside Tcolorbox breaks page before long Multicols (and doesn't listen to pageheight)

As can be shown when compiling the following MWE, the page-height (2inch) allows for 11 lines of text per page (cf. page 1), since Twelfth line and Thirteenth line are sent to page 2.

After those thirteen lines, I introduce another thirteen lines of text, but which are inside a Multicols environment.

1. Explanation of title: Multicols inside Tcolorbox breaks page before long Multicols

The annoying thing is that the Multicol-lines are not added immediately after the previous lines (i.e. First line (inside multicols) doesn't start after Thirteenth line, but instead is sent to the next page because the Multicol is "too long" to fit on the same page).

1. Explanation of title: Multicols inside Tcolorbox doesn't listen to pageheight

Then, one can notice that the lines inside the Tcolorbox actually don't break after 11 lines, but go well beyond that (cf. the lines overflowing on page 3).

Note: I suppose that these behavior are not specifically related to the Tcolorbox (but are instead endemic to Multicols). Anyway, the MWE shows how I figured out the issue, and at the same time the Tcolorbox can clarify some things visually (e.g. page-height).

\documentclass{article}

\usepackage{multicol}
\usepackage[a4paper, total={7in, 2in}]{geometry}
\usepackage[breakable]{tcolorbox}
\newcommand\tbox[1]{\begin{tcolorbox}[breakable]#1\end{tcolorbox}}
\begin{document}

\tbox{

First line\\
Second line\\
Third line\\
Fourth line\\
Fifth line\\
Sixth line\\
Seventh line\\
Eighth line\\
Tenth line\\
Eleventh line\\
Twelfth line\\
Thirteenth line\\

\begin{multicols}{2}

First line (inside multicol)\\
Second line (inside multicol)\\
Third line (inside multicol)\\
Fourth line (inside multicol)\\
Fifth line (inside multicol)\\
Sixth line (inside multicol)\\
Seventh line (inside multicol)\\
Eighth line (inside multicol)\\
Tenth line (inside multicol)\\
Eleventh line (inside multicol)\\
Twelfth line (inside multicol)\\
Thirteenth line (inside multicol)\\ \columnbreak

Next to first line (inside multicol)\\
Next to second line (inside multicol)\\
Next to third line (inside multicol)\\
Next to fourth line (inside multicol)\\
Next to fifth line (inside multicol)\\
Next to sixth line (inside multicol)\\
Next to seventh line (inside multicol)\\
Next to eighth line (inside multicol)\\
Next to tenth line (inside multicol)\\
Next to eleventh line (inside multicol)\\
Next to  twelfth line (inside multicol)\\
Next to thirteenth line (inside multicol)\\

\end{multicols}

}

\end{document}

• I wouldn't have expected multicol to work inside a breakable tcolorbox. tcolorbox puts its material in a large box to find the breakpoints and this clashes with the output routine of multicols. – Ulrike Fischer Apr 17 '16 at 6:39
• @UlrikeFischer Would you know any work-around, please? I am just looking for a possibility to have a line-by-line 2-column-text inside a Tcolorbox (but keep it break-able as usual). – O0123 Apr 17 '16 at 7:37
• The \tbox command is bad, in my point of view -- why not using a \newtcbox command then? – user31729 Apr 17 '16 at 8:31
• @ChristianHupfer Hupfer - Can you show us how that would solve the problem? I used the \tbox (arbitrary name) definition to be able to call for a Tcolorbox without needing to copy-paste a lot of lay-out settings (not visible in the MWE). – O0123 Apr 17 '16 at 9:03
• I did not say that it will solve the problem ;-) – user31729 Apr 17 '16 at 9:04

since you want manual control over the lines anyway, I'd just do

\documentclass{article}

\usepackage{multicol}
\usepackage[a4paper, total={7in, 2in}]{geometry}
\usepackage[breakable]{tcolorbox}
\newcommand\tbox[1]{\begin{tcolorbox}[breakable]#1\end{tcolorbox}}
\newcommand\x[2]{%
\noindent\makebox[.5\textwidth][l]{#1}%
\makebox[.5\textwidth][l]{#2}%
}
\begin{document}

\tbox{

\x{%
First line (inside multicol)}{%
Next to first line (inside multicol)}

\x{%
Second line (inside multicol)}{%
Next to second line (inside multicol)}

\x{%
Third line (inside multicol)}{%
Next to third line (inside multicol)}

\x{%
Fourth line (inside multicol)}{%
Next to fourth line (inside multicol)}

\x{%
Fifth line (inside multicol)}{%
Next to fifth line (inside multicol)}

\x{%
Sixth line (inside multicol)}{%
Next to sixth line (inside multicol)}

\x{%
Seventh line (inside multicol)}{%
Next to seventh line (inside multicol)}

\x{%
Eighth line (inside multicol)}{%
Next to eighth line (inside multicol)}

\x{%
Tenth line (inside multicol)}{%
Next to tenth line (inside multicol)}

\x{%
Eleventh line (inside multicol)}{%
Next to eleventh line (inside multicol)}

\x{%
Twelfth line (inside multicol)}{%
Next to  twelfth line (inside multicol)}

\x{%
Thirteenth line (inside multicol)}{%
Next to thirteenth line (inside multicol)}

}

\end{document}

• Impressive! Could you perhaps beautify the answer (it can make the end-result more legible for long tcolorboxes; it would then show where a "new" tcolorbox starts, which might have a different context given by the writer) by making the top and bottom of the multicol having round borders, but not anywhere else where it is cut to the another page? – O0123 Apr 22 '16 at 0:03

You could do it in two stages. First create a document (test5.pdf) to fit the interior of the tcolorbox. Then copy each page into the tcolorboxes for the final document.

\documentclass{article}
\usepackage[a4paper, total={7in, 2in}]{geometry}
\usepackage{tcolorbox}
\newcounter{box}
\begin{document}

\begin{tcolorbox}[height=\textheight]
text width \tcbtextwidth\par
text height \tcbtextheight\par
\end{tcolorbox}% used to determine page size

\loop\stepcounter{box}%
\tcbset{sharp corners}% default
\ifnum\value{box}=1\relax \tcbset{rounded corners=north}\fi% first page
\ifnum\value{box}=3\relax \tcbset{rounded corners=south}\fi% last page
\begin{tcolorbox}
\includegraphics[page=\thebox]{test5.pdf}%
\end{tcolorbox}
\ifnum\value{box}<3\relax\repeat% 3 pages

\end{document}


where test5.pdf was created using

\documentclass{article}
\usepackage[paperwidth=474.59206pt,paperheight=124.62315pt,margin=0pt]{geometry}
\usepackage{multicol}
\usepackage{lipsum}
\pagestyle{empty}
\begin{document}
\begin{multicols}{2}
\lipsum[1-4]
\end{multicols}
\end{document}


• Very nifty. But, a problem which I find (with regards to lay-out and legibility for some purposes) is that it now seems as if there are 3 seperate Tcolorboxes (what I mean with that is that their rounded borders appear at the bottoms and tops of each Tcolorbox). Could you adapt that as to make only the last Tcolorbox have rounded bottom corners, and to only have the first Tcolorbox have rounded top corners? An example of such cut Tcolorboxes with only partially rounded corners can be found in the images at tex.stackexchange.com/a/223398/67761 – O0123 Apr 17 '16 at 20:37
• With this approach you really don't need a breakable colorbox at all. Each box could be generated independently. You just need \ifnum\value{box} to check for the first and last box. – John Kormylo Apr 18 '16 at 0:48
• I am very impressed with how you have come up with the solution, but as for readability purposes, I think it would be nice to visually communicate with the reader where a Tcolorbox is the continuation of a previous one or not (I use Tcolorboxes for quoted passages). – O0123 Apr 18 '16 at 0:50
• I revised the solution to use sharp corners except on the first and last page. – John Kormylo Apr 18 '16 at 2:05
• Which package(s) should I update to compile please? I get the error: text width \tcbtextwidth. – O0123 Apr 18 '16 at 20:26

I made this a separate answer since it uses a totally different approach (one stage). It provides the environment TwoColumnBox which provides all the features of my previous solution plus it will use whatever space is left in the first page (assuming it is partially filled), and leave unused space on the last page.

Note: I had to use a \parbox to set column width, so things like \parindent and \parskip may need to be set inside the environment.

\documentclass{article}
\usepackage[a4paper, total={7in, 2in},showframe]{geometry}
\usepackage{tcolorbox}
\usepackage{environ}
\usepackage{tikzpagenodes}% for remaning height
\usepackage{lipsum}

\newsavebox{\TCbox}
\newlength{\TCpageheight}
\newlength{\TCheight}
\newlength{\TCwidth}
\newif\ifTCfirstpage

\NewEnviron{TwoColumnBox}[1][]% #1=tcolorbox options (optional)
{\let\columnbreak=\pagebreak
% get remaining height on page
\tikz[overlay,remember picture]{%
\pgfextracty{\TCpageheight}{\pgfpointanchor{current page text area}{south}}%
\global\TCpageheight=\dimexpr-\TCpageheight-0.5\baselineskip\relax}%
\sbox0{\begin{tcolorbox}[height=\TCpageheight,#1]
\global\TCheight=\tcbtextheight
\global\TCwidth=\tcbtextwidth
\end{tcolorbox}}% hidden
\ifdim\TCheight<\baselineskip \TCpageheight=\textheight \fi
% create source column
\TCwidth=\dimexpr 0.5\TCwidth-0.5\columnsep\relax
{\hsize=\TCwidth
\global\setbox\TCbox=\vbox{\strut\BODY}}%
% break column into pages
\TCfirstpagetrue
\loop
\sbox0{\begin{tcolorbox}[height=\TCpageheight,#1]
\global\TCheight=\tcbtextheight
\end{tcolorbox}}% hidden
\tcbset{sharp corners}% default
\ifTCfirstpage
\TCfirstpagefalse
\tcbset{rounded corners=north}%
\TCpageheight=\textheight
\fi
\ifdim\ht\TCbox>2\TCheight
\setbox0=\vsplit\TCbox to \TCheight
\setbox1=\vsplit\TCbox to \TCheight
\begin{tcolorbox}[#1]
\hbox{\box0\hspace{\columnsep}\box1}
\end{tcolorbox}
\else
\TCheight=0.5\ht\TCbox
\setbox2=\copy\TCbox
\setbox0=\vsplit\TCbox to \TCheight
\ifdim\ht\TCbox>\TCheight
\TCheight=\ht\TCbox
\setbox\TCbox=\copy2
\setbox0=\vsplit\TCbox to \TCheight
\fi
\setbox1=\vsplit\TCbox to \TCheight
\begin{tcolorbox}[rounded corners=south,#1]
\hbox{\box0\hspace{\columnsep}\box1}
\end{tcolorbox}
\fi
\ifdim\ht\TCbox>0pt \repeat
}

\begin{document}
test line

\begin{TwoColumnBox}
\lipsum[1-4]
\end{TwoColumnBox}
\end{document}

• I am very curious to see the result! Could you tell us which external .sty needs to be loaded before we can compile your code please? – O0123 Apr 20 '16 at 20:28
• @VincentVerheyen - Just update tcolorbox (my version dated 2/29/2016). – John Kormylo Apr 21 '16 at 4:16
• But it doesn't provide the \columnbreak command? Would that be possible, please? – O0123 Apr 21 '16 at 9:08
• Done. (\let\columnbreak=\pagebreak) – John Kormylo Apr 21 '16 at 14:10
• @pasbi - I removed the \strut before \BODY`, then played a bit to try to better align the columns. – John Kormylo Mar 27 '20 at 16:08