# Width of columns in a table with only multicolumns

I want to create a table with this specific structure:

| b | c | d |
|  f  |  g  |


So basically a table with 1 line which is cut in half and a second line which is cut in thirds.

I have tried to make the table out of 6 columns and use \multicolumn to make bigger cells out of 2 or 3 smaller ones but that does not work. It looks like the reason is that there is no row which has all 6 columns in it, but I have no idea how I can work around this.

Also, I would like to have the overall width of the table flexible so that it adjusts to the texts in the cells.

Edit: Below I've provided a table exactly as I want it. I tried reducing it to the core of the problem I'm facing, but obviously that was a mistake since it created more questions than it soved. Sorry for that. Note: Every content should be centered in its cell.

|     OSI-Schicht        |               Umsetzung              |
----------------------------------------------------------------
----------------------------------------------------------------
|   Anwendungsschicht    |            |            |            |
--------------------------            |            |            |
|  Darstellungsschicht   |   SOME/IP  |  AVB/TSN   |    DoIP    |
--------------------------            |            |            |
|    Sitzungsschicht     |            |            |            |
----------------------------------------------------------------
|   Transportschicht     |        TCP        |       UDP        |
----------------------------------------------------------------
|  Vermittlungsschicht   |        IPv4       |       IPv6       |
----------------------------------------------------------------
|   Sicherungsschicht    |              Ethernet                |
----------------------------------------------------------------
| Bitübertragungsschicht | 100BASE-TX | 100BASE-T1 | 1000BASE-T |
----------------------------------------------------------------

• Welcome to TeX.SE! Should columns b, c, and d be equally wide? Should columns f and g be equally wide? How wide should the table be overall? Should automatic line-breaking be enabled inside cells? Should the cell contents be centered, left-aligned (aka "ragged-right"), fully justified, or arranged in some other way? Please be specific.
– Mico
Mar 3 '17 at 10:38
• Sorry for not being more specific. Yes, b, c and d should be equally wide, as well es f and g. The whole table should be wide enough to fit the text of the cells. Automatic line-breaking would be nice to have, now that you mention it. The contents should be centered. Mar 3 '17 at 10:44
• The criterion "wide enough to fit the text of the cells" isn't sufficient, as we don't know yet what's in the cells. (I take it it's safe to assume that the cells won't contain just single letters...) Please provide more information.
– Mico
Mar 3 '17 at 10:50
• This is perhaps a duplicate of tex.stackexchange.com/questions/354956/… Mar 3 '17 at 11:42
• I've tried to use the solution provided in the link but it does not work in this case. I think it works in the original case because of the exact number of characters in each cell. Since the cells here don't have a regular content it doesn't solve this problem. Mar 3 '17 at 13:02

I suggest to start by determining the (minimum required) column widths of the table:

• It's actually easiest to start with the width of the 2-column cells: This width must be equal to the width of the longest string, which happens to be "100BASE-TX". (The string "1000BASE-T" is ever so slightly shorter.) Call this width, say, \lenb.

• The width of the (latent) single-column cells -- called, say, \lena -- is obtained by solving

6\lena + 12\tabcolsep + 6\arrayrulewidth = 3\lenb + 6\tabcolsep + 3\arrayrulewidth


for \lena: \lena=0.5\lenb-\tabcolsep-\arrayrulewidth/2.

• Similarly, the width of the triple-column cells -- called, say, \lenc -- may be obtained by solving

3\lenb + 6\tabcolsep + 3\arrayrulewidth = 2\lenc + 4\tabcolsep + 2\arrayrulewidth


for \lenc: \lenc=1.5\lenb+\tabcolsep+\arrayrulewidth/2.

Once the three (minimal) lengths are obtained, it's straightforward to set up the entire tabular environment.

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}
\usepackage{array,calc}

\newlength\lena \newlength\lenb \newlength\lenc
\settowidth{\lenb}{100BASE-TX}
\setlength{\lena}{\dimexpr0.5\lenb-\tabcolsep-\arrayrulewidth/2\relax}
\setlength{\lenc}{\dimexpr1.5\lenb+\tabcolsep+\arrayrulewidth/2\relax}

