They are centred vertically. That is, they are centred on the current baseline. (See explanation below.) The problem is that the bottom of the tikzpicture
is on the baseline by default. To centre that, we can use baseline
in the argument for the picture:
\documentclass[12pt,letterpaper]{article}
\usepackage{array}
\usepackage{tabularx}
\usepackage{tikz}
\usepackage{cellspace}
\setlength\cellspacetoplimit{10pt}
\setlength\cellspacebottomlimit{4pt}
\addparagraphcolumntypes{X}
\newcolumntype{C}[1]{>{\centering\arraybackslash}m{#1}}
\newcolumntype{Y}{>{\centering\arraybackslash}X}
\begin{document}
\begin{tabularx}{16cm}{|C{2.5cm}|C{3cm}|Y|} \hline
\textbf{Parts Per Whole} & \textbf{Name of Each Part} & \textbf{Number Line} \\ [0.2cm] \hline
3 & third &
\begin{tikzpicture}[xscale=4 , yscale=2, baseline=(current bounding box.center)]
\draw (0,0)--(2,0) ;
\foreach \x in {0,...,6}
\draw (\x/3,-0.2)--(\x/3,0.2);
\foreach \x in {0,...,2} \node[below] at (\x,-0.35) {\x};
\end{tikzpicture} \\ [0.2cm] \hline
\end{tabularx}
\end{document}
Note that the tabular is too wide for the page. Also, you might want to read booktabs
' manual which has some recommendations for laying out professional quality tables.
For example, adjusting things to fit and using booktabs
:
\documentclass[12pt,letterpaper]{article}
\usepackage{array,booktabs}
\usepackage{tabularx}
\usepackage{tikz}
\usepackage{cellspace}
\setlength\cellspacetoplimit{10pt}
\setlength\cellspacebottomlimit{4pt}
\addparagraphcolumntypes{X}
\newcolumntype{C}[1]{>{\centering\arraybackslash}m{#1}}
\newcolumntype{Y}{>{\centering\arraybackslash}X}
\begin{document}
\noindent\begin{tabularx}{\textwidth}{C{2.5cm}C{3cm}Y}
\toprule
\textbf{Parts Per Whole} & \textbf{Name of Each Part} & \textbf{Number Line} \\\midrule
3 & third &
\begin{tikzpicture}[xscale=3, yscale=1.5, baseline=(current bounding box.west)]
\draw (0,0)--(2,0) ;
\foreach \x in {0,...,6}
\draw (\x/3,-0.2)--(\x/3,0.2);
\foreach \x in {0,...,2} \node[below] at (\x,-0.35) {\x};
\end{tikzpicture}\\ \bottomrule
\end{tabularx}
\end{document}
Explanation
This is obviously not a complete explanation but merely an indication of how TeX is aligning things vertically.
In this answer I illustrate the way TeX aligns things vertically by playing with some minipage
s and showing how the alignment options affect their position relative to a line of text or to each other.
Here, I use the same idea to illustrate alignment of m{}
columns within a tabular
. Each cell in the tabular
includes a minipage
. The top blue line is the baseline of the first line of text. The bottom one is the baseline of the last line of text. The blue letter t
, b
or c
is the alignment of the minipage
- top, bottom or centred. This tells TeX which point of the minipage should be aligned to the current baseline. The baseline is shown in red.
It is important to remember that everything is a box. TeX doesn't care what is inside the boxes. It just follows a set of rules for laying out boxes on a page. A single letter is a box. So is a comma. So is an entire tikzpicture
or a minipage
or the contents of a cell in a tabular
. Smaller boxes can be put together to form bigger boxes: a tabular
is a big box containing smaller boxes. How stuff is aligned depends on which box TeX is aligning and how that is aligned. The baseline is adjusted to ensure things are aligned according to the options (or defaults) requested.
Alignment is relative to the current baseline. The baseline is not fixed. The location of the baseline depends on the content of the line. A large box (like a tikzpicture
) will shift the baseline down by default because the default setting is to align its bottom with the current baseline and the only way to make room for it is to shift the baseline down.
\documentclass[a4paper]{article}
\usepackage{geometry}
\geometry{vscale=.975}
\pagestyle{empty}
\usepackage{tikz,array,tikzpagenodes}
\usetikzlibrary{tikzmark}
\begin{document}
\newcommand\demobox[1]{%
\fbox{%
\begin{minipage}[#1]{.25\textwidth}
\tikz[baseline=(n.base)]{%
\node (n) [inner sep=0pt, outer sep=0pt, text width=\linewidth] {Top};
\draw [blue] (n.west |- n.base) -- (n.east |- n.base);}
\par
This is a box with baseline at \textcolor{blue}{\bfseries #1}.
\par
\tikz[baseline=(n.base)]{%
\node (n) [inner sep=0pt, outer sep=0pt, anchor=base, text width=\linewidth] {Bottom};
\draw [blue] (n.west |- n.base) -- (n.east |- n.base);}
\end{minipage}}}
\tikzmark{first}
\begin{tabular}{m{.25\textwidth}p{.25\textwidth}p{.25\textwidth}}
\demobox{c}&\demobox{c}&\demobox{c}\tikzmark{1}\\
\demobox{t}&\demobox{t}&\demobox{t}\tikzmark{2}\\
\demobox{b}&\demobox{b}&\demobox{b}\tikzmark{3}\\
\demobox{t}&\demobox{c}&\demobox{b}\tikzmark{4}\\
\end{tabular}
\vfill
\hrule
\vfill
\tikzmark{centre}
\begin{tabular}{p{.25\textwidth}m{.25\textwidth}p{.25\textwidth}}
\demobox{c}&\demobox{c}&\demobox{c}\tikzmark{5}\\
\demobox{t}&\demobox{t}&\demobox{t}\tikzmark{6}\\
\demobox{b}&\demobox{b}&\demobox{b}\tikzmark{7}\\
\demobox{t}&\demobox{c}&\demobox{b}\tikzmark{8}\\
\end{tabular}
\vfill
\hrule
\vfill
\tikzmark{final}
\begin{tabular}{p{.25\textwidth}p{.25\textwidth}m{.25\textwidth}}
\demobox{c}&\demobox{c}&\demobox{c}\tikzmark{9}\\
\demobox{t}&\demobox{t}&\demobox{t}\tikzmark{10}\\
\demobox{b}&\demobox{b}&\demobox{b}\tikzmark{11}\\
\demobox{t}&\demobox{c}&\demobox{b}\tikzmark{12}\\
\end{tabular}
\begin{tikzpicture}[remember picture, overlay]
\node [left, align=left, text width=.2\textwidth] at ({pic cs:first}) {Vertically centre \textcolor{blue}{\bfseries first} column};
\node [left, align=left, text width=.2\textwidth] at ({pic cs:centre}) {Vertically centre \textcolor{blue}{\bfseries middle} column};
\node [left, align=left, text width=.2\textwidth] at ({pic cs:final}) {Vertically centre \textcolor{blue}{\bfseries last} column};
\foreach \i in {1,...,12} \draw [red] ({pic cs:\i} -| current page text area.west) -- ({pic cs:\i} -| current page text area.east);
\end{tikzpicture}
\end{document}
Here is how this works with multiline text without minipages. The red lines mark the current baseline.
\documentclass[a4paper]{article}
\usepackage{array,geometry,tikz,tikzpagenodes}
\usetikzlibrary{tikzmark}
\geometry{scale=.9}
\newcommand\mykant{Let us suppose that the noumena have nothing to do with necessity, since knowledge of the Categories is a posteriori.}
\begin{document}
\begin{tabular}{m{.25\textwidth}p{.25\textwidth}p{.25\textwidth}}
\multicolumn{3}{c}{\bfseries First column vertically centred}\\
\mykant & \tikzmark{a}some text & \mykant\\
\end{tabular}
\bigskip
\hrule
\bigskip
\begin{tabular}{p{.25\textwidth}m{.25\textwidth}p{.25\textwidth}}
\multicolumn{3}{c}{\bfseries Middle column vertically centred}\\
\mykant & some text\tikzmark{b} & \mykant\\
\end{tabular}
\bigskip
\hrule
\bigskip
\begin{tabular}{p{.25\textwidth}p{.25\textwidth}m{.25\textwidth}}
\multicolumn{3}{c}{\bfseries Last column vertically centred}\\
\mykant & some text\tikzmark{c} & \mykant\\
\end{tabular}
\begin{tikzpicture}[remember picture, overlay]
\foreach \i in {a,b,c}
\draw [draw=red] ({pic cs:\i} -| current page text area.west) -- ({pic cs:\i} -| current page text area.east);
\end{tikzpicture}
\end{document}
\m
? I don't see that anywhere in the code you posted.m{}
not\m{}
. I'll fix that in the original post. In the code, there is am{}
underneath the comment " % To center the first two columns. "m{..}
doesn't work if it is not the last column. If it is, then all columns are vertically centered regardless of column specifier.This problem was ones already discussed in SE, but I cant remember the question.m{...}
works everywhere EXCEPT the last column?