# How to vertically-center the text of the cells?

I have a simple table as follows:

\begin{table*}
\centering
\begin{tabular}{|l|c|c|c|c|p{2in}|}
...
...
\end{tabular}
\caption{The factors the camera solver depends on to evaluate the rules.}
\label{table:factors}
\end{table*}


How is it possible to vertically-center the text of the cells?

• This earlier question might be of help to you. Dec 16, 2010 at 12:34
• Looking closer at your example, I realize you obviously have the array package loaded. p{...} aligns the content toward the top, m{...} aligns the content toward the center, while b{...} aligns it toward the bottom. Dec 17, 2010 at 23:19
• @Jimi: the example works even without array. The p specifier is standard. Dec 18, 2010 at 15:35
• Question, actually. How in the world would a person who knows nothing about code go about this? I'm drowning in information, here.
– user44066
Jan 12, 2014 at 23:33
• @Amy it's not as bad as it looks. You can just copy the code into your document and see if it works. After some time you will get used to Latex code more and more. I would start with the small things first by making tables in an -- for you -- acceptable format, without worrying too much about perfection, which can be done later.
– TomM
Jan 13, 2014 at 0:16

\documentclass{article}
\usepackage[a4paper,vmargin=2cm,hmargin=1cm,showframe]{geometry}
\usepackage[demo]{graphicx}
\usepackage[table]{xcolor}
\usepackage{array}
\usepackage{longtable}

\parindent=0pt

\def\correction#1{%
\abovedisplayshortskip=#1\baselineskip\relax\belowdisplayshortskip=#1\baselineskip\relax%
\abovedisplayskip=#1\baselineskip\relax\belowdisplayskip=#1\baselineskip\relax}

\arrayrulewidth=1pt\relax
\tabcolsep=5pt\relax
\arrayrulecolor{red}
\fboxsep=\tabcolsep\relax
\fboxrule=\arrayrulewidth\relax

