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:
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)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:
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:
Text("Lisbon")
.padding(12)
.border(brand.outlineTertiary.strengthen(by: 2)) // _200 in light mode, _800 in darkA 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#
public extension Color {
func strengthen(by stops: Int = 1) -> Color
}| Parameter | Type | Default | What other values do |
|---|---|---|---|
stops | Int | 1 | A 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#
- Color+Adjustments.swift, which defines
strengthen(by:)assoften(by: -stops). - ColorAdjustment.swift, which moves a color along the stops.
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.