3

I was trying to answer a question but the TikZcd I would like to typeset is not well vertically positioned between the curly braces (the red lines are drawn to better show the problem):

\documentclass{article}
\usepackage{geometry}
\usepackage{amsmath}

\usepackage{tikz-cd}
\newcommand{\tricd}[3]{%
    \begin{tikzcd}[
        ampersand replacement=\&, 
        every matrix/.append style={nodes={inner sep=0pt, draw=red}, draw=red}, 
        row sep=0pt,
        column sep=10pt,
        ]
        #1\ar[rr]\ar[dr]\&\&#2\ar[dl]\\
        \&#3
    \end{tikzcd}%
    }
    
\begin{document}
Why is the Ti\emph{k}Zcd not well
vertically aligned between braces? \(
\left\{\tricd{X}{Y}{Z}\right\}
\)
\end{document}

enter image description here

3
  • it's like pineapple pizza. It is perfectly aligned but your expectation is wrong. Mar 9 at 21:09
  • 1
    @DavidCarlisle It's not good, like pineapple pizza.
    – CarLaTeX
    Mar 9 at 21:13
  • 1
    baseline={([yshift=-.5ex]\tikzcdmatrixname) should align the center of the matrix (not the whole TikZ picture) so that it sits 0.5ex above the baseline. Mar 9 at 22:47

4 Answers 4

4

When a TikZ picture has been created it will be just a box with its lowest point of the bounding box on the baseline.

TikZ-CD overwrites this default. For a 1-row diagram it will be placed in such a way that the baseline of the nodes will be on the baseline of the surrounding text.
For any other diagram its baseline will be the center of the matrix (not the whole picture) which is also y = 0 pt by default.

This is usually a good choice because the diagram is either on its own line (e.​g. in the figure environment) or the only element of a display-math environment.

For inline diagrams the box needs to be shifted up so that the matrix's center is on the height of that brace's nub. TikZ-CD brings with it a PGFMath function axis_height that allows you to use this distance inside of PGF/TikZ.

Thus, you will need

baseline={([yshift=-axis_height]\tikzcdmatrixname)}
% or, if no vertical shifting of the matrix has been applied, just
baseline=-axis_height

for your inline diagrams.


I took the liberty to adjust some inner and outer seps so that the nodes and the matrix are tightly packed but the nodes still have a bit padding for the arrows left. If labels, i.e. nodes along the arrows, should be able to be used, their outer sep should be set to 0pt or the default .5\pgflinewidth again.

Notes:

  • I've added a bended (but overlayed) arrow which doesn't interfer with how the braces are measured.

  • The matrix library provides left delimiter and right delimiter. However, since \left/\right don't output exact lengths for the delimiters and the library places the delimiters somewhat unlucky these can't be used here without adjusting how TikZ places them.

    The solution with TikZ's delimiters is commented in the code below.

Code

\documentclass{article}
\usepackage{geometry}
\usepackage{amsmath}
\usepackage{tikz-cd}
%\makeatletter
%\tikzset{better delimiters/.style={
%  /tikz/every left delimiter/.append style={at=(\tikz@last@fig@name.west),anchor=east},
%  /tikz/every right delimiter/.append style={at=(\tikz@last@fig@name.east),anchor=west}}}
%\makeatother
\newcommand{\tricd}[3]{%
  \begin{tikzcd}[
    baseline={([yshift=-axis_height]\tikzcdmatrixname)},
    ampersand replacement=\&,
%    /tikz/better delimiters,
    every matrix/.append style={% https://tex.stackexchange.com/a/653533/16595
%      left delimiter=\{, right delimiter=\},
      every outer matrix/.append style={inner sep=+0pt, outer sep=+0pt},
      cells={nodes={inner sep=+0pt, outer sep=+.15em, draw=red}},
      draw=red},
    row sep=0pt, column sep=10pt]
    #1\ar[rr]\ar[dr]\&\&#2\ar[dl] \ar[ll, bend right, overlay]\\
    \&#3
  \end{tikzcd}}
\begin{document}
Why is the Ti\emph{k}Zcd not well vertically aligned between braces?
\( \left\{ \tricd{X}{Y}{Z} \right\} \)
\end{document}

Output

enter image description here

4

enter image description here

you would see the same with \left\{\begin{array}[t]... The X are aligned on the baseline so the construct has large depth, but \{ are vertically centred. Nudge the baseline of the tikz:

\documentclass{article}
\usepackage{geometry}
\usepackage{amsmath}

\usepackage{tikz-cd}
\newcommand{\tricd}[3]{%
    \begin{tikzcd}[
baseline=-2pt,
        ampersand replacement=\&, 
        every matrix/.append style={nodes={inner sep=0pt, draw=red}, draw=red}, 
        row sep=0pt,
        column sep=10pt,
        ]
        #1\ar[rr]\ar[dr]\&\&#2\ar[dl]\\
        \&#3
    \end{tikzcd}%
    }
    
\begin{document}
Why is the Ti\emph{k}Zcd not well
vertically aligned between braces? \(
\left\{\tricd{X}{Y}{Z}\right\}
\)
\end{document}
3

Use gathered.

\documentclass{article}
\usepackage{geometry}
\usepackage{amsmath}
\usepackage{tikz-cd}

\newcommand{\tricd}[3]{%
  \begin{gathered}%
    \begin{tikzcd}[
        ampersand replacement=\&,
        every matrix/.append style={nodes={inner sep=0pt}},
        row sep=0pt,
        column sep=10pt,
        ]
        #1\ar[rr]\ar[dr]\&\&#2\ar[dl]\\
        \&#3
    \end{tikzcd}%
  \end{gathered}%
}

\begin{document}

The Ti\emph{k}Zcd is well
vertically aligned between braces! \(
\left\{\tricd{X}{Y}{Z}\right\}
\)

\end{document}

enter image description here

2

You can add \vcenter{\hbox{...}} around the tikzcd.

enter image description here

\documentclass{article}
\usepackage{geometry}
\usepackage{amsmath}

\usepackage{tikz-cd}
\newcommand{\tricd}[3]{%
    \vcenter{\hbox{\begin{tikzcd}[
        ampersand replacement=\&, 
        every matrix/.append style={nodes={inner sep=0pt, draw=red}, draw=red}, 
        row sep=0pt,
        column sep=10pt,
        ]
        #1\ar[rr]\ar[dr]\&\&#2\ar[dl]\\
        \&#3
    \end{tikzcd}}}%
    }
    
\begin{document}
Why is the Ti\emph{k}Zcd not well
vertically aligned between braces? \(
\left\{\tricd{X}{Y}{Z}\right\}
\)
\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .