18

If I make different tables on one page, it doesn't always look as good as I wanted. The biggest problem is that some tables are wider then other. Therefore I would like to control the columns of a tables in function of the text width, so it would always be even width. Is there an option to do something like this:

\begin{document}
\begin{tabular}{|p{10%}|p{30%}|p{30%}|p{30%}|} 
\hline
A & B & C & D \\
\hline 
\end{tabular}
\end{document}
Sigur
  • 37,330

2 Answers2

24

Package tabularx can help in calculating the column widths. There are four columns, which should fill the available space (\linewidth). Then the column specification using X columns is given in the following example. Package tabularx takes care of \tabcolsep and the width of the vertical rules, if it calculates the column width.

\documentclass{article}
\usepackage{array}
\usepackage{tabularx}

\begin{document}
  \noindent
  \begin{tabularx}{\linewidth}{
    |>{\hsize=.4\hsize}X|% 10% of 4\hsize 
    >{\hsize=1.2\hsize}X|% 30% of 4\hsize
    >{\hsize=1.2\hsize}X|% 30% of 4\hsize 
    >{\hsize=1.2\hsize}X|% 30% of 4\hsize
       % sum=4.0\hsize for 4 columns
  }
    \hline
    A & B & C & D \\
    \hline
  \end{tabularx}
\end{document}

Result

Solution without package tabularx

The problem can be solved with simple p-columns:

  • LaTeX adds width \tabcolsep to the left and right of a column by default.

  • Vertical lines have width \arrayrulesep if package array is loaded (the packages is often implicitly loaded by other packages). Otherwise, the contribution to the table width is zero.

The following example first calculates the net table width for the columns for use in the p-columns. The calculation is done with e-TeX's \dimexpr. Alternatively, package calc with \setlength can be used.

\documentclass{article}
\usepackage{array}

\newdimen\NetTableWidth

\begin{document}
  \noindent
  \NetTableWidth=\dimexpr
    \linewidth
    - 8\tabcolsep
    - 5\arrayrulewidth % if package array is loaded
  \relax
  \begin{tabular}{%
    |p{.1\NetTableWidth}|%
    p{.3\NetTableWidth}|%
    p{.3\NetTableWidth}|%
    p{.3\NetTableWidth}|%
  }
    \hline
    A & B & C & D \\
    \hline
  \end{tabular}
\end{document}
Heiko Oberdiek
  • 271,626
  • 1
    There is a good reason to want to achieve the same using something other than tabularx though. I've just found out that tabularx can't display verbatim environments (such as minted). – Zach Smith Dec 03 '17 at 20:14
  • @ZachSmith Added solution without package tabularx. – Heiko Oberdiek Dec 03 '17 at 23:04
2

I came across this thread looking for a solution without tabluarx. I didn't want to use another extra package as proposed in the solution by Heiko.

Here is my alternative solution that does not require any additional package. I included multi-column cells to highlight the relative width of the columns, meaning in this use case you don't want to manually set the width of each column, but in relation to other columns, while using the percentage of \linewidth.

\documentclass[]{article}
\begin{document}
\newlength{\width}
\width.1\linewidth
\begin{table} [h!]
    \centering\begin{tabular}{|p{\width}|p{\width}|p{\width}|p{\width}|p{\width}|p{\width}|p{\width}|}
        \hline
        Num & A & B & C & D & E & F  \\\hline
        1 & 1A & 1B & \multicolumn{2}{c|}{1CD} &  \multicolumn{2}{c|}{1EF} \\\hline
        2 & 2A & 2B & 2C & 2D &  \multicolumn{2}{c|}{2EF} \\\hline
        3 & \multicolumn{6}{c|}{3ABCDEF} \\\hline
        4 & 4A & 4B & 4C &  \multicolumn{3}{c|}{4DEF} \\\hline
    \end{tabular}
\end{table}
\end{document}

Output:

Screenshot of a table with multi-column cells

LonLon
  • 442
  • This does not work though, your table is more than 70% of the linewidth, you can see this by adding more columns for instance. This is because, as the other answer correctly accounts for, every cell wall gets left and right a bit of space added to it. – Rich_Rich Mar 29 '24 at 12:43