Skip to content
ColorTokensKitby Penguin Design Ventures
Contents
Function

ProGradient recipes

Make a gradient from one color with a preset like .tonal or .fade, or write your own in a line.

Updated View as Markdown

Get a finished gradient from a single color: pass a recipe, such as .tonal for depth or .fade for a glow, to proGradient(_:). A recipe turns one color into the gradient's colors, and with no recipe you get .subtle, which runs from one stop lighter at the top to the color itself:

swift
Text("Book now")
    .padding()
    .foregroundStyle(.black)
    .background(brand._400.proGradient())   // .subtle: _350 at the top to _400
light mode
Book now

Pick a color or a token below to draw every recipe from it, in both modes. The checkerboard shows where a recipe turns transparent:

Try it / Recipes
Color
light mode
.subtleA touch lighter at the start
.fadeThe color fading to transparent
.tonalTwo stops lighter to two stops darker
.analogousA drift through the neighboring hues
.washA soft, translucent tint
.sheenA band of color, clear at both ends
.edgeHighlightStrongest in the middle
dark mode
.subtleA touch lighter at the start
.fadeThe color fading to transparent
.tonalTwo stops lighter to two stops darker
.analogousA drift through the neighboring hues
.washA soft, translucent tint
.sheenA band of color, clear at both ends
.edgeHighlightStrongest in the middle

Color.proBlue._400.toColor().proGradient(.fade)

The seven presets#

RecipeColors it makes from colorGood for
.subtle (default)color.lighten(), colorButtons and icons
.fadecolor, color.opacity(0)Glows and scrims
.tonalcolor.lighten(by: 2), color, color.darken(by: 2)Cards and headers
.analogouscolor.analogous(), the hues 30° either sideBanners
.washcolor.opacity(0.1), color.opacity(0.3)Card backdrops
.sheencolor.opacity(0), color.opacity(0.5), color.opacity(0)A shine, made from white
.edgeHighlightcolor.opacity(0.15), color, color.opacity(0.15)Borders and rims

Every recipe works with all three shapes: proGradient, proRadialGradient and proAngularGradient.

Adding a sheen to a button#

.sheen puts a band of color across the middle, clear at both ends. Made from white and laid over a .tonal fill, it reads as a shine:

swift
Button("Book now") {}
    .buttonStyle(.plain)
    .padding()
    .foregroundStyle(.black)
    .background(Color.white.proGradient(.sheen, from: .leading, to: .trailing))
    .background(brand._400.proGradient(.tonal))   // _300 through _400 to _500
light mode
Book now

Writing your own recipe#

A recipe is a function from one Color to the gradient's colors, in order. Add it as a static property, and it reads like the presets:

swift
extension ProGradient.Recipe {
    static var deepen: Self { Self { [$0, $0.darken(by: 4)] } }
}

Rectangle()
    .fill(brand._400.proGradient(.deepen))   // _400 to _600
    .frame(height: 64)
light mode

Reading a recipe's colors#

colors(from:) gives a recipe's colors without drawing a gradient, for a chart series, a row of badges or your own gradient type:

swift
let steps = ProGradient.Recipe.tonal.colors(from: accent)   // [accent.lighten(by: 2), accent, accent.darken(by: 2)]

How it behaves#

Recipes built on lighten() and darken() land palette colors on exact stops, so .tonal on _400 gives _300, _400 and _500. A color off the palette moves the same number of steps along the lightness ladder, keeping its hue and chroma.

On a family, a recipe starts from the family's own color: _450 for a built-in family, and your hex for a family made with ProTheme(hex:). To start from a stop, call it on the stop, as in brand._400.proGradient(.tonal).

The recipes that fade, .fade, .wash, .sheen and .edgeHighlight, change only opacity, so the color keeps its hue all the way to transparent. On a token they fade the token's color in each mode.

API#

swift
public enum ProGradient {
    public struct Recipe {
        public init(_ makeColors: @escaping (Color) -> [Color])
        public func colors(from color: Color) -> [Color]
    }
}

public extension ProGradient.Recipe {
    static var subtle: Self { get }
    static var fade: Self { get }
    static var tonal: Self { get }
    static var analogous: Self { get }
    static var wash: Self { get }
    static var sheen: Self { get }
    static var edgeHighlight: Self { get }
}
ParameterTypeDefaultWhat other values do
makeColors (init)(Color) -> [Color]noneReturns the gradient's colors for a color, in order.
color (colors(from:))ColornoneAny color, including tokens and system colors.

colors(from:) returns the recipe's colors in gradient order. Pass a recipe as the first argument of proGradient, proRadialGradient or proAngularGradient on a Color or ProTheme.

Sources#

See also