48

I have the code:

\documentclass{article}
\usepackage[a4paper]{geometry}
\usepackage{tabularx}
\usepackage{lipsum}
\begin{document}
\begin{tabularx}{\textwidth}{ | X | c | }
  \hline
  \lipsum[1] & top\\
  \hline
  \lipsum[1] & center\\
  \hline
  \lipsum[1] & bottom\\
  \hline
\end{tabularx}
\end{document}

Gives this:

enter image description here

The top row is already aligned top. How can I vertically align the center row at the center? And the bottom row at the bottom?

inavda
  • 136
  • 1
  • 7
user4035
  • 5,035
  • 6
  • 40
  • 57

5 Answers5

37

The vertical adjustment of the row "c" is related to the definition of the columntype X which uses the specifier p.

You need m for a centered adjustment and b for bottom. This can be achieved by \multicolumn, whereby the line width must be saved (I don't know a good solution).

Here is an example:

\documentclass{article}
\usepackage[a4paper]{geometry}
\usepackage{tabularx}
\usepackage{lipsum}
\begin{document}

\begin{tabularx}{\textwidth}{ | X | c | }
  \hline
  \lipsum*[1]\xdef\tempwidth{\the\linewidth} & top\\\hline
  \multicolumn{1}{|m{\tempwidth}|}{\lipsum*[1]} & center\\\hline
  \multicolumn{1}{|b{\tempwidth}|}{\lipsum*[1]} & bottom\\\hline
\end{tabularx}
\end{document}

enter image description here

TeXnician
  • 33,589
Marco Daniel
  • 95,681
  • 3
    @MarcoDaniel Why column c vertical alignment is defined by changing column X? – user4035 May 07 '13 at 19:24
  • @user4035: Because the column type X is responsible for the baseline. – Marco Daniel May 07 '13 at 19:26
  • 1
    @MarcoDaniel What if we have 3 columns: X|c|c. And want the 1-st c to be top aligned, and 2-nd c to be bottom aligned? – user4035 May 07 '13 at 19:31
  • @user4035: you can use the same trick or use David's trick – Marco Daniel May 07 '13 at 19:49
  • @Marco May this changed over they year but based on my tests you are wrong. The the column is of type X is irrelevant. The important fact is that it contains the large multi-line text. – Robert Sep 05 '19 at 15:02
  • @MarcoDaniel Does this specific example work in the beamer class? I just put \documentclass{beamer} instead of \documentclass{article} to get an error. Isn't it compatible with tabularx? – shyzealot Mar 06 '20 at 01:16
37

enter image description here

\documentclass{article}
\usepackage[a4paper]{geometry}
\usepackage{tabularx}
\usepackage{lipsum}
\begin{document}

\noindent
\begin{tabularx}{\textwidth}{ | X | c | }
  \hline
  \lipsum[1] & top\\
  \hline
  \noindent\parbox[c]{\hsize}{\lipsum[1]} & center\\
  \hline
  \noindent\parbox[b]{\hsize}{\lipsum[1]} & bottom\\
  \hline
\end{tabularx}

\end{document}
David Carlisle
  • 757,742
  • 2
    I absolutely love this simple solution, but for my liking there should be a bit of empty space between the cells. When I applied this to my table the cells are so close to each other that it looks kinda awkward. Is there any way to add a bit of empty space on the top and bottom of the cell? – Cadbon Apr 04 '15 at 14:43
  • @Cadbon \renewcommand\arraystretch{2} or whatever number works for you – David Carlisle Apr 04 '15 at 15:02
  • 2
    Unfortunately I couldn't solve my issues with that method as my top row has only one row of text and the arraystretch command stretches all cells. This means that my top row only has a single row of text but a very large cell which looks silly. – Cadbon Apr 06 '15 at 10:22
  • Any idea how I can center the lipsum text horizontally with this? I tried \parbox[c][][c] but that doesn't seem to help... – gghuffer Oct 05 '15 at 02:05
  • @gghuffer as in any parbox or p or X column,, just use \centering – David Carlisle Oct 05 '15 at 06:58
  • @Cadbon Although not pretty, you can simply add a \vspace*{2mm} inside the parbox, before and after the text. For prettiness, define it as a command – Attaque Feb 16 '16 at 13:37
  • @DavidCarlisle The solution given by you is elegant and working. But, it increases the table size vertically. That result in overall increase in page count of the paper, if there are many tables in the paper. Can this is handled? – S G Mar 11 '21 at 10:39
  • Could anyone please explain how this works? How is \parbox in the left cell affecting the position of text in the right cell? – mavzolej Aug 03 '23 at 02:07
  • 1
    @mavzolej all the text in a table row is placed on the same baseline so \parbox[b]{...} has its reference point on its bottom row so that row shares the baseline with the c column – David Carlisle Aug 03 '23 at 07:10
16

Another way, using a minipage environment instead of a tabularx package:

\documentclass{article}
\usepackage{lipsum}
\usepackage[a4paper]{geometry}
\begin{document}

\begin{tabular}{|l|c|}
  \hline
  \begin{minipage}[t]{0.85\textwidth}\lipsum[1]\end{minipage} & top\\
  \hline
  \begin{minipage}{0.85\textwidth}\lipsum[1]\end{minipage} & center\\
  \hline
  \begin{minipage}[b]{0.85\textwidth}\lipsum[1]\end{minipage} & bottom\\
  \hline
\end{tabular}

\end{document}

enter image description here

Mike T
  • 543
9

My new LaTeX3 package tabularray has two new h and f alignment types for putting cell text at the head and foot of the row respectively:

\documentclass{article}
\usepackage[a4paper]{geometry}
\usepackage{tabularray}
\usepackage{lipsum}
\begin{document}
\noindent
\begin{tblr}{
  colspec = {|X|c|}, rowspec = {Q[h]Q[m]Q[f]},
}
  \hline
  \lipsum[1] & top\\
  \hline
  \lipsum[1] & center\\
  \hline
  \lipsum[1] & bottom\\
  \hline
\end{tblr}
\end{document}

enter image description here

L.J.R.
  • 10,932
  • While this package is very new (might not be in TeXLive/etc. by default), it has several nice features: h/f valign option (which is closer to top/bottom vertical align in word processors), individual cell alignment with \SetCell (however, unfortunately there's no corresponding for middle-align i.e. halfway between the head and the foot, you mostly have to middle-align the whole row). For other features see the doc – user202729 Nov 16 '21 at 15:18
1

With {NiceTabularX} of nicematrix, you can use the command \Block with its keys T, v-center and B to change the vertical alignment of the cells of the second column. You don't have to change anything in the first column.

\documentclass{article}
\usepackage[a4paper]{geometry}
\usepackage{nicematrix}
\usepackage{lipsum}
\begin{document}

\noindent \begin{NiceTabularX}{\textwidth}{ | X | c | } \hline \lipsum[1] & \Block[T]{}{top} \ \hline \lipsum[1] & \Block[v-center]{}{center} \ \hline \lipsum[1] & \Block[B]{}{bottom} \ \hline \end{NiceTabularX}

\end{document}

Output of the above code

In fact, with nicematrix, it's possible to have the same output with a slightly shorter code:

\documentclass{article}
\usepackage[a4paper]{geometry}
\usepackage{nicematrix}
\usepackage{lipsum}
\begin{document}

\noindent \begin{NiceTabular}{Xc}[hvlines] \lipsum[1] & \Block[T]{}{top} \ \lipsum[1] & \Block[v-center]{}{center} \ \lipsum[1] & \Block[B]{}{bottom} \ \end{NiceTabular}

\end{document}

The output is the same.

F. Pantigny
  • 40,250