Post

Conditional TikZ Decorations Based on Content Height

Conditional TikZ Decorations Based on Content Height

Decorative elements around code blocks enhance visual appeal, but static decorations fail when applied uniformly to content of varying heights. Short code blocks appear cramped with oversized ornaments, while tall blocks may exhibit awkward spacing. This article presents a technique for measuring content height at render time and conditionally rendering TikZ decorations based on computed dimensions.

Problem Statement

Consider a beamer presentation theme with decorative “blob” elements positioned along the edges of minted code blocks. A fixed decoration layout creates visual problems:

  • Short code blocks: Vertical decorations overlap or extend beyond the content area
  • Tall code blocks: Decorations appear too compressed or misaligned with content boundaries
  • Dynamic content: Slides generated from varying source files produce inconsistent visual results

The fundamental issue lies in applying static positioning to dynamic content. LaTeX processes content sequentially without knowledge of final dimensions until rendering completes.

Solution Architecture

The solution leverages tcolorbox overlays, which execute after content dimensions are finalized. The overlay mechanism provides access to computed coordinates through TikZ’s interior and frame nodes. By calculating content height within the overlay, conditional logic determines whether to render decorations and how to position them.

The implementation follows this pattern:

  1. Define minimum height thresholds for different decoration behaviors
  2. Calculate half-height of the interior region using TikZ coordinate extraction
  3. Store computed values globally using \pgfextra for access outside the path
  4. Apply conditional rendering based on dimension comparisons
  5. Position decorations differently for tall versus short content

Core Implementation

The following code section demonstrates the height calculation and conditional positioning logic within a tcolorbox overlay:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
\path let \p1 = (interior.north), \p2 = (interior.south),
\n1 = {0.5*(\y1 - \y2)} % Half the interior height in pt
in
\pgfextra{%
    \pgfmathsetlengthmacro{\halfHeight}{\n1}
    \pgfmathsetlengthmacro{\minHeightPt}{\minHeight}
    \ifdim\halfHeight>\minHeightPt\relax
        % Tall box: position blobs inset from edge
        \pgfmathsetlengthmacro{\tempVertOffset}{\halfHeight - \blobInsetPt}%
    \else
        % Short box: position based on actual height minus padding
        \pgfmathsetlengthmacro{\tempVertOffset}{\halfHeight - \shortBoxPaddingPt}%
    \fi
    \global\let\halfHeightValue\halfHeight
    \global\let\vertoffsetValue\tempVertOffset
};

% Later, conditionally render middle decorations
\ifdim\halfHeightValue>\minHeight\relax
    \node[...] at (Left) { \blobmiddleleft };
    \node[...] at (Right) { \blobmiddleright };
\fi

Coordinate Extraction with let Syntax

The TikZ let operation extracts coordinates from named nodes:

1
\path let \p1 = (interior.north), \p2 = (interior.south)

This assigns the north anchor of the interior to \p1 and the south anchor to \p2. The \y1 and \y2 macros then provide access to the y-coordinates of these points in TeX points.

Computing Derived Values

The \n1 syntax defines a computed value:

1
\n1 = {0.5*(\y1 - \y2)}

This calculates half the vertical span of the interior region. The result feeds into subsequent positioning calculations.

Global Value Storage

The \pgfextra command executes TeX code within a TikZ path without affecting path construction:

1
2
3
4
\pgfextra{%
    \pgfmathsetlengthmacro{\halfHeight}{\n1}
    \global\let\halfHeightValue\halfHeight
};

The \global\let assignment makes the computed value available outside the \path scope. Without \global, the value would be lost when the path completes.

Conditional Logic

Standard TeX dimension comparison determines decoration behavior:

1
2
3
4
5
\ifdim\halfHeight>\minHeightPt\relax
    % Tall box logic
\else
    % Short box logic
\fi

The \relax token prevents TeX from scanning ahead for additional comparison operands.

Decoration Positioning Strategies

Two positioning strategies address different content heights:

Tall Box Strategy

For tall content, decorations inset from the edge by a fixed amount:

1
\pgfmathsetlengthmacro{\tempVertOffset}{\halfHeight - \blobInsetPt}

This positions middle decorations at a consistent distance from the top and bottom edges, regardless of total height. The visual result maintains proportional spacing.

Short Box Strategy

For short content, decorations position relative to actual content:

1
\pgfmathsetlengthmacro{\tempVertOffset}{\halfHeight - \shortBoxPaddingPt}

A smaller padding value keeps decorations closer to content boundaries, preventing them from appearing disconnected from the visual mass of the box.

Blob Decoration System

The decoration system uses TikZ path definitions to create organic shapes. Each blob consists of curved segments combined with fills and strokes:

