Skip to main content
Glama
gradient.md6.23 kB
# Gradient A color gradient. Typst supports linear gradients through the [`gradient.linear` function]($gradient.linear), radial gradients through the [`gradient.radial` function]($gradient.radial), and conic gradients through the [`gradient.conic` function]($gradient.conic). A gradient can be used for the following purposes: - As a fill to paint the interior of a shape: `{rect(fill: gradient.linear(..))}` - As a stroke to paint the outline of a shape: `{rect(stroke: 1pt + gradient.linear(..))}` - As the fill of text: `{set text(fill: gradient.linear(..))}` - As a color map you can [sample]($gradient.sample) from: `{gradient.linear(..).sample(50%)}` # Examples ```example >>> #set square(size: 50pt) #stack( dir: ltr, spacing: 1fr, square(fill: gradient.linear(..color.map.rainbow)), square(fill: gradient.radial(..color.map.rainbow)), square(fill: gradient.conic(..color.map.rainbow)), ) ``` Gradients are also supported on text, but only when setting the [relativeness]($gradient.relative) to either `{auto}` (the default value) or `{"parent"}`. To create word-by-word or glyph-by-glyph gradients, you can wrap the words or characters of your text in [boxes]($box) manually or through a [show rule]($styling/#show-rules). ```example >>> #set page(width: auto, height: auto, margin: 12pt) >>> #set text(size: 12pt) #set text(fill: gradient.linear(red, blue)) #let rainbow(content) = { set text(fill: gradient.linear(..color.map.rainbow)) box(content) } This is a gradient on text, but with a #rainbow[twist]! ``` # Stops A gradient is composed of a series of stops. Each of these stops has a color and an offset. The offset is a [ratio]($ratio) between `{0%}` and `{100%}` or an angle between `{0deg}` and `{360deg}`. The offset is a relative position that determines how far along the gradient the stop is located. The stop's color is the color of the gradient at that position. You can choose to omit the offsets when defining a gradient. In this case, Typst will space all stops evenly. Typst predefines color maps that you can use as stops. See the [`color`]($color/#predefined-color-maps) documentation for more details. # Relativeness The location of the `{0%}` and `{100%}` stops depends on the dimensions of a container. This container can either be the shape that it is being painted on, or the closest surrounding container. This is controlled by the `relative` argument of a gradient constructor. By default, gradients are relative to the shape they are being painted on, unless the gradient is applied on text, in which case they are relative to the closest ancestor container. Typst determines the ancestor container as follows: - For shapes that are placed at the root/top level of the document, the closest ancestor is the page itself. - For other shapes, the ancestor is the innermost [`block`] or [`box`] that contains the shape. This includes the boxes and blocks that are implicitly created by show rules and elements. For example, a [`rotate`] will not affect the parent of a gradient, but a [`grid`] will. # Color spaces and interpolation Gradients can be interpolated in any color space. By default, gradients are interpolated in the [Oklab]($color.oklab) color space, which is a [perceptually uniform](https://programmingdesignsystems.com/color/perceptually-uniform-color-spaces/index.html) color space. This means that the gradient will be perceived as having a smooth progression of colors. This is particularly useful for data visualization. However, you can choose to interpolate the gradient in any supported color space you want, but beware that some color spaces are not suitable for perceptually interpolating between colors. Consult the table below when choosing an interpolation space. | Color space | Perceptually uniform? | | ------------------------------- |-----------------------| | [Oklab]($color.oklab) | *Yes* | | [Oklch]($color.oklch) | *Yes* | | [sRGB]($color.rgb) | *No* | | [linear-RGB]($color.linear-rgb) | *Yes* | | [CMYK]($color.cmyk) | *No* | | [Grayscale]($color.luma) | *Yes* | | [HSL]($color.hsl) | *No* | | [HSV]($color.hsv) | *No* | ```preview >>> #set text(fill: white, font: "IBM Plex Sans", 8pt) >>> #set block(spacing: 0pt) #let spaces = ( ("Oklab", color.oklab), ("Oklch", color.oklch), ("sRGB", color.rgb), ("linear-RGB", color.linear-rgb), ("CMYK", color.cmyk), ("Grayscale", color.luma), ("HSL", color.hsl), ("HSV", color.hsv), ) #for (name, space) in spaces { block( width: 100%, inset: 4pt, fill: gradient.linear( red, blue, space: space, ), strong(upper(name)), ) } ``` # Direction Some gradients are sensitive to direction. For example, a linear gradient has an angle that determines its direction. Typst uses a clockwise angle, with 0° being from left to right, 90° from top to bottom, 180° from right to left, and 270° from bottom to top. ```example >>> #set square(size: 50pt) #stack( dir: ltr, spacing: 1fr, square(fill: gradient.linear(red, blue, angle: 0deg)), square(fill: gradient.linear(red, blue, angle: 90deg)), square(fill: gradient.linear(red, blue, angle: 180deg)), square(fill: gradient.linear(red, blue, angle: 270deg)), ) ``` # Note on file sizes Gradients can be quite large, especially if they have many stops. This is because gradients are stored as a list of colors and offsets, which can take up a lot of space. If you are concerned about file sizes, you should consider the following: - SVG gradients are currently inefficiently encoded. This will be improved in the future. - PDF gradients in the [`color.oklab`]($color.oklab), [`color.hsv`]($color.hsv), [`color.hsl`]($color.hsl), and [`color.oklch`]($color.oklch) color spaces are stored as a list of [`color.rgb`]($color.rgb) colors with extra stops in between. This avoids needing to encode these color spaces in your PDF file, but it does add extra stops to your gradient, which can increase the file size.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/FujishigeTemma/typst-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server