\newcolumntype{P}[1]{>{\centering\arraybackslash}p{#1}} % centered "p" column
\newcommand\mcii[1]{\multicolumn{2}{P{\lenb}|}{#1}}  % handy shortcut macros
\newcommand\mciii[1]{\multicolumn{3}{P{\lenc}|}{#1}}

\begin{document}
\begin{table}[ht!]
\setlength\extrarowheight{2pt}
\centering
\begin{tabular}{|l|*{6}{p{\lena}|}}
\hline
OSI-Schicht            & \multicolumn{6}{c|}{Umsetzung}\\
\hline\hline
Anwendungsschicht      & \mcii{} & \mcii{} & \mcii{} \\
\cline{1-1}
Darstellungsschicht    & \mcii{SOME/I} & \mcii{AVB/TSN} & \mcii{DoIP} \\
\cline{1-1}
Sitzungsschicht       & \mcii{} & \mcii{} & \mcii{} \\
\hline
Transportschicht       & \mciii{TCP}  & \mciii{UDP}    \\
\hline
Vermittlungsschicht    & \mciii{IPv4} & \mciii{IPv6}   \\
\hline
Sicherungsschicht      & \multicolumn{6}{c|}{Ethernet} \\
\hline
Bitübertragungsschicht & \mcii{100BASE-TX} & \mcii{100BASE-T} & \mcii{1000BASE-T} \\
\hline
\end{tabular}
\end{table}
\end{document}

• This is exactly what I needed! Thanks a lot! Mar 3 '17 at 13:18
\documentclass[a4paper]{article}
\usepackage{array}
\begin{document}

\newcolumntype{C}[1]{>{\centering\arraybackslash}p{#1}}

\begin{tabular}{|*6{C{2cm}|}} \hline
\multicolumn{2}{|C{4cm}}{b} & \multicolumn{2}{|C{4cm}}{c} & \multicolumn{2}{|C{4cm}|}{d} \\ \hline
\multicolumn{3}{|C{6cm}}{f} & \multicolumn{3}{|C{6cm}|}{g} \\  \hline
\end{tabular}

\end{document}


Another flexible approach using \tabularx with two \newcommands for convenience:

\newcommand{\row}[2]{%
\begin{tabularx}{\textwidth}{|X|X|}
#1&#2
\end{tabularx}
}

\newcommand{\rrow}[3]{%
\begin{tabularx}{\textwidth}{|X|X|X|}
#1&#2&#3
\end{tabularx}
}

\begin{tabular}{@{}c@{}}\hline
\rrow{Long text here to test text wrapping in cells}{Long text here to test text wrapping in cells}{Long text here to test text wrapping in cells}\\\hline
\row{Long text here to test text wrapping in cells}{Long text here to test text wrapping in cells}\\\hline
\end{tabular}


Building on the above, here is a complete solution:

\documentclass[a4paper]{article}
\usepackage{tabularx,array,multirow}
\begin{document}

\newcolumntype{C}{>{\centering\arraybackslash}X}

\newcommand{\xtab}[1]{%
\begin{tabularx}{.7\textwidth}{C}
#1
\end{tabularx}
}

\newcommand{\xxtab}[2]{%
\begin{tabularx}{.7\textwidth}{C|C}
#1&#2
\end{tabularx}
}

\newcommand{\xxxtab}[3]{%
\begin{tabularx}{.7\textwidth}{C|C|C}
#1&#2&#3
\end{tabularx}
}

\begin{tabular}{|l|c|}
\hline
OSI-Schicht &   \xtab{Umsetzung}                        \\ \hline
Anwendungsschicht   &                           \\ \hline
Darstellungsschicht &   \xxxtab{    SOME/IP }{  AVB/TSN}{   DoIP    }   \\ \hline
Sitzungsschicht &                           \\ \hline
Transportschicht    &   \xxtab{TCP}         {UDP}           \\ \hline
Vermittlungsschicht &   \xxtab{IPv4}            {IPv6}          \\ \hline
Sicherungsschicht   &   \xtab{Ethernet}                     \\ \hline
Bitübertragungsschicht  &   \xxxtab{100BASE-TX}     {100BASE-T1}        {100BASE-T}     \\ \hline

\end{tabular}

\end{document}


This is very easy in ConTeXt MKIV with Natural Tables.

\starttext

\startTABLE
\NC[nx=2] b \NC[nx=2] c \NC[nx=2] d \NC\NR
\NC[nx=3] f \NC[nx=3] g \NC\NR
\stopTABLE

\stoptext