# uniform entry sizes in tikzcd

I've asked before about the easiest way to normalize entry sizes in tikzcd but feel like I still don't understand the best practices to draw a relatively symmetric diagram with widely divergent entry sizes. (By "symmetric" I mean that I'd like to be able to ensure that the overall shape is a square (or rotated square) and that composable diagonal arrows are actually parallel, when appropriate.)

Here's an example that I've attempted to normalize in three different ways, using various tricks that I've learned on this site.

I understand attempt 1 the best: \makebox is used to spoof the entry size and shorten is used to adjust the length of the arrows. But in practice, this approach feels to ad hoc.

It's been suggested elsewhere to use between origins as I've done in attempt 2, but I don't understand what this actually does, or what my other options might be. In practice this seems to look great half the time and terribly the other half of the time (or half great and half terribly like here).

The third attempt I understand even less. Basically I'm looking for someone to give a quick tutorial on different potential techniques. This is one of hundreds of diagrams, so I need a solution I can modify to many other settings with different diagram shapes.

\documentclass{article}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{tikz-cd}
\usepackage{makebox}
\begin{document}
Attempt 1:
$\begin{tikzcd}[column sep=0em, row sep=small] & & \hom_A(a,A) \underset{X}{\times} \hom_B(B,b) \arrow[dl, two heads, "\pi_1"'] \arrow[dd, phantom, "\rotatebox{135}{\ulcorner}" pos=.1] \arrow[dr, two heads, "\pi_0"] \\ & \hom_A(a,A) \arrow[dl, two heads, "p_1"', shorten >=-1em] \arrow[dr, two heads, "p_0"] & & \hom_B(B,b) \arrow[dl, two heads, "p_1"'] \arrow[dr, two heads, "p_0", shorten >=-1em] \\ \makebox*{\hom_A(a,A)A}{A} & & X & & \makebox*{A\hom(a,A)_A}{B} \end{tikzcd}$
Attempt 2:
$\begin{tikzcd}[column sep={4em,between origins}] & & \hom_A(a,A) \underset{X}{\times} \hom_B(B,b) \arrow[dl, two heads, "\pi_1"'] \arrow[dd, phantom, "\rotatebox{135}{\ulcorner}" pos=.1] \arrow[dr, two heads, "\pi_0"] \\ & \hom_A(a,A) \arrow[dl, two heads, "p_1"'] \arrow[dr, two heads, "p_0"] & & \hom_B(B,b) \arrow[dl, two heads, "p_1"'] \arrow[dr, two heads, "p_0"] \\ \makebox*{\hom_A(a,A)A}{A} & & X & & \makebox*{A\hom(a,A)_A}{B} \end{tikzcd}$
Attempt 3:
$\begin{tikzcd}[nodes in empty cells, column sep=-3ex, row sep=1em, cells={nodes={minimum width=1em, inner sep=1pt}}] & & \hom_A(a,A) \underset{X}{\times} \hom_B(B,b) \arrow[dl, two heads, "\pi_1"'] \arrow[dd, phantom, "\rotatebox{135}{\ulcorner}" pos=.1] \arrow[dr, two heads, "\pi_0"] \\ & \hom_A(a,A) \arrow[dl, two heads, "p_1"'] \arrow[dr, two heads, "p_0"] & & \hom_B(B,b) \arrow[dl, two heads, "p_1"'] \arrow[dr, two heads, "p_0"] \\ \makebox*{\hom_A(a,A)A}{A} & & X & & \makebox*{A\hom(a,A)_A}{B} \end{tikzcd}$
\end{document}


Since your pullback is a very large object I believe you need to separate different rows with different sizes, for this you can use &[...]. The same for columns \$...]. This is maybe not the best solution: \documentclass{article} \usepackage{amsmath} \usepackage{amssymb} \usepackage{tikz-cd} \begin{document} \begin{center} \begin{tikzcd} &[-5mm]&[-24mm] \hom_A(a,A) \times_X \hom_B(B,b) \ar[two heads]{ld}\ar[two heads]{rd} \ar{rd} \ar[phantom, very near start]{dd}{\rotatebox{-45}{\lrcorner}} \\[3mm] & \hom_A(a,A)\ar[two heads]{ld}\ar[two heads]{rd} &&[-24mm] \hom_B(B,b)\ar[two heads]{ld}\ar[two heads]{rd}\\[3mm] A && X &&[-5mm] B \end{tikzcd} \end{center} \end{document}  ## Second approach, with tikz Since I cannot figure out an automatic way to achieve this and many other possible diagrams I will only give an easier way to obtain the desired output. I will use calc library to make some calculations. I'll put the pullback at the top and everything else will be below. From the angles given in the first entry for the other objects and the length given in the second entry is easy to calculate the height of the triangle \hom_A(a,A) \times_X \hom_B(B,b) \hom_A(a,A) \hom_B(b,B). In this case is 2 sin(45) or 2 · 1/sqrt(2) From which the desired length for the object X is 4 · 1/sqrt(2) here is where I use calc. Is not an automatic way to create such diagrams but at least with an easy calculation you can achieve the desired output: \documentclass{article} \usepackage{amsmath} \usepackage{amssymb} \usepackage{tikz-cd} \usetikzlibrary{calc} \begin{document} \[ \begin{tikzpicture}[commutative diagrams/every diagram] \node (P) at (0:0) {\hom_A(a,A) \times_X \hom_B(B,b)}; \node (A) at (225:2) {\hom_A(a,A)} ; \node (B) at (315:2) {\hom_B(B,b)}; \node (x) at (270:4/sqrt 2) {X}; \node (a) at (225:4) {A}; \node (b) at (315:4) {B}; \path[commutative diagrams/.cd, every arrow, every label] (P) edge[->>] (A) (P) edge[->>] (B) (A) edge[->>] (a) (A) edge[->>] (x) (B) edge[->>] (x) (B) edge[->>] (b); \end{tikzpicture}$
\end{document}


I write [->>] in every edge because is possible that not all the arrows in future diagrams be epimorphic.

• Thanks for the suggestion. The output looks great. Is there any systematic way to work out the measurements (eg -5mm, -24mm, -3mm). I'm never sure what best practices are either (i) for selecting the units "mm" vs "em" vs "in" or (ii) for working out the optimal numerical value. Aug 12, 2020 at 15:20
• I'm not sure I can make an automatic version of these diagrams. I'll try to do it, if I can, I'll let you know. It might be better to use measurements like em instead of mm, but if you're not thinking of changing fonts then there should be no problem using mm. Aug 12, 2020 at 15:28

You can get a “quasi square” by lowering the X. The wide objects are assigned a smaller width.

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

\newcommand{\zb}[2][2em]{\makebox[#1]{$\displaystyle#2$}}

\begin{document}

$\begin{tikzcd} & & \zb{\hom_A(a,A) \underset{X}{\times} \hom_B(B,b)} \arrow[dl, two heads, "\pi_1"'] \arrow[dd, phantom, "\rotatebox{135}{\ulcorner}" pos=.1] \arrow[dr, two heads, "\pi_0"] \\ & \zb{\hom_A(a,A)} \arrow[dl, two heads, "p_1"'] \arrow[ddr, two heads, "p_0"] & & \zb{\hom_B(B,b)} \arrow[ddl, two heads, "p_1"'] \arrow[dr, two heads, "p_0"] \\ A & & {} & & B \\[-2.5em] && X \end{tikzcd}$

\end{document}