Skip to content
ColorTokensKitby Penguin Design Ventures
Contents
Function

.shades(count:)

Darker steps of any color, one stop apart, for stacked cards that recede.

Updated View as Markdown

Stack cards so the ones behind recede with .shades(): darker versions of your color, one stop apart, nearest first. You pass how many you want and get them back as colors that work in both modes.

swift
let behind = brand.backgroundSecondary.shades(count: 2)
// _150 and _200 in light mode, _850 and _900 in dark

VStack(spacing: 0) {
    Rectangle()
        .fill(behind[1])
        .frame(height: 6)
        .padding(.horizontal, 24)
    Rectangle()
        .fill(behind[0])
        .frame(height: 6)
        .padding(.horizontal, 12)
    VStack(alignment: .leading, spacing: 4) {
        Text("Lisbon")
            .font(.headline)
            .foregroundStyle(brand.foregroundPrimary)     // _1000 in light mode, _50 in dark
        Text("3 nights from October 12")
            .font(.subheadline)
            .foregroundStyle(brand.foregroundSecondary)   // _800 in light mode, _200 in dark
    }
    .padding()
    .frame(maxWidth: .infinity, alignment: .leading)
    .background(brand.backgroundSecondary)                // _100 in light mode, _800 in dark
}
.padding()
.background(brand.backgroundPrimary)                      // _50 in light mode, _1000 in dark
light mode
Lisbon3 nights from October 12

Pick any color below and change the counts. Near the dark end of the ramp, shades run out: they stop at _1000.

Try it / Lightness sets
Color
light mode

monochromatic

tints

shades

dark mode

monochromatic

tints

shades

swift
let color = Color.proGreen._400.toColor()

color.monochromatic()
color.tints()
color.shades()

Darker in both modes#

On a token, shades are darker in both modes: louder on a white page, quieter on a black one. For steps that are louder in both modes, use strengthen(by:) instead:

swift
let louder = (1...2).map { brand.foregroundTertiary.strengthen(by: $0) }
// _750 and _800 in light mode, _250 and _200 in dark

How it behaves#

shades(count: 3) is darken(by: 1), darken(by: 2) and darken(by: 3). A palette color steps to exact stops of its own hue, so its shades keep its hue and chroma. At _1000 there's nothing darker, so the shades of _950 are _1000 three times.

Any other color moves by the same visual steps, keeping its hue and as much chroma as Display P3 can show. shades is on Color only; for a family's stops, read them directly, such as _700 and _750.

API#

swift
public extension Color {
    func shades(count: Int = 3) -> [Color]
}
ParameterTypeDefaultWhat other values do
countInt3How many darker versions. 0 or less gives an empty array.

It returns count colors, each one stop darker than the last, starting one stop below yours. Your color isn't in the array.

Sources#

See also

  • .tints(count:) Lighter steps of any color, one stop apart, to tell apart the parts of one thing.
  • .monochromatic(count:) Show ordered data, like cheap to pricey days, in evenly spaced steps of one hue.
  • .darken(by:) Make hover and pressed fills from any color, an exact stop darker in both modes.
  • .strengthen(by:) Make any token stand out more: darker in light mode, lighter in dark mode.