213

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?

6
  • 4
    This earlier question might be of help to you. Commented Dec 16, 2010 at 12:34
  • 6
    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. Commented Dec 17, 2010 at 23:19
  • 3
    @Jimi: the example works even without array. The p specifier is standard. Commented Dec 18, 2010 at 15:35
  • 2
    Question, actually. How in the world would a person who knows nothing about code go about this? I'm drowning in information, here. Commented Jan 12, 2014 at 23:33
  • 1
    @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. Commented Jan 13, 2014 at 0:16

9 Answers 9

51

Edit: The existence of this new answer has made my answer now obsolete and embarrassing. Please proceed to the new answer and vote it up.

enter image description here

\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 bothering about the layout.} \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} 
8
  • 133
    Your solution is working absolutely fine, but isn't there a simpler solution? Aligning contents vertically feels time like simpler than the proposed solution. Commented Dec 16, 2010 at 19:42
  • 57
    This answer should have some explaining text so it is easier to understand. Commented Sep 15, 2016 at 23:20
  • 67
    Unfortunately, this kind of answer is what may scare people away from LaTeX. Commented Jul 14, 2018 at 20:24
  • 38
    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. Commented Jul 26, 2018 at 22:27
  • 19
    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). Commented Nov 15, 2018 at 14:29
160

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.

5
  • 1
    Are you sure that an image inclusion will be EXATCLY vertically centered using your method above? Commented Dec 19, 2010 at 22:42
  • 1
    @xport: It might be relative to the first and last baselines of the cells, not the exact totalheight. Commented Jul 10, 2011 at 15:53
  • 24
    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. Commented 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}? Commented Feb 25, 2017 at 4:59
  • 2
    @jimioke How does one align vertically with defining a space ie can it be written as m{} Commented Apr 30, 2018 at 4:13
52

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.

Specifically, the values m or h are passed to the valign= key which centers the content, which can be found in section 2.5 Rows and Columns in the documentation.

\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 bothering about the layout.% } \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} 

enter image description here

4
  • I add the pointer to the relevant documentation section, I hope you don't mind. (it's hard to search for single-character keys) -- also, I think if you say (in the manual) t and b vertical alignment are counterintuitive, it would makes more sense to default to h type instead. (may break some backwards compatibility however.) Commented Feb 3, 2023 at 15:22
  • Side note, the reason why in the first table it need to be of type h instead of the usual m has something to do with baseline, and is explained in Vertical alignment broken with graphics in tabularray - TeX - LaTeX Stack Exchange. Commented Feb 3, 2023 at 16:36
  • Is this compatible with the longtable package? Commented Jan 6, 2024 at 15:11
  • @მამუკაჯიბლაძე tabularray has its own support for long table Commented Oct 8, 2024 at 9:10
34

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:

enter image description here

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} 
8
  • 2
    This doesn't seem to work in a tabularx env. Commented May 24, 2019 at 7:07
  • 3
    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}} Commented Jan 26, 2020 at 16:13
  • 2
    @SanzioAngeli : Use \begin{tabular}{|@{}l@{}|@{}c@{}|@{}c@{}|} instead of \begin{tabular}{|l|c|c|}. I edited the answer accordingly. Commented Mar 19, 2020 at 8:41
  • 6
    didn't work for me :-/ Commented Apr 22, 2020 at 20:07
  • 1
    @AnthonyScemama In my case, since not all the cell lines had to be edited, I better off put the @{}s in the definition of the inner tables. Commented Sep 27 at 5:46
11

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: enter image description here

11

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 "example-image.jpg" width 3cm & \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 

enter image description here

9

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.

2

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] 
1

For hopeless people who couldn't make any of the above solutions work:

Define a parbox and manually offset your text. The following macro should do it.

\newcommand{\centeredtxt}[1]{ \begin{tabular}{l} \parbox{2cm}{\vspace{-50pt} \centering #1} \end{tabular} } 
1
  • Welcome to TeX.SE. Please extend your code fragment to complete small document, by which we can test your solution and eventually confirm it usefulness. BTW, similar approach is described in accepted answer. Commented Dec 13, 2023 at 21:40

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.