1
2
3
4
5
6
7
8
9
\def\blobtopleft{%
    \begin{tikzpicture}[scale=\blobscale]
        \fill[blob fill] (0,0) .. controls (0.3,-0.2) and (0.5,0.1) ..
                         (0.8,0) .. controls (0.6,0.3) and (0.2,0.2) ..
                         cycle;
        \draw[blob stroke] (0,0) .. controls (0.3,-0.2) and (0.5,0.1) ..
                           (0.8,0);
    \end{tikzpicture}%
}

Corner, edge, and middle variants position at different locations around the frame. The conditional logic selectively renders middle decorations based on height thresholds.

Scalable Decorations

A tcolorbox key provides decoration scaling without modifying path definitions:

1
2
3
4
\tcbset{
    blob scale/.store in=\blobscale,
    blob scale=1.0
}

Usage within box definitions:

1
2
3
\begin{tcolorbox}[blob scale=0.8]
    % Content with 80% scale decorations
\end{tcolorbox}

The scale value propagates to all blob TikZ pictures through the shared \blobscale macro.

Exported Coordinates

For advanced layouts, the overlay exports frame coordinates globally:

1
2
3
4
5
6
7
8
9
10
11
12
overlay={
    % Calculate and export coordinates
    \coordinate (CodeFrameNW) at (frame.north west);
    \coordinate (CodeFrameSE) at (frame.south east);
    \path let \p1 = (CodeFrameNW), \p2 = (CodeFrameSE) in
        \pgfextra{
            \xdef\codeFrameNWx{\x1}
            \xdef\codeFrameNWy{\y1}
            \xdef\codeFrameSEx{\x2}
            \xdef\codeFrameSEy{\y2}
        };
}

External TikZ pictures can then reference these coordinates:

1
2
3
\begin{tikzpicture}[remember picture, overlay]
    \draw[->] (some node) -- (\codeFrameNWx, \codeFrameNWy);
\end{tikzpicture}

Complete Overlay Example

The following demonstrates a full overlay implementation with conditional decorations:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
\newtcolorbox{decoratedcode}{
    enhanced,
    overlay={
        % Extract dimensions
        \path let \p1 = (interior.north), \p2 = (interior.south),
              \n1 = {0.5*(\y1 - \y2)}
        in \pgfextra{%
            \pgfmathsetlengthmacro{\halfHeight}{\n1}
            \global\let\halfHeightValue\halfHeight

            % Determine positioning strategy
            \ifdim\halfHeight>30pt\relax
                \pgfmathsetlengthmacro{\vertOffset}{\halfHeight - 8pt}
            \else
                \pgfmathsetlengthmacro{\vertOffset}{\halfHeight - 4pt}
            \fi
            \global\let\vertOffsetValue\vertOffset
        };

        % Always render corner decorations
        \node[anchor=north west] at (frame.north west) {\blobtopleft};
        \node[anchor=north east] at (frame.north east) {\blobtopright};
        \node[anchor=south west] at (frame.south west) {\blobbottomleft};
        \node[anchor=south east] at (frame.south east) {\blobbottomright};

        % Conditionally render middle decorations
        \ifdim\halfHeightValue>30pt\relax
            \node[anchor=west] at ([yshift=\vertOffsetValue]frame.west)
                {\blobmiddleleft};
            \node[anchor=east] at ([yshift=\vertOffsetValue]frame.east)
                {\blobmiddleright};
            \node[anchor=west] at ([yshift=-\vertOffsetValue]frame.west)
                {\blobmiddleleft};
            \node[anchor=east] at ([yshift=-\vertOffsetValue]frame.east)
                {\blobmiddleright};
        \fi
    }
}

Integration with Minted

The technique integrates with minted code listings through tcolorbox’s minted library:

1
2
3
4
5
6
7
8
9
10
\tcbuselibrary{minted}

\newtcblisting{decoratedlisting}[1][]{
    listing engine=minted,
    minted language=#1,
    enhanced,
    overlay={
        % Conditional decoration logic here
    }
}

The overlay executes after minted renders the code, ensuring accurate height measurements.

Threshold Tuning

Optimal threshold values depend on decoration dimensions and aesthetic preferences:

ParameterTypical ValuePurpose
\minHeight25-35ptMinimum half-height for middle decorations
\blobInsetPt6-10ptEdge inset for tall boxes
\shortBoxPaddingPt3-5ptContent padding for short boxes

Testing with representative content samples helps identify appropriate values for specific decoration designs.

Summary

Conditional TikZ decorations based on content height solve the visual inconsistency problem inherent in static decoration layouts. The key techniques include:

  • Using tcolorbox overlays for post-render dimension access
  • Extracting coordinates with TikZ let syntax
  • Storing computed values globally with \pgfextra and \global\let
  • Applying \ifdim conditionals for dimension-based branching
  • Implementing different positioning strategies for tall versus short content

The approach generalizes beyond decorative blobs to any content-aware visual element, including callout positioning, connector routing, and adaptive spacing systems.

This post is licensed under CC BY 4.0 by the author.