# Vertical alignment relative to row height

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}


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:

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}


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:

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

• 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} Mar 26, 2020 at 15:26

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}


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}


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

Or use

\phantom

\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}


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}