# .toLAB()

Change a color's lightness alone in CIELab, the lightness that decides contrast.

Change a color's lightness and nothing else with `toLAB()`: CIELab L\* from 0 to 100, plus `a` (green to red) and `b` (blue to yellow). It takes nothing and returns a `LABColor`:

```swift
Color(hex: "#00B386").toLAB()   // LABColor(l: 64.93, a: -49.37, b: 12.31)
```

## Changing lightness alone

`adjustLightness(by:)` adds to L\* and keeps `a` and `b`, so the color gets lighter or darker without turning another hue:

```swift
let lab = Color(hex: "#00B386").toLAB()
let lighter = lab.adjustLightness(by: 10)   // LABColor(l: 74.93, a: -49.37, b: 12.31)
let fill = lighter.toLCH().toColor()        // #3CCFA0
```

- lab: #00b386
- lighter: #3ccfa0

For a palette color, [`lighten(by:)`](https://colortokenskit.com/api/lighten/index.md) is usually the better choice: it moves whole stops, so the result is a palette color too.

## Replacing a value

`with(l:a:b:alpha:)` returns a copy with the values you pass and keeps the rest, as in `lab.with(alpha: 0.5)`.

## How it behaves

`adjustLightness(by:)` keeps L\* within 0 to 100. Conversions use the D65 white point and pass through extended sRGB without clipping. Inside sRGB, `a` runs from about −86 to 98 and `b` from about −108 to 94; Display P3 colors reach further. A token gives its light-mode value on iOS 17, macOS 14 and later.

`LABColor` has no `toColor()`, so go through another type, as in `lab.toLCH().toColor()`. From a `LABColor` you can go to `toRGB()`, `toXYZ()` and `toLCH()`.

## API

```swift
public extension Color {
    func toLAB() -> LABColor
}

public struct LABColor: Hashable, Sendable {
    public let l: CGFloat       // 0 to 100, CIELab L*
    public let a: CGFloat       // green (negative) to red (positive)
    public let b: CGFloat       // blue (negative) to yellow (positive)
    public let alpha: CGFloat   // 0 to 1

    public init(l: CGFloat, a: CGFloat, b: CGFloat, alpha: CGFloat)

    public func with(
        l: CGFloat? = nil, a: CGFloat? = nil, b: CGFloat? = nil, alpha: CGFloat? = nil
    ) -> LABColor
    public func adjustLightness(by amount: CGFloat) -> LABColor
    public func lerp(_ other: LABColor, t: CGFloat) -> LABColor

    public func toRGB() -> RGBColor
    public func toXYZ() -> XYZColor
    public func toLCH() -> LCHColor
}
```

| Parameter | Type      | What it does                                                          |
| --------- | --------- | --------------------------------------------------------------------- |
| `amount`  | `CGFloat` | L\* to add. Negative values darken. The result stays within 0 to 100. |

## Sources

- [Color+ColorSpaces.swift](https://github.com/metasidd/ColorTokensKit-Swift/blob/main/Sources/ColorTokensKit/Platform/SwiftUI/Color+ColorSpaces.swift), which defines `toLAB()` on `Color`.
- The [LAB](https://github.com/metasidd/ColorTokensKit-Swift/tree/main/Sources/ColorTokensKit/ColorSpace/LAB) folder, which defines `LABColor`, `with(l:a:b:alpha:)` and `adjustLightness(by:)`.

## See also

- [.toLCH()](https://colortokenskit.com/api/to-lch/index.md): Read a color as CIELab lightness, chroma and hue, to match LCH numbers or check contrast.
- [.lighten(by:)](https://colortokenskit.com/api/lighten/index.md): Add highlights and lighter steps to any color, landing on an exact palette stop.
- [.toXYZ()](https://colortokenskit.com/api/to-xyz/index.md): Get a color's CIE XYZ values, where y is the relative luminance contrast is built on.
- [How accessible is it?](https://colortokenskit.com/basics/how-accessible/index.md): What the palette guarantees for contrast in every hue and mode, and what you still need to check.

---

From ColorTokensKit, by Penguin Design Ventures: https://colortokenskit.com/api/to-lab/ (updated September 26, 2026).
