# Arrow length in tikz-cd diagrams

Is there an easy way to modify the length of an arrow between two nodes in a tikz-cd diagram (while keeping the distance between the nodes fixed)?

For example, the diagonal arrow in the diagram

\begin{tikzcd}[column sep = large, row sep = large]
* \dar \rar &* \dar \dlar[Rightarrow]{}    \\
* \rar &*
\end{tikzcd}


would look a lot better for what I need (it's an arrow between the two paths in the diagram, not between the nodes) if it were, say, half as long. This could be accomplished by changing the start and end anchor coordinates, but that's unwieldy and scales horribly if you need to do it repeatedly in diagrams of different shapes.

• I've updated my answer with some explanation on how to use the new style to scale the arrows. – Gonzalo Medina Feb 4 '15 at 16:54

## Improved version

In this improved version, you can apply a scaling factor to the arrow:

\documentclass{article}
\usepackage{tikz-cd}
\usetikzlibrary{decorations.markings,intersections}

\tikzset{%
scalearrow/.style n args={3}{
decoration={
markings,
mark=at position (1-#1)/2*\pgfdecoratedpathlength
with {\coordinate (#2);},
mark=at position (1+#1)/2*\pgfdecoratedpathlength
with {\coordinate (#3);},
},
postaction=decorate,
}
}

\begin{document}

\noindent
Scaling factor=1 (no scaling):\par
\begin{tikzcd}[row sep=huge,column sep=huge]
A \dar\rar & B\dar\dlar[phantom,scalearrow={1}{start}{end}]\arrow[dr,Rightarrow,to path= (start) -- (end)]  \\
C \rar & D
\end{tikzcd}
\par\medskip

\noindent
Scaling factor=0.5:\par
\begin{tikzcd}[row sep=huge,column sep=huge]
A \dar\rar & B\dar\dlar[phantom,scalearrow={0.5}{start}{end}]\arrow[dr,Rightarrow,to path= (start) -- (end)]  \\
C \rar & D
\end{tikzcd}

\par\medskip

\noindent
Two arrows, each with scaling factor=0.3333:\par
\begin{tikzcd}[row sep=huge,column sep=huge]
A
\dar\rar
&
B
\dar
\dlar[phantom,scalearrow={0.3333}{starta}{enda}]
\arrow[dr,Rightarrow,to path= (starta) -- (enda)] &
C
\dar\lar
\\
D \rar
&
E
&
F
\lar
\ular[phantom,scalearrow={0.3333}{startb}{endb}]
\arrow[ul,Rightarrow,to path= (startb) -- (endb)]
\end{tikzcd}

\end{document}


The idea is to measure the path length using a decoration and \pgfdecoratedpathlength and to place two marks along the path such that the distance between those marks is the path length scaled by the desired factor.

This is achieved by using a "phantom" arrow with the scalearrow style; in this style you set the scaling factor (first argument for the style) and two names internally used for the start and end of the scaled path so, for example,

\dar[phantom,scalearrow={0.3333}{name1}{name2


places a downwards arrow from the current node (let's refer to it as X) to the node below it (let's refer to it as Y) and sets two internal coordinates called name1 and name2 at the exact position along the path from X to Y in such a way that now you can use those names to draw the scaled arrow (using a factor of 0.3333 for the scaling) using, for example

\arrow[d,Rightarrow,to path= (name1) -- (name2)]


## First version

One option using shorten:

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

\begin{document}

\begin{tikzcd}[column sep = large, row sep = large]
* \dar \rar &* \dar \dlar[Rightarrow,shorten >= 10pt,shorten <= 10pt]{}    \\
* \rar &*
\end{tikzcd}

\end{document}


• Thanks, I overlooked this option in the documentation, and it works a lot better. I'd be interested to see if there's a solution that uses scaling instead of length deduction, but if not, I'll gladly accept this answer. – user54748 Feb 3 '15 at 20:46
• @user54748 I updated my answer with a new approach using a scaling factor, as requested :) – Gonzalo Medina Feb 4 '15 at 3:26
• How would you add a label to the shrinked arrow ? the normal placement of label seems to be dropped by this nice solution. – nicolas Feb 24 '17 at 11:00