\newcolumntype{A}[2]{%
>{\minipage{\dimexpr#1\linewidth-2\tabcolsep-#2\arrayrulewidth\relax}\vspace\tabcolsep}%
c<{\vspace\tabcolsep\endminipage}}

\newenvironment{Table}[4]{%
\longtable{%
|A{#1}{1.5}% for figure
|>{\centering$\displaystyle}A{#2}{1}<{$}% for inline equation
|>{\correction{-1}\strut$}A{#3}{1}<{$\strut}% for displayed equation
|>{\centering}A{#4}{1.5}% for text
|}\hline\ignorespaces}{%
\endlongtable\ignorespacesafterend}

\newcommand{\dummy}{%
It is practically a big lie that \LaTeX\
makes you focus on the content without

\newcommand{\Row}{%
\includegraphics[width=\linewidth]{newton}&
\frac{a+b}{a-b}=0&
\int_a^b f(x)\, \textrm{d}x=\frac{b-a}{b+a}&
\fcolorbox{cyan}{yellow}{\parbox{\dimexpr\linewidth-2\fboxsep-2\fboxrule\relax}{\dummy}}
\tabularnewline\hline}

\begin{document}
\begin{Table}{0.25}{0.25}{0.25}{0.25}
\Row
\Row
\end{Table}

\def\x{\centering$\displaystyle\int_a^bf(x)\,\textrm{d}x=\frac{a-b}{a+b}$}

\longtable{|A{0.2}{1.5}*2{|A{0.25}{1}}|A{0.3}{1.5}|}\hline
\x & \x & \multicolumn{2}{A{0.55}{1.5}|}{\x} \tabularnewline\hline
\multicolumn{2}{|A{0.45}{1.5}|}{\x} & \x & \x\tabularnewline\hline
\x & \multicolumn{2}{A{0.5}{1}|}{\x} & \x\tabularnewline\hline
\multicolumn{4}{|A{1}{2}|}{\x}\tabularnewline\hline
\endlongtable
\end{document}

• Your solution is working absolutely fine, but isn't there a simpler solution? Aligning contents vertically feels time like simpler than the proposed solution. Dec 16, 2010 at 19:42
• This answer should have some explaining text so it is easier to understand. Sep 15, 2016 at 23:20
• Unfortunately, this kind of answer is what may scare people away from LaTeX. Jul 14, 2018 at 20:24
• This kind of answer shows that LaTeX is just plain bad at tables. It's great at many things, but doing anything with tables is an overcomplicated mess and a huge distraction from what I'm actually trying to do, every time. Gah. Jul 26, 2018 at 22:27
• This can't be the best solution. I expected including a package and just adding something like \vcenter to the cell of choice. This is intended as a critique on LaTeX, not the answer in itself (for which I thank you). Nov 15, 2018 at 14:29

One easy way to this would be to use the array package, specifying your column width with m{...}. For example:

\begin{tabular}{ m{4cm} m{1cm} }
... & ... \\end{tabular}


will give you a four centimeter-long column and a one centimeter-long column. In each cell, the contents will be vertically aligned to the center. Note, however, that the cell contents will be horizontally aligned left. If you also want to align all the cell contents toward the center in a horizontal sense, then you could do something like this:

\begin{tabular}{ >{\centering\arraybackslash} m{4cm} >{\centering\arraybackslash} m{4cm} }
... & ... \\end{tabular}


The point of \arraybackslash is to return \\ to its original meaning because the \centering command alters this and could possibly give you a noalign error during compilation.

If you have several columns and do not want your source to look cluttered, you could define new columns before your tabular environment, for example:

\newcolumntype{C}{ >{\centering\arraybackslash} m{4cm} }
\newcolumntype{D}{ >{\centering\arraybackslash} m{1cm} }
\begin{tabular}{ C D }
... & ... \\end{tabular}


There is a lot of useful information on tables in the wiki LaTeX guide, if you want to explore this further.

• Are you sure that an image inclusion will be EXATCLY vertically centered using your method above? Dec 19, 2010 at 22:42
• @xport: It might be relative to the first and last baselines of the cells, not the exact totalheight. Jul 10, 2011 at 15:53
• When using this method, people should be cautious NOT to mix other column types such as p. The height of a row AND vertical-alignment follows that of the cell with the maximum height in that row. It is fine if an m column cell has the maximum height, but otherwise the vertical-align would not work. Dec 27, 2012 at 15:22
• If you just want equally spaced columns and the whole table's width to be \textwidth, can't do that with a general m{something}? Feb 25, 2017 at 4:59
• @jimioke How does one align vertically with defining a space ie can it be written as m{} Apr 30, 2018 at 4:13

Putting a tabular in the cell of a tabular centers the content of the cell horizontally and vertically.

\begin{tabular}{|l|c|c|}
\hline
\begin{tabular}{l}
text in cell 1
\end{tabular} &
\begin{tabular}{l}
first line of text in cell 2 \\
second line of text in cell 2
\end{tabular} &
\begin{tabular}{l}
first line of text in cell 3 \\
second line of text in cell 3 \\
third line of text in cell 3 \\
\end{tabular}
\\
\hline
\begin{tabular}{l}
first line of text in cell 4 \\
second line of text in cell 4
\end{tabular} &
\begin{tabular}{l}
first line of text in cell 5 \\
second line of text in cell 5 \\
third line of text in cell 5 \\
\end{tabular} &
\begin{tabular}{l}
first line of text in cell 6 \\
second line of text in cell 6 \\
\end{tabular} \\
\hline
\end{tabular}


gives:

so you can define a macro centered

\newcommand{\centered}[1]{\begin{tabular}{l} #1 \end{tabular}}


and use it like this:

%\begin{tabular}{|l|c|c|}  <- Old version of this answer
\begin{tabular}{|@{}l@{}|@{}c@{}|@{}c@{}|}
% This update now avoids double indentations and allows hlines
\hline
\centered{ text in cell 1 } &
\centered{
first line of text in cell 2 \\
second line of text in cell 2} &
\centered{
first line of text in cell 3 \\
second line of text in cell 3 \\
third line of text in cell 3 \\ } \\
\hline
\centered{
first line of text in cell 4 \\
second line of text in cell 4 } &
\centered{
first line of text in cell 5 \\
second line of text in cell 5 \\
third line of text in cell 5 \\ } &
\centered{
first line of text in cell 6 \\
second line of text in cell 6 \\ } \\
\hline
\end{tabular}

• This doesn't seem to work in a tabularx env. May 24, 2019 at 7:07
• It looks like you produce double inner indentation in each cell. So it makes sense to define command this way \newcommand{\centered}[1]{\begin{tabular}{@{}l@{}} #1 \end{tabular}} Jan 26, 2020 at 16:13
• This works great except for when I try to add a horizontal line in a child tabular. The line does not stretch the full width of the parent cell. How would I go about changing this? Mar 19, 2020 at 4:47
• @SanzioAngeli : Use \begin{tabular}{|@{}l@{}|@{}c@{}|@{}c@{}|} instead of \begin{tabular}{|l|c|c|}. I edited the answer accordingly. Mar 19, 2020 at 8:41
• didn't work for me :-/ Apr 22, 2020 at 20:07

There is a command \vcenter which vertically centers its content in horizontal mode. It can only be used in mathmode.

Here is an example with Plain XeTeX (compile with xetex yourfilename.tex)

{ \offinterlineskip
\def\trule{\noalign{\hrule}}
\def\hcenter#1{\hfil#1\hfil}
\halign{\vrule#&&\hcenter{$\vcenter{\hbox{#}}$}\vrule\cr\trule
&Lorem ipsum dolor sit amet&\XeTeXpicfile "test-pattern.jpg" &
\TeX&$E=mc^2$&$\displaystyle{a^2-b^2\over c^2}$\cr\trule
&Etiam quam lacus&\vrule width 4em height 5ex depth 2ex&\eTeX &
$E\ne mc^2$&{\it \&} cetera\cr\trule}
}
\bye


If you just want to center the text because you are not happy with the default row height, you can put the following command before each tabular environment:

\renewcommand{\arraystretch}{number}


where number is the factor to multiply the default row height.

I just found this solution for a spacing Problem. When the spaceing is set at a big enough distance, the text is centered, or at least seems like.

\Huge Text in Tabular touches table border

Here is my example:

\usepackage{makecell}%To keep spacing of text in tables
\setcellgapes{4pt}%parameter for the spacing

\begin{table}[h]
\makegapedcells
\centering
\resizebox{\textwidth}{!}{%resizing the whole table
\begin{tabular}{|c|c|c|c|c|c|c|c|c|}
\hline
\multicolumn{9}{|c|}{\Huge Relaisplatine} \\
\hline
Relay Nr. & Part & Test-Id & \specialcell[c]{Signal-Name \\for Testcases} & Conn. & Pin & \specialcell[c]{Pin-\\Func.} & R Value & \specialcell[c]{Influenced \\ Signal/Voltage } \\
\hline
&  &  &  &  & 1 & N.C. & Open & Open \\
\cline{6-9}
%\hline
0 & RIO & RIO\_VOLT\_SDAR & RIO\_GPP\_VCORE & P2 & 3 & COM &  0 $\Omega$ & SIGN08116 \\
\cline{6-9}
%\hline
&  &  &  &  & 5 & N.O. &  0 $\Omega$ & GND \\
%\cline{6-9}
\hline
&  &  &  &  & 7 & N.C. &  Open & Open \\
\cline{6-9}
1 & RIO & RIO\_VOLT\_SDAR & RIO\_ETH\_+1V2 & P2 & 9 & COM &  0 $\Omega$ & SIGN0818 \\
\cline{6-9}
&  &  &  &  & 11 & N.O. &  0 $\Omega$ & GND \\
\hline
&  &  &  &  & 13 & N.C. &  Open & Open \\
\cline{6-9}
2 & RIO & RIO\_VOLT\_SDAR & RIO\_CLOCK\_+3V3 & P2 & 15 & COM &  0 $\Omega$ & SIGN0817 \\
\cline{6-9}
&  &  &  &  & 17 & N.O. &  0 $\Omega$ & GND \\
\hline
&  &  &  &  &  & N.C. &  Open & Open \\
\cline{6-9}
3 & RIO & RIO\_VOLT\_SDAR & RIO\_HICURR1 & P3 & PCB-Cable & COM &  0 $\Omega$ & RIO\_+3V3 \\
\cline{6-9}
&  &  &  &  & PCB-Cable & N.O. &  0 $\Omega$ & GND \\
\hline
&  &  &  &  &  & N.C. &  Open & Open \\
\cline{6-9}
4 & RIO & RIO\_VOLT\_SDAR & RIO\_HICURR2 & P3 & PCB-Cable & COM &  0 $\Omega$ & RIO\_+3V3 \\
\cline{6-9}
&  &  &  &  & PCB-Cable & N.O. &  0 $\Omega$ & GND \\
\hline
&  &  &  &  & 14 & N.C. &  Open & Open \\
\cline{6-9}
5 & RIO & RIO\_VOLT\_SDAR & BAT\_LOW TBD & P2 & 16 & COM &  0 $\Omega$ & TBD \\
\cline{6-9}
&  &  &  &  & 18 & N.O. &  0 $\Omega$ &  \\
\hline
&  &  &  &  & 8 & N.C. &  Open & Open \\
\cline{6-9}
6 & RIO & RIO\_VOLT\_SDAR & BAT\_EMPTY TBD & P2 & 10 & COM &  0 $\Omega$ & TBD \\
\cline{6-9}
&  &  &  &  & 12 & N.O. &  0 $\Omega$ &  \\
\hline
&  &  &  &  & 2 & N.C. &  Open & Open \\
\cline{6-9}
7 & RIO & RIO\_VOLT\_SDAR & RIO\_DSP\_+3V3 & P2 & 4 & COM &  0 $\Omega$ & SIGN08150 \\
\cline{6-9}
&  &  &  &  & 6 & N.O. &  0 $\Omega$ & Open \\
\hline
\end{tabular}
}
\caption{Verkabelung der ersten Relaisplatine an X400/PortA}
\end{table}


Gives me:

I will replicate @xport's answer with my new LaTeX3 package tabularray. It is much easier while the images are still exactly vertically centered using this method.

\documentclass{article}

\usepackage[a4paper,vmargin=2cm,hmargin=1cm]{geometry}
\usepackage{graphicx}
\usepackage{xcolor}
\usepackage{tabularray}

\setlength{\parindent}{0pt}

\newcommand{\dummy}{%
It is practically a big lie that \LaTeX\
makes you focus on the content without
}

\newcommand\xx{$\displaystyle\frac{a+b}{a-b}=0$}
\newcommand\yy{$\displaystyle\int_a^bf(x)\,\textrm{d}x=\frac{a-b}{a+b}$}
\newcommand\zz{\fcolorbox{cyan3}{yellow9}{\parbox{\dimexpr\linewidth-2\fboxsep-2\fboxrule\relax}{\dummy}}}

\begin{document}

\noindent
\begin{tblr}{
colspec = {X[c,h]X[c]X[c]X[c]},
stretch = 0,
rowsep = 6pt,
hlines = {red5, 1pt},
vlines = {red5, 1pt},
}
\includegraphics[width=0.22\textwidth]{example-image-a} & \xx & \yy & \zz \\
\includegraphics[width=0.22\textwidth]{example-image-b} & \xx & \yy & \zz \\
\end{tblr}

\bigskip

\begin{tblr}{
colspec = {X[c,m]X[c,m]X[c,m]X[c,m]},
cell{1}{3} = {c=2}{c}, % multicolumn
cell{2}{1} = {c=2}{c}, % multicolumn
cell{3}{2} = {c=2}{c}, % multicolumn
cell{4}{1} = {c=4}{c}, % multicolumn
rowsep = 6pt,
hlines = {red5, 1pt},
vlines = {red5, 1pt}, % vlines can not pass through multicolumn cells
}
\yy & \yy & \yy &     \\
\yy &     & \yy & \yy \\
\yy & \yy &     & \yy \\
\yy &     &     &     \\
\end{tblr}

\end{document}


I found out a different approach that doesn't require extra packages or redefining stuff (I guess it only works properly with one line of text in each cell).

For padding at the top you can use this solution (I found it here):

\rule{0pt}{4ex}


...which creates vertical space to by adding an invisible (0 width) horizontal bar of the height you need (in this case, 4 times the lowercase x, counting from the text baseline). This one goes before the first cell content.

For padding at the bottom, you just add the needed space after the line ends:

cell & cell & cell \\[4ex]


Note: For a nice balance I found that the top padding needs to be 2.2ex more than the bottom one (to compensate for the height of the text itself).

\rule{0pt}{4.2ex} cell & cell & cell \\[3ex]