Get the matching color for the opposite surface with invert(): the same hue at the mirrored stop, _200 to _850 and back. It takes nothing and returns a Color that follows dark mode, so a badge can be dark on a light page and light on a dark one:
let fill = brand.backgroundTertiary // _200 in light mode, _700 in dark
let twin = fill.invert() // _850 in light mode, _350 in dark
HStack {
Text("Booked").padding(8).foregroundStyle(brand.foregroundPrimary).background(fill)
Text("Booked").padding(8).foregroundStyle(brand.foregroundPrimary.invert()).background(twin)
}Pick a color below to see its mirror in both modes:
Color.proBlue._600.toColor().invert()With the defaults, proBlue._600 inverts to exactly proBlue._450.
Not colorInvert()#
SwiftUI's colorInvert() is a view modifier that flips everything a view draws, hue included, so blue turns yellow. invert() changes one color and keeps its hue.
Text on inverted surfaces#
For text on the invertedBackground tokens, use the invertedForeground tokens rather than inverting your text colors. We picked those stops for inverted surfaces, and they aren't all mirrors: invertedForegroundSecondary is _150 in light mode and _800 in dark, where inverting foregroundSecondary gives _250 and _850. Understanding semantic tokens lists every pair.
How it behaves#
A palette color moves to the mirrored stop of its family: _50 and _1000 swap, and so do _500 and _550. Inverting twice gives back the stop you started from. Gray mirrors along gray's own stops.
A color off the palette moves to the mirrored point between stops and keeps its hue and chroma, as much as Display P3 can show. The result keeps the color's opacity.
API#
public extension Color {
func invert() -> Color
}It takes no parameters and returns a new Color at the mirrored stop in each appearance.
Sources#
- Color+Adjustments.swift, which defines
invert(). - ColorAdjustment.swift, which mirrors a color's place on the stops.
See also
- Managing dark mode Get dark mode without extra code: tokens switch stops for you, and your own colors can too.
- .lighten(by:) Add highlights and lighter steps to any color, landing on an exact palette stop.
- Stops: ._50 to ._1000 Twenty fixed colors per theme, lightest to darkest, with the same contrast in every hue.
- How colors land on exact stops Derived colors land on exact stops, so you know their contrast before you run the app.