# Tabularx and \hsize column tuning

In this answer : Tabularx table with multirows and multicolumns, I have discovered the \hsize possibility to tune X column width of tabularx table.

The documentation says :

Make sure that the sum of the widths of all the X columns is unchanged.

But the answer says :

\begin{tabularx}{\textwidth}{|>{\hsize=0.5\hsize}X|
*{3}{ >{\hsize=1.5\hsize}X|}
}


that makes a sum of 5 for 4 columns, and it leeds to problems if one not fill columns enought.

Questions :

• Why it works in the example and not in the following example ?

• What is the correct method to calculate the \hsizes ?

\documentclass{article}
\usepackage{tabularx}
\begin{document}
\begin{table}

\begin{tabularx}{\linewidth}{|>{\hsize=0.5\hsize}X|
*{3}{ >{\hsize=1.5\hsize}X|}
}\hline
1&2&3&4\\\hline
\end{tabularx}

\bigskip

% My proposition if correctly understood the manuel
\begin{tabularx}{\linewidth}{|>{\hsize=0.5\hsize}X|
*{3}{ >{\hsize=1.16667\hsize}X|}
}\hline
1&2&3&4\\\hline
\end{tabularx}
\end{table}
\end{document}

• Please explain what exactly you're trying to achieve. Do you need the first column to be 1/3 as wide as the other three? Please advise. – Mico Mar 19 '18 at 20:40
• i delete my answer at linked question :-( – Zarko Mar 19 '18 at 20:47
• I try to understand how the \hsize system works : in the related question, the sum is over but it seems to work but I don't know why : with the same table preambule the result is messy. If I start with a 0.5 for the first column the 3 orther have to be set to 1+1/6 to fit the rule : .5+3*(1+1/6)=4 from the manuel. Is this correct ? It is te meaning of my questions. – Tarass Mar 19 '18 at 20:50
• @zarko I'm sorry it wasn't the purpose. I just try to understand how it works. Thank you for your explanaitions. – Tarass Mar 19 '18 at 20:53
• @Zarko sorry:-) actually if you change 2 to 3 it would have given the right table as it happens – David Carlisle Mar 19 '18 at 22:30

It seems you want three equal-width columns (let's denote their width by x), plus another column that's one-third as wide as the other three; denote its width by y. The combined width of the four columns should equal \linewidth.

The computation is that of barycentric coordinates: you have to solve the linear system:

3x + y = 4 % 4: number of columns of type "X"
x = 3y


It is easy to find this yields y=0.4 and x=1.2, whence the code:

\documentclass{article}
\usepackage{tabularx}
%% define a custom col. type to simplify expressing relative col. widths
\newcolumntype{H}[1]{>{\hsize=#1\hsize\arraybackslash}X}

\begin{document}

\begin{table}
\begin{tabularx}{\linewidth}{| H{0.4} | *{3}{H{1.2}|} } % 0.4+3*1.2=4
\hline
1&2&3&4\\
\hline
\end{tabularx}
\end{table}

\end{document}


• this is of course the right answer but the fact that the right answer involves telling the end user to solve a linear system does rather imply that the user interface for tabularx is somewhat suboptimal. – David Carlisle Mar 19 '18 at 20:57
• It make sense. Why \arraybackslash necesseraly ? why barycentric ? – Tarass Mar 19 '18 at 20:58
• It is used to reset \ to \tabularnewline (don't forget X columns have p{...} type, hence we could theoretically want to use \ inside a cell. Barycentric coordinates are numbers used as a system of weights for each point in a finite set. It's just an analogy here. – Bernard Mar 19 '18 at 21:13
• @Tarass \arraybackslash is not doing anything here but it is very common to use \centering or \raggedright in that >{...} and then \arraybackslash allows \\  to end the table row. Always adding it doesn't do any harm. – David Carlisle Mar 19 '18 at 21:31

Bernard's answer shows how to set the values while following the rules in the tabularx documentation, but to answer your question about what happens in the table that doesn't follow the rules.

First note that as posted there is a small error as seen in the spanning column entries which are not centred in their width.

The intention of the calculation was that the width was double the natural width plus adjustment for the space and rules around the columns, but the columns that are spanned already have 1.5 multiplier applied so the spanning column needs to be 3\hsize not 2\hsize plus adjustment for the column padding. see the second table in the example her:

\documentclass{article}
\usepackage{tabularx}

\tracingtabularx
\begin{document}
\begin{table}

\begin{tabularx}{\linewidth}{@{\extracolsep{0pt}}|>{\hsize=0.5\hsize}X|
*{3}{>{\hsize=1.5\hsize}X|}
}\hline
1\dotfill X&
\multicolumn{2}{>{\hsize=\dimexpr2\hsize+2\tabcolsep+\arrayrulewidth\relax}X|}{text\dotfill X}&
4\dotfill X\\\hline
1\dotfill X&2\dotfill X&3\dotfill X&4\dotfill X\\\hline
\end{tabularx}

\bigskip

\begin{tabularx}{\linewidth}{@{\extracolsep{0pt}}|>{\hsize=0.5\hsize}X|
*{3}{>{\hsize=1.5\hsize}X|}
}\hline
1\dotfill X&
\multicolumn{2}{>{\hsize=\dimexpr3\hsize+2\tabcolsep+\arrayrulewidth\relax}X|}{text\dotfill X}&
4\dotfill X\\\hline
1\dotfill X&2\dotfill X&3\dotfill X&4\dotfill X\\\hline
\end{tabularx}

\end{table}
\end{document}


So why does the second table work as it doesn't follow either of tabularx stated rules

• Make sure that the sum of the widths of all the {\ttfamily X} columns is unchanged. (In the above example, the new widths still add up to twice the default width, the same as two standard {\ttfamily X} columns.)

• Do not use "\multicolumn" entries which cross any {\ttfamily X} column.

The reason is hinted in the tabularx documentation which follows those rules by the helpful further documentation

As with most rules, these may be broken if you know what you are doing.

Here essentially what is happening is that the initial guessed widths are too narrow as tabularx is expecting 5 columns, but the standard tabularx iterative trials to find the right widths reduces the effective number of X columns at each trial (to take account of X columns that are "hidden" by \multicolumn{c} headers and so do not affect the total table width. So it turns out that apart from causing one extra iteration of the tabularx trials the end result is a table of the right width. Note however without the multicolumn the initial bad starting point sends tabularx into a path where it never converges on a solution that gives the correct table:

\documentclass{article}
\usepackage{tabularx}

\tracingtabularx
\begin{document}
\begin{table}

\begin{tabularx}{\linewidth}{@{\extracolsep{0pt}}|>{\hsize=0.5\hsize}X|
*{3}{>{\hsize=1.5\hsize}X|}
}\hline
1\dotfill X&
?&?&
4\dotfill X\\\hline
1\dotfill X&2\dotfill X&3\dotfill X&4\dotfill X\\\hline
\end{tabularx}

\end{table}
\end{document}


so perhaps

As with most rules, these may be broken if you know what you are doing.

could have perhaps have been phrased as

As with most rules, these may be broken if you are lucky.

• @Tarass it took me a while to see why the \multicolumn in your example made such a difference and it's my code I was tracing, not been in some of those parts since last millennium:-) – David Carlisle Mar 20 '18 at 7:32