# Draw a line within a rectangle

I have the following piece of code:

\tikzstyle{startstop} = [rectangle, rounded corners, minimum width=1.5cm, minimum height=0.5cm,text centered, draw=black, fill=white]


Which is a simple rectangle. I would like to draw a straight horizontal line inside it, which divides it in two equal parts, and write something in them (therefore above and below the straight line). Is that possible within this \tikzstyle ?

Try with the shapes.multipart library of tikz

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.multipart}
\begin{document}
\tikzset{
split/.style={rectangle split, rectangle split parts=2,draw,
minimum width=1.5cm,rounded corners,minimum height=1cm,
text width=2cm,align=center,inner ysep=2cm}
}

\begin{tikzpicture}
\node[split] at (8,0) { A \nodepart{two} BBBBBBB\\ BBBB};
\end{tikzpicture}

\end{document}


Another possibility is to use a matrix, in which case you can add any directives to the cells.

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{matrix,calc}
\begin{document}
\begin{tikzpicture}
\matrix[matrix of nodes,nodes={text height=0.5cm,text width=0.5cm,align=center},draw,rounded corners] (mat)
{  A \\
{B \\ C} \\
};
\path ($(mat-1-1.south)!0.5!(mat-2-1.north)$) coordinate (aux);
\draw (aux -|mat.west) -- (aux -|mat.east);
\end{tikzpicture}
\end{document}


Or you can just use fit to draw a contour around two stacked nodes, to which you can pass any parameters you like.

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{positioning,fit}
\begin{document}
\begin{tikzpicture}
\node (A) {A};
\node[below=1mm of A,align=center,text height=8mm] (B) {B\\ C};
\node[fit=(A) (B),draw,rounded corners] (mat){};
\path (A.south) -- (B.north) coordinate[midway] (aux);
\draw (aux -|mat.west) -- (aux -|mat.east);
\end{tikzpicture}
\end{document}


• Hi, thanks, it works, but I do not know how to change the height of the rectangles. The height changes automatically on the basis of what I write inside, but if I add minimum height=4cm it does not change anything – learner Sep 26 '18 at 13:55
• Sorry, no idea at the moment, it is already answered for horizont split nodes here but I did not figure it out for your case – BambOo Sep 26 '18 at 14:55
• @marmot, I was assuming the OP would adapt these parameters, I updated the code though. Do you have any idea regarding the size of the boxes ? I tried with \vphantom call, without sucess – BambOo Sep 26 '18 at 16:08
• @marmot, thanks. I understand your point, \vphantom was really my prefered choice, but I guess it does not work for multiline text in the node, I am not certain of this though. – BambOo Sep 26 '18 at 16:43
• +1 because in two out of three examples you use the nice border=3.14mm. ;-) – user121799 Sep 26 '18 at 17:08

As @BambOo 's examples show, there are a variety of ways of approaching this. Here's yet another approach.

I tend to like to keep the content of my document as clean as possible and hide all the messy inner-workings else where. Even for a one-off because invariably I find myself reusing that code at some point.

So my approach would be to define a command that takes three arguments: the first argument is the width, the second argument is the content of the top box, and the third argument is the content of the bottom box.

\aeboxtwo{this is my first  box\\and more stuff}
{this is my second box:\\[2\baselineskip]
GALLIA est omnis
divisa in partes tres, quarum unam incolunt Belgae,
aliam Aquitani, tertiam qui ipsorum lingua Celtae,
nostra Galli appellantur. Hi omnes lingua,
institutis, legibus inter se differunt.  Gallos ab
Aquitanis Garumna flumen, a Belgis Matrona et
Sequana dividit.}%%


and then produce

Here's the full code to create this:

\documentclass[border=6pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}

