3

I'm struggling with a seemingly trivial case of vertical alignment in a tabular. Consider 3 columns: two columns contain text that is supposed to be soft-wrapped and should be aligned at the top of the cells. The third column (the middle column in my example) should be vertically centered within the row.

Example:

\documentclass{scrartcl}
\usepackage{lipsum}
\usepackage{array}
\begin{document}

    \begin{tabular}{m{4cm} m{1cm} m{4cm}}
    \lipsum[1][1] & x  & \lipsum[1][1]
    \end{tabular}

\end{document}

Output 1: ok

This looks as expected, but only if the two texts occupy the same height. Otherwise (just changing the second \lipsum[1][1] to \lipsum[1][1-2], the result is:

Output 2: wrong

Problem: The content of column 1 is not aligned at the top of the cell.

Of course, changing the alignment of the two "long" columns to p{4cm} does not help:

\documentclass{scrartcl}
\usepackage{lipsum}
\usepackage{array}
\begin{document}
    \begin{tabular}{p{4cm} m{1cm} p{4cm}}
    \lipsum[1][1] & x  & \lipsum[1][1-2]
    \end{tabular}
\end{document}

Output 3: wrong

Problem: Now the column in the middle is not vertically centered anymore.


I think I understand why this is happening: All these alignments are relative to the first "line" of the current cell, not relative to the cell itself. (How) Is this possible? I'm looking for a column specification that allows me to produce:

Expected output

In the best case, I wouldn't even have to specify a width for the column in the middle.

1
  • Here is a way using multirow. However, not ideal since you have to count the lines of the larger cell: \documentclass{scrartcl} \usepackage{lipsum} \usepackage{array} \usepackage{multirow} \begin{document} \begin{tabular}{p{4cm} l p{4cm}} \lipsum[1][1] & \multirow{6}{*}{x} & \lipsum[1][1-2] \end{tabular} \end{document}
    – leandriis
    Mar 26, 2020 at 15:26

4 Answers 4

1

You can cheat with \multirow, counting the maximum number of lines in the cells of a row:

\documentclass{scrartcl}
\usepackage{lipsum}
\usepackage{array, multirow}

\begin{document}

    \begin{tabular}{p{4cm} m{1cm} p{4cm}}
    \lipsum[1][1] & \multirow{6}{=}{x} & \lipsum[1][1-2]
    \end{tabular}

\end{document} 

enter image description here

1

Not really so trivial.

You could measure the two large boxes and then place the middle one at the vertical center. However, TeX can do it for you.

\documentclass{article}

\usepackage[latin]{babel} % for better hyphenation
\usepackage{lipsum} % for mock text
\usepackage{microtype} % for less overfull boxes

\newcommand{\mytwocols}[4][4cm]{%
  \valign{##\cr
    \mycol{\vtop}{#1}{#2}\vfill\cr
    \noalign{\hspace{2\tabcolsep}}
    \vfill\mycol{\vbox}{1cm}{#3}\vfill\cr
    \noalign{\hspace{2\tabcolsep}}
    \mycol{\vtop}{#1}{#4}\vfill\cr
  }%
}
\newcommand{\mycol}[3]{%
  #1{\hsize#2\relax\parindent0pt\relax\sloppy#3}%
}


\begin{document}

\mytwocols
  {\lipsum[1][1]}
  {x}
  {\lipsum[1][1]}

\bigskip

\mytwocols
  {\lipsum[1][1]}
  {x}
  {\lipsum[1][1-2]}

\bigskip

\mytwocols
  {\lipsum[1][1-2]}
  {x}
  {\lipsum[1][1]}

\end{document}

enter image description here

1
  • Nice. And here I was, by chance, looking for some examples of the use of \valign...
    – sgmoye
    Mar 26, 2020 at 17:40
0

Or use

\phantom

enter image description here

\documentclass{scrartcl}
\usepackage{lipsum}
\usepackage{array}
\newcolumntype{M}[1]{>{\centering\let\newline\\\arraybackslash\hspace{0pt}}m{#1}}
\begin{document}
    \begin{tabular}{p{4cm} M{5cm} p{4cm}}
    \lipsum[1][1] &  {\phantom{\lipsum[1][1-2]}} x  & \lipsum[1][1-2]
    \end{tabular}
\end{document}
0

A manual but very simple solution could be equalize the number of lines of left cell and use a c column for the "x" separator:

\documentclass{scrartcl}
\usepackage{lipsum}
\usepackage{array}
\begin{document}
    \begin{tabular}{m{4cm}@{\qquad}c@{\qquad}m{4cm}}
    \lipsum[1][1]\newline\newline\newline     & x  & \lipsum[1][1-2]
    \end{tabular}
\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .