# How to vertically align some text in a table?

## EDIT

I was given the following code for a table template (modified in order to take into account David's remarks below) :

\documentclass[12pt, a4paper, final]{article}
\usepackage{array}
\usepackage{multirow}
\usepackage{booktabs}

% This command computes and creates a vertical space
% depending on the number of rows to compensate for.
% It makes use of the counter verticalcompensationrows
% and the length \verticalcompensationlength which equals
% \aboverulesep plus \belowrulesep
\newlength{\verticalcompensationlength}
\setlength{\verticalcompensationlength}{\aboverulesep}
\newcounter{verticalcompensationrows}
\newcommand{\verticalcompensation}[1]{%
\setcounter{verticalcompensationrows}{#1}%
\vspace*{-\value{verticalcompensationrows}\verticalcompensationlength}%
}

% This command reimplements \multirow to compensate
% for the vertical offset, but looses some functionality
% of the \multirow command (not discussed here).
\newcommand{\multirowbt}[3]{%
\multirow{#1}{#2}{\verticalcompensation{#1}#3}%
}

\begin{document}
\begin{tabular}{lp{13cm}}
\toprule
\multicolumn{2}{c}{Table title or something else ...}  \\
\midrule
\multirowbt{4}{*}{My name} & A bit of text  \\
\cmidrule{2-2}
& A bit more text A bit more text A bit more text A bit more text  \\
\cmidrule{2-2}
& A bit more text A bit more text A bit more text A bit more text \\
\cmidrule{2-2}
& A bit more text A bit more text A bit more text A bit more text \\
\midrule
\multirowbt{3}{*}{Your name} & Some text \\
\cmidrule{2-2}
& More text More text More text \\
\cmidrule{2-2}
& More text More text More text \\
\bottomrule
\end{tabular}
\end{document}


It outputs the table shown in Figure 1 below :

However, when I have some text that covers more than one line, the vertical aligned in column 1 is no longer OK, as demonstarated by TABLE 2.

In his answer below, David gives a solution to this problem using \raisebox. This works, but it requires me to change the amount the box has to be shifted for each column of each table.

I was wondering whether anyone knew of a way to get Latex to center this content automatically.

-
change {ll} to {lp{5cm}} or whatever width you need so the second column is a parbox that automatically breaks lines. –  David Carlisle Nov 29 '12 at 22:34
Thanks, that solves indeed my first problem; now it's just the vertical alignment in column 1 that still needs correcting. –  Percy Nov 29 '12 at 22:40
you might prefer \usepackage{array} then you can use m instead of p which uses parbox[c] so the baseline of the first column will align with the centre of the box –  David Carlisle Nov 29 '12 at 22:41

If you box the contents in column 2, the m-column specification will vertically center its anchor point, providing the alignment you're after. My way of boxing it is by putting it in a tabular of known/fixed width and making sure that it fits within the text block:

\documentclass[12pt]{article}
\usepackage{booktabs,array}% http://ctan.org/pkg/{booktabs,array}
\begin{document}

\noindent
\setbox0=\hbox{Your name}% Store the widest left-column entry
\begin{tabular}{lm{\dimexpr\textwidth-3\tabcolsep-\wd0}@{}}
\toprule
\multicolumn{2}{c}{Table title or something else ...}  \\
\midrule
My name & \begin{tabular}{p{\dimexpr\linewidth-\tabcolsep}@{}}
A bit of text  \\
\midrule
A bit more text A bit more text A bit more text A bit more text  \\
\midrule
A bit more text A bit more text A bit more text A bit more text \\
\midrule
A bit more text A bit more text A bit more text A bit more text
\end{tabular} \\
\midrule
Some text \\
\midrule
More text More text More text \\
\midrule
More text More text More text
\end{tabular} \\
\bottomrule
\end{tabular}

\end{document}


The widest left-column entry is stored and used in the width-calculation for the right m-column.

-
Works beautifully, thanks! –  Percy Nov 30 '12 at 17:11

\documentclass[12pt, a4paper, final]{article}

\usepackage{booktabs}
\usepackage{tabularx}
\renewcommand\tabularxcolumn[1]{m{#1}}

\begin{document}

\noindent
\begin{tabularx}{\textwidth}{lX}
\toprule
\multicolumn{2}{c}{Table title or something else ...}  \\
\midrule
\smash{\raisebox{-50pt}{My name}} & A bit of text  \\
\cmidrule{2-2}
& A bit more text A bit more text A bit more text A bit more text  \\
\cmidrule{2-2}
& A bit more text A bit more text A bit more text A bit more text \\
\cmidrule{2-2}
& A bit more text A bit more text A bit more text A bit more text \\
\midrule
\smash{\raisebox{-20pt}{Your name}} & Some text \\
\cmidrule{2-2}
& More text More text More text \\
\cmidrule{2-2}
& More text More text More text \\
\bottomrule
\end{tabularx}

\end{document}

-
OK thanks, this works, but is there not a way for the text in the first column to be vertically centered automatically ? I have 10 or so tables in my document (with up to 6 rows each), and individually fiddling around with raisebox for each row of each table can be a bit tricky ... –  Percy Nov 30 '12 at 9:48
ew well not really in the standard packages, multirow (or the code in the template that you started with that I deleted) can make a guess at that but only by assuming all the table rows are the same height. Once you have multi-line p cells this isn't the case. It is of course possible to have more convoluted code that measures stuff but nothing "out of the box" as far as I know. –  David Carlisle Nov 30 '12 at 9:55
In practice I wouldn't use multirow or the raisebox I'd probably just put the first column cell so it aligned with the top line of the third row in the first group and the second line in the second group. Then you get baseline alignment automatically –  David Carlisle Nov 30 '12 at 9:57

And of course the always present overkill tikz-based solution:

\documentclass{article}
\usepackage{array}
\usepackage{booktabs}
\usepackage{tikz}
\begin{document}

\def\tikzmark#1{\tikz[overlay, remember picture]\node[coordinate] (#1) {};}
\def\textbetween#1#2#3{ % #1 #2 row ids, #3 content
\tikz[overlay, remember picture]\path ([yshift=1ex] #1)--(#2) node[midway,right] {#3};%
}

\begin{tabular}{p{2cm}p{10cm}}
\toprule
\multicolumn{2}{c}{Table title or something else ...}  \\
\midrule
\tikzmark{1} & A bit of text  \\
\cmidrule{2-2}
& This is what happens when I write too much text in one line: it creates
an extra line and the item in the first column is no longer aligned!  \\
\cmidrule{2-2}
& A bit more text A bit more text A bit more text A bit more text \\
\cmidrule{2-2}
\tikzmark{2} & A bit more text A bit more text A bit more text A bit more text \\
\midrule
\textbetween{1}{2}{My Name}%
\tikzmark{1} & Some text \\
\cmidrule{2-2}
& More text More text More text \\
\cmidrule{2-2}
\tikzmark{2} & More text More text More text \\
\bottomrule

Usage: Put \tikzmark{x} at the first and last row filled by your multirow, being x an arbitrary identifier for the row, and then use the macro \textbetween to put the text centered between the two marks.