\newsavebox\aeboxA
\newsavebox\aeboxB
\newcommand\createbox[3]{%%
\begin{lrbox}#1
\begin{minipage}{#2}
\centering #3
\end{minipage}%%
\end{lrbox}}
\newcommand\aeboxtwo[3][4in]{%%
\begingroup
\createbox\aeboxA{#1}{#2}%%
\createbox\aeboxB{#1}{#3}%%
%% get the total height of the tallest box
\pgfmathsetmacro\aeht{max(\ht\aeboxA+\dp\aeboxA,\ht\aeboxB+\dp\aeboxB)}%%
\def\aeinnersep{4pt}%%
\begin{tikzpicture}[%%
box/.style={inner sep=\aeinnersep,
outer sep=0pt,
minimum height=(2*\aeinnersep) + \aeht,
}]
\node[box]              (top)                {\usebox\aeboxA};
\node[box,anchor=north] (bot) at (top.south) {\usebox\aeboxB};
\draw[rounded corners] (top.north west) rectangle (bot.south east);
\coordinate (mid) at ($(top.north west)!0.5!(bot.south west)$);
\draw (mid) -- (mid-|top.north east);
%\draw[line width=4pt,blue] (top.north) -- (top.south);
%\draw[line width=4pt,red]   ([xshift=4pt]bot.north) -- ([xshift=4pt]bot.south);
\end{tikzpicture}
\endgroup
}

\begin{document}

\aeboxtwo{this is my first  box\\and more stuff}
{this is my second box:\\[2\baselineskip]
GALLIA est omnis
divisa in partes tres, quarum unam incolunt Belgae,
aliam Aquitani, tertiam qui ipsorum lingua Celtae,
nostra Galli appellantur. Hi omnes lingua,
institutis, legibus inter se differunt.  Gallos ab
Aquitanis Garumna flumen, a Belgis Matrona et
Sequana dividit.}%%

\end{document}


I tend to underutilize TikZ text node formatting capacities. On the one hand, this is because for the documents I create, I like to perform various manipulations of the content of my paragraphs to a degree that using TikZ node syntax just creates headaches.

On the other hand, I also have a strong preference to keep the different parts of my document clearly defined and separate. So, I handle text processing in one part and drawing diagrams in another and then integrate the two in the final product. I find the code easier to read and easier to tweak in the future.

One key issue is how to guarantee that the two boxes are drawn to the same height: namely the height of the tallest box. For me, this is reason enough to separate text from picture. By creating two boxes, \aeboxA and \aeboxB I can measure their total height:

\ht\aeboxA + \dp\aeboxA %% total height is height (above the baseline) + depth


And then use the pgf's clear syntax to find the maximum height between the two boxes.

Another difficulty it sounds like you're encountering is managing the minimum height. It's probably being realized as you want, but is being calculated in a manner you might not be considering. So, even if my code isn't to your liking, I'd suggest playing with it. I've set up parameters in there to allow you play with things a bit to see what happens.

Most likely the issue you're encountering with minimum height is that the value for inner sep is also a part of this height. If inner sep=0, well then there's no problem. But, if you're like me, you may like a fair amount of white space to form borders.

My approach here was to set the minimum height to the total height of the tallest box plus twice the inner sep. That way I don't have to know ahead of time which box is the taller or what that height is.

This answer is really for you to play with and get a better sense of where what is happening.

So, adjust the value of \aeinnersep and perhaps rewrite the line

minimum height=(2*\aeinnersep) + \aeht,


to

minimum height=\aeht,


and then uncomment the last two \draw commands in the definition of \aeboxtwo. This way you might get a better picture of what's going on. In particular, for the case where inner sep is nonzero, you'll notice that the horizontal line drawn between the two boxes isn't really in the center if you've not take the value of inner sep into consideration when setting the minimum height.

I hope this helps clarify things. Probably the split node approach is more suited to your needs. I'm just hoping this answer can help you see what's happening with inner sep and minimum height. And,... perhaps it can help illustrate a certain value in separating out text formatting from drawing pictures (or rectangles).