Skip to content
ColorTokensKitby Penguin Design Ventures
Contents
Function

.strengthen(by:)

Make any token stand out more: darker in light mode, lighter in dark mode.

Updated View as Markdown

Make a token stand out more with strengthen(by:). It moves the color away from the page by whole stops, darker in light mode and lighter in dark mode, and returns a Color:

swift
VStack(spacing: 0) {
    Text("Lisbon")
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(12)
        .background(brand.backgroundSecondary)                // hovered: _100 and _800
    Text("Kyoto")
        .frame(maxWidth: .infinity, alignment: .leading)
        .padding(12)
        .background(brand.backgroundSecondary.strengthen())   // selected: _150 and _750
}
.foregroundStyle(brand.foregroundPrimary)
light mode
LisbonKyoto

The selected row sits one stop further from the page than the hovered one, in both modes. Pick a color and a number of stops below:

Try it / strengthen()
Color
light mode
Before
#4176b8proBlue._600
After
#3a69a5proBlue._650
dark mode
Before
#4176b8proBlue._600
After
#4882caproBlue._550
swift
Color.proBlue._600.toColor().strengthen()

With the defaults, proBlue._600 strengthens to proBlue._650 in light mode and proBlue._550 in dark.

Stronger outlines#

Two stops away from the page, outlineTertiary lands on the stops of outlineSecondary, so a decorative hairline can step up to a stronger line, say around the section in view:

swift
Text("Lisbon")
    .padding(12)
    .border(brand.outlineTertiary.strengthen(by: 2))   // _200 in light mode, _800 in dark
light mode
Lisbon

A control's own edge, like a text field's, takes outlinePrimary, which already reaches 3:1 on every background.

Fills under text#

A strengthened fill moves toward the text on it. In dark mode it gets lighter, closer to a light label, so for a pressed fill use darken(by:), which keeps the label's contrast in both modes.

How it behaves#

The direction comes from the appearance, not from what's behind the color, so on an inverted surface strengthening goes the wrong way. On watchOS, which always draws dark, it always goes lighter.

A palette color lands on an exact stop of its family, and stops at _50 or _1000. A color off the palette moves by the same step in lightness and keeps its hue. The result keeps the color's opacity.

API#

swift
public extension Color {
    func strengthen(by stops: Int = 1) -> Color
}
ParameterTypeDefaultWhat other values do
stopsInt1A negative value moves toward the page, so strengthen(by: -1) is soften().

It returns a new Color that resolves in each appearance: darker in light mode and lighter in dark mode.

Sources#

See also

  • .soften(by:) Make quieter text and fills from any token: lighter in light mode, darker in dark mode.
  • Building for interaction states Give buttons and rows hover, pressed, selected and disabled colors that stay readable in both modes.
  • Understanding semantic tokens Learn the 20 tokens by the job each one does, and get dark mode and passing contrast with them.
  • .lighten(by:) Add highlights and lighter steps to any color, landing on an exact palette stop.