# Set absolute length of arrow in tikzcd

If you want to change the lengths of arrows in a tikzcd diagram, there are lots of options:

• Append "shorten => 10pt" or "shorten >= 15pt" to the arrow description.
• Change the row/column separation using [{column sep = 15pt, row sep = 20pt}] at the start of the tikzcd.
• Change individual column/row separations using [-15pt] or [5pt] before the appropriate & or // .

If I want the absolute length of all (or one) of my arrows to be say 20pt, how can I do that?

That is, so all (or one in particular) of my arrows is 20pt long. Note that none of the above options do this.

• What should happen when the available length is less than 20pt? Where along the distance should those 20pt be? At the start, at the middle, or the end? What about curved arrows? Nov 4, 2022 at 21:00

Here is a possibility. Define a new arrow type called myarrow, which is a white arrow decorated with a special arrowhead. The arrowhead is a Butt Cap of a given length followed by a standard arrowhead (shifted to keep it centered). The length is controlled globally by \myarrowlength. You can then use myarrow for a single arrow as in the first example using \arrow[r, myarrow], or for all arrows as in the second example using \begin{tikzcd}[arrows=myarrow]

\documentclass{article}

\usepackage{tikz-cd}
\usetikzlibrary{decorations.markings}

\newcommand{\myarrowlength}{10pt}

\tikzset{mytip/.tip={Butt Cap[black, length=\myarrowlength, sep=-1.6pt]>[black]},
myarrow/.style={white, decoration={transform={xshift=.5*\myarrowlength}, markings, mark=at position .5 with {\arrow{mytip}}}, postaction=decorate}}

\begin{document}

\begin{tikzcd}
A\arrow[dr]\\
B\arrow[u]\arrow[r, myarrow] & C
\end{tikzcd}
\begin{tikzcd}[arrows=myarrow]
A\arrow[dr]\\
B\arrow[u]\arrow[r] & C
\end{tikzcd}

\end{document}


## Update:

To add labels to the arrows, the white arrow must get a label. This is now included in the definition, along with a default empty label. For example, myarrow="h"' will place the label h on the "right" side. Use {} for more complicated labels, e.g., myarrow={"h"', text=red}.

\documentclass{article}

\usepackage{tikz-cd}
\usetikzlibrary{decorations.markings}

\newcommand{\myarrowlength}{10pt}

\tikzset{mytip/.tip={Butt Cap[black, length=\myarrowlength, sep=-1.6pt]>[black]},
myarrow/.style={white, text=black, #1, decoration={transform={xshift=.5*\myarrowlength}, markings, mark=at position .5 with {\arrow{mytip}}}, postaction=decorate},
myarrow/.default={}}

\begin{document}

\begin{tikzcd}
A\arrow[dr]\\
B\arrow[u]\arrow[r, myarrow="h"'] & C
\end{tikzcd}
\begin{tikzcd}[arrows=myarrow]
A\arrow[dr]\\
B\arrow[u]\arrow[r] & C
\end{tikzcd}

\end{document}

• Thanks for the answer! I've just noticed that this disables labels on the arrows. Is there any way to shorten arrows compatibly with labels? Jan 22, 2023 at 12:23
• @Pulcinella: I updated my response. Jan 22, 2023 at 16:39
• Thank you so much for all the help! Jan 23, 2023 at 6:04
• I'm really sorry to bother you again - I tried to work this out myself but I wasn't able to. Do you know whether it's possible to make this compatible with making arrows of the form =, ->>, => , etc ? At the moment, when I attempt = arrows, I get a => arrow with an enormous head. Feb 12, 2023 at 9:41

For straight paths the new shorter line can simply be calculated.

The /tikz/commutative diagrams/@shiftabletopath key sets \tikztostart and \tikztotarget to the actual points on the border of the nodes so that the short path is actually placed halfway between the nodes' borders and not their centers.

This will lead to unfortunate drawing when the distance between the nodes is shorter than the specified length (the arrow will cross into the nodes) and will absolutely fail for non-straight arrows. The best solution will be a decoration then, I guess. But then again, I don't think a 20pt bended arrow will help much when the nodes are 100pt away.

## Code

\documentclass{standalone}
\usepackage{tikz-cd}
\usetikzlibrary{calc}
\tikzcdset{
fixed length/.default=10pt,
fixed length/.style={
/tikz/commutative diagrams/@shiftabletopath,
to path={
($(\tikztostart)!.5!(\tikztotarget)!#1/2!(\tikztostart)$)
-- ($(\tikztostart)!.5!(\tikztotarget)!#1/2!(\tikztotarget)$)
\tikztonodes}}}
\begin{document}
\begin{tikzcd}
X           \arrow[r, hook]
\arrow[dr, dashrightarrow, fixed length]
& \bar{X} \arrow[d]\\
& Y
\end{tikzcd}

\begin{tikzcd}[arrows=fixed length]
X           \arrow[r, hook]
\arrow[dr, dashrightarrow]
& \bar{X} \arrow[d]\\
& Y
\end{tikzcd}
\end{document}