2

How can I vertically center the first three columns such that all the values in these columns are in the center?

\begin{center}
\begin{tabular}{|c| c |c| p{5cm}|}
\hline

\rowcolor[gray]{.8}Day & Min Temp & Max Temp & \multicolumn{1}{c|}{ Summary} \\ \hline

Monday & 11C & 22C & A clear day with lots of sunshine. 
However, the strong breeze will bring down the temperatures \\ \hline 

Tuesday & 9C & 19C & Cloudy with rain, across many northern regions. 
Clear spells across most of Scotland and Northern Ireland, but rain 
reaching the far northwest \\ \hline

Wednesday & 10C & 21C & Rain will still linger for the morning. 
Conditions will improve by early afternoon and continue throughout the evening.                        \\ \hline

\end{tabular}
\end{center}

enter image description here

It should look like this:

enter image description here

Edit:

Here's what I tried from the questions pasted in comments:

\begin{center}
\renewcommand{\tabularxcolumn}[1]{m{#1}}
\begin{tabularx}{|m{1in}|c|c| p{5cm}|}
\hline

\rowcolor[gray]{.8}Day & Min Temp & Max Temp & \multicolumn{1}{c|}{ Summary} \\ \hline

Monday                     & 11C                             & 22C                             & A clear day with lots of sunshine. However, the strong breeze will bring down the temperatures                                                 \\ \hline
Tuesday                    & 9C                              & 19C                             & Cloudy with rain, across many northern regions. Clear spells across most of Scotland and Northern Ireland, but rain reaching the far northwest \\ \hline
Wednesday                  & 10C                             & 21C                             & Rain will still linger for the morning. Conditions will improve by early afternoon and continue throughout the evening.                        \\ \hline
\end{tabularx}
\end{center}

It still doesn't work.

2

Welcome to TeX.SE!

Please consider posting a complete MWE next time. I added some missing parts to my answer, but missed the grey background color in the heading line. Consider this as your homework ;-)

LaTeX basically knows two types of columns. One type, where LaTeX calculates the width of the column itself. The letters l, c and rrepresent this type of columns. The columns "growths" in width, whenever the author adds text to them.

On the other hand, we do have the type of columns, where the author defines a width. The identifier for this columntype is e.g. p{<width>}. You have used it for your last column and defined p{5cm} in your MWE. This column shall be 5 cm wide. If the author (i.e. you!) add more text, that is wider than 5 cm, LaTeX will break the text and begins a new line. The resulting column will be formatted in justified text, as you can see in your examples.

To get your desired results, all you have to do is

  1. load the array package
  2. use the the m{<width>} column type instead of c or p{<width>} columns

Of course, this is only half the truth.

The array packages offers you the m and the b column types. They act like the p column in that the user has to define its width. LaTeX will than break lines and produce justified text. The difference between those column types is the vertical alignment. The rule of thumb is:

  • p is aligned at the toP,
  • m is aligned at the Middle and
  • b is aligned at the Bottom.

(Please read the array manual, to understand the exact behaviour!)

So using an m type of column in your table will align all lines vertically centered, as you requested.

But we also have to address the horizontal alignment. The m columns behave the same, as the p columns, which we just replaced. In the last column, this behaviour is OK. But in the first columns we want the text also to be centered horizontally.

Here comes the next trick, offered by the array package. You can use the >{cmd}. Visualise the > as an arrow, which pushes the cmd from inside the curly braces to the column next to it. If you define in your tabular something like

\begin{tabular}{ l >{\raggedright}p{5cm} l }

you will get a p type of column of 5 cm width in the middle between two usual l columns as first and last column of that table.

But the >{\raggedright} pushes the command \raggedright into that m column, everytime you enter this second column. This command will change the alignment in that second column to be flush on the left side and a ragged on its right side.

Instead of the above definition, you could have typed

\begin{tabular}{l p{5cm} l}
first cell & \raggedright lots of text in the second cell, which is flush left & third cell \\
next line, first cell & \raggedright again lots of text ... & third cell \\
new line first cell & \raggedright ... & ... \\
once again & \raggedright ... & end \\
\end{tabular}

But in this case, you have to enter the \raggedright command everytime you enter the second column, which might get annoying very fast. Instead of typing it every time you enter that column, the >{\raggedright} trick from the former definition will do it automatically for you. Sounds promising to me.

To get a real clean LaTeX code, you should add \arraybackslash\hspace{0pt} to the above example. But this monstrous string will make your input code unreadable. So I present the next trick.

The array package also offers the \newcolumntype command. You should use it in the preamble of your document (i.e. before \begin{document}). Just choose a letter to act as a new column type. You asked for a centered type of column. Therefore I suggest the letter "C", which wasn't defined before.

So the simplest solution would be

\newcolumntype{C}{>{\raggedright\arraybackslash\hspace{0pt}}m{5cm}}

and replace all your column definitions (c and p{5cm}) with this brand new and shiny C column type.

\begin{tabular}{|C|C|C|C|}

Sometimes a such a simple solution has some major drawbacks. In your particualr case, every column in your table is now 5 cm wide. I guess, its not exactly, what you want, right? The first three columns don't need to be 5 cm wide. How could we solve that?

Here is my next enhancement. In the first row, the widest entry seems to be the word "wednesday". So let LaTeX determine its width and use that as width for the first column. In order to do so, you can use the command \settowidth to measure the width of the word. But we also have to change our new column definition of C. We have to define it in a more flexible manner. By careful inspection, should realise, that the C column should have a variable width, as p{<width>} has. The p column has one pair of braces. So lets add this to our C column.

\newcolumntype{C}[1]{>{\raggedright\arraybackslash\hspace{0pt}}m{#1}}

See the difference? I added [1] in the beginning of the definition. This means, that the C column must have one pair of braces. The value given in that pair is denoted with #1 at the end of my definition. This gives us the desired flexibility.

The full MWE looks now like this:

\documentclass{article}
\usepackage{array}                  % better control for tabular

%% Define the length of the longest day name
\newlength{\daylength}
\settowidth{\daylength}{Wednesday}

%% Create a new columntype, where the text is vertically and
%% horizontally centered.  The new identifier should be "C".
\newcolumntype{C}[1]{%
  >{\centering\arraybackslash\hspace{0pt}}m{#1}}


\begin{document}
\begin{center}
   \begin{tabular}{|C{\daylength}| C{2cm} | C{2cm} | m{5cm} |}
    \hline
    Day & Min Temp & Max Temp & \multicolumn{1}{c|}{ Summary} \\
    \hline
    Monday & 11C & 22C & A clear day with lots of sunshine. 
    However, the strong breeze will bring down the temperatures \\ 
    \hline 
    Tuesday & 9C & 19C & Cloudy with rain, across many northern regions. 
    Clear spells across most of Scotland and Northern Ireland, but rain 
    reaching the far northwest \\ 
    \hline
    Wednesday & 10C & 21C & Rain will still linger for the morning. 
    Conditions will improve by early afternoon and continue throughout the evening. \\ 
    \hline
  \end{tabular}
\end{center}
\end{document}

and results in this output

enter image description here

Personally, I would also define a new R type of column, which facilitates an flush left aligned column, as this small columns don't look good, when they are justified. I'll add it to your pile of homework. :-)


EDIT

\arraybackslash enables you again, to use \\ to end the tableline and start a new line. \hspace{0pt} enables LaTeX to start breaking in the first word, which is important in very small columns.

| improve this answer | |
  • Thanks, that was the best answer to my question. Actually, I didn't know that it'd take much just to center align stuff in tables. Can I only center align the text in a single row e.g. the header row of the table? – cpx Dec 6 '19 at 20:36
  • @cpx You are welcome. If it solved your problem, click the "solved" checkmark. What do you mean by "center align"? Looking at the output of my example, the headers in the first line are horizontally centered. Is that an answer to your question? – Jan Dec 7 '19 at 0:30
  • Yes, they are horizontally centered, but I also want vertical centering of the header in case when I add more text into table. – cpx Dec 7 '19 at 0:36
  • @cpx in that case, just use the m type of column in your heading also. Additionally, you can use \newline to create a manual break in a particular cell and force linebreaks. My MWE uses the Ctype column, which internally is derived from the m-type. So it will work fine. BTW: if "11C" should read "11 °C", than use \usepackage{siunitx} in your preambel and write \SI{11}{\celsius} in your table. Read the long and fine manual siunitx.pdf. – Jan Dec 7 '19 at 0:42
  • Can I also use your C to center (horizontal + vertical) just a single cell in the table? – cpx Dec 7 '19 at 0:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.