hsl()

Baseline 广泛可用 *

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2015 年 7 月⁩以来,各浏览器均已提供此特性。

* 此特性的某些部分可能存在不同级别的支持。

备注:hsla() 函数式表示法是 hsl() 的别名,它们完全等效。建议使用 hsl()

hsl() 函数式表示法根据颜色的色相饱和度亮度分量,在 sRGB 色彩空间中表示一种颜色。一个可选的 alpha 分量表示颜色的透明度。

试一试

background: hsl(50 80% 40%);
background: hsl(150deg 30% 60%);
background: hsl(0.3turn 60% 45% / 0.7);
background: hsl(0 80% 50% / 25%);
<section id="default-example">
  <div class="transition-all" id="example-element"></div>
</section>
#example-element {
  min-width: 100%;
  min-height: 100%;
  padding: 10%;
}

使用 hsl() 定义互补色可以通过对色相值加上或减去 180 度来实现,因为它们位于色轮的同一条直径上。例如,如果一种颜色的色相角是 10deg,那么它的互补色的色相角就是 190deg

语法

css
/* Absolute values */
hsl(120deg 75% 25%)
hsl(120 75 25) /* deg and % units are optional */
hsl(120deg 75% 25% / 60%)
hsl(none 75% 25%)

/* Relative values */
hsl(from green h s l / 0.5)
hsl(from #123456 h s calc(l + 20))
hsl(from rgb(200 0 0) calc(h + 30) s calc(l + 30))

/* Legacy 'hsla()' alias */
hsla(120deg 75% 25% / 60%)

/* Legacy format */
hsl(120, 75%, 25%)
hsl(120deg, 75%, 25%, 0.8)

备注: hsl()/hsla() 也可以用一种旧式写法,即所有值都用逗号分隔,例如 hsl(120, 75%, 25%)hsla(120deg, 75%, 25%, 0.8)。在以逗号分隔的旧式语法中,不允许使用 none 值,色相值上的 deg 单位是可选的,而饱和度和亮度值则必须使用 % 单位。

下面描述了绝对颜色和相对颜色的允许值。

绝对值语法

hsl(H S L[ / A])

参数如下:

H

一个 <number>、一个 <angle> 或关键字 none(在此情况下等同于 0deg),表示颜色的<hue>(色相)角度。

备注: 在 sRGB(hsl()hwb() 使用)、CIELAB(lch() 使用)和 Oklab(oklch() 使用)色彩空间中,特定色相对应的角度是不同的。更多详情和示例,请参阅 <hue> 参考页面。

S

一个 <percentage> 或关键字 none(在此情况下等同于 0%)。该值表示颜色的饱和度。其中 100% 表示完全饱和,而 0% 表示完全不饱和(灰色)。

L

一个 <percentage> 或关键字 none(在此情况下等同于 0%)。该值表示颜色的亮度。其中 100% 是白色,0% 是黑色,50% 是“正常”亮度。

A 可选

一个 <alpha-value>,表示颜色的 alpha 通道值,其中数字 0 对应 0%(完全透明),1 对应 100%(完全不透明)。此外,关键字 none 可用于明确指定无 alpha 通道。如果未明确指定 A 通道值,则默认为 100%。如果包含该值,则其前面需要有一个斜杠(/)。

备注:有关 none 的效果,请参阅缺失的颜色分量

备注: 绝对 hsl() 颜色会被序列化为 rgb() 值。在序列化过程中,红、绿、蓝分量的值可能会被四舍五入。

相对值语法

hsl(from <color> H S L[ / A])

参数如下:

from <color>

在定义相对颜色时,总是包含关键字 from,其后跟着一个 <color> 值,表示源颜色。这是相对颜色所基于的原始颜色。源颜色可以是任何有效的 <color> 语法,包括另一个相对颜色。

H

一个 <number>、一个 <angle> 或关键字 none(在此情况下等同于 0deg),表示输出颜色的<hue>(色相)角度。

S

一个 <percentage> 或关键字 none(在此情况下等同于 0%)。这表示输出颜色的饱和度。其中 100% 表示完全饱和,而 0% 表示完全不饱和(灰色)。

L

一个 <percentage> 或关键字 none(在此情况下等同于 0%)。这表示输出颜色的亮度。其中 100% 是白色,0% 是黑色,50% 是“正常”亮度。

A 可选

一个 <alpha-value>,表示输出颜色的 alpha 通道值,其中数字 0 对应 0%(完全透明),1 对应 100%(完全不透明)。此外,关键字 none 可用于明确指定无 alpha 通道。如果未明确指定 A 通道值,则默认为源颜色的 alpha 通道值。如果包含该值,则其前面需要有一个斜杠(/)。

备注: 为了能够完全表示可见光谱中的所有颜色,相对 hsl() 颜色函数的输出会被序列化为 color(srgb)。这意味着通过 HTMLElement.style 属性或 CSSStyleDeclaration.getPropertyValue() 方法查询输出颜色值时,将返回一个 color(srgb ...) 格式的值。

定义相对颜色输出通道分量

当在 hsl() 函数内部使用相对颜色语法时,浏览器会将源颜色转换为等效的 HSL 颜色(如果尚未指定为 HSL 格式)。颜色被定义为三个不同的颜色通道值——h(色相)、s(饱和度)和 l(亮度)——外加一个 alpha 通道值(alpha)。这些通道值在函数内部可用,用于定义输出颜色的通道值。

  • h 值被解析为一个介于 0360(含)之间的 <number>,表示源颜色的<hue>(色相)度数值。
  • sl 值分别被解析为一个介于 0100(含)之间的 <number>,其中 100 等同于 100%
  • alpha 值被解析为一个介于 01(含)之间的 <number>

在定义相对颜色时,输出颜色的不同通道可以用几种不同的方式表示。下面,我们将通过一些示例来说明这些方式。

在下面的前两个示例中,我们使用了相对颜色语法。然而,第一个示例输出的颜色与源颜色相同,而第二个示例输出的颜色则完全不基于源颜色。它们实际上并没有创建相对颜色!你不太可能在真实的代码库中使用这些写法,而可能会直接使用绝对颜色值。我们包含这些示例是为了让你开始学习相对 hsl() 语法。

让我们从源颜色 rgb(255 0 0)(等同于 hsl(0 100% 50%))开始。下面的函数输出与源颜色相同的颜色——它使用源颜色的 hsl 通道值(0100%50%)作为输出通道值。

css
hsl(from rgb(255 0 0) h s l)

该函数的输出颜色是 hsl(0 100% 50%) 的 sRGB color() 等效值:color(srgb 1 0 0)

下一个函数对输出颜色的通道值使用绝对值,输出了一个完全不同于源颜色的新颜色:

css
hsl(from rgb(255 0 0) 240 60% 70%)

在上述情况下,输出颜色是 hsl(240 60% 70%) 的 sRGB color() 等效值:color(srgb 0.52 0.52 0.88)

以下函数创建了一个基于源颜色的相对颜色:

css
hsl(from rgb(255 0 0) h 30% 60%)

此示例:

  • 将源颜色(rgb(255 0 0))转换为等效的 hsl() 颜色(hsl(0 100% 50%))。
  • 将输出颜色的 H 通道值设置为源颜色 hsl() 等效值的 H 通道值——0
  • 将输出颜色的 SL 通道值设置为不基于源颜色的新值:分别为 30%60%

最终的输出颜色是在 sRGB 色彩空间中等同于 hsl(0 30% 60%) 的颜色——color(srgb 0.72 0.48 0.48)

备注:如上所述,如果输出颜色使用的颜色模型与源颜色不同,源颜色会在后台被转换为与输出颜色相同的模型,以便能够以兼容的方式表示(即使用相同的通道)。

在本节我们目前看到的示例中,源颜色和输出颜色的 alpha 通道都没有被明确指定。当未指定输出颜色的 alpha 通道时,它默认为与源颜色 alpha 通道相同的值。当未指定源颜色的 alpha 通道时(且它不是相对颜色),它默认为 1。因此,上述示例中的源和输出 alpha 通道值均为 1

让我们看一些指定源和输出 alpha 通道值的示例。第一个示例将输出 alpha 通道值指定为与源 alpha 通道值相同,而第二个示例则指定一个与源 alpha 通道值无关的不同输出 alpha 通道值。

css
hsl(from rgb(255 0 0 / 0.8) h s l / alpha)
/* Computed output color: color(srgb 1 0 0 / 0.8) */

hsl(from rgb(255 0 0 / 0.8) h s l / 0.5)
/* Computed output color: color(srgb 1 0 0 / 0.5) */

在下面的示例中,rgb() 源颜色再次被转换为 hsl() 表示——hsl(0 100% 50% / 0.8)calc() 计算被应用于 HSLA 值,最终的输出颜色是在 sRGB 色彩空间中等同于 hsl(60 80% 30% / 0.7) 的颜色:color(srgb 0.72 0.72 0.08 / 0.7)

css
hsl(from rgb(255 0 0 / 0.8) calc(h + 60) calc(s - 20) calc(l - 10) / calc(alpha - 0.1))

备注:因为源颜色通道值被解析为 <number> 值,所以在使用它们进行计算时,你必须给它们加上数字,即使在通道通常接受 <percentage><angle> 或其他值类型的情况下也是如此。例如,将 <percentage> 添加到 <number> 是行不通的。

正式语法

<hsl()> = 
<legacy-hsl-syntax> |
<modern-hsl-syntax>

<legacy-hsl-syntax> =
hsl( <hue> , <percentage> , <percentage> , <alpha-value>? )

<modern-hsl-syntax> =
hsl( [ from <color> ]? [ <hue> | none ] [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ / [ <alpha-value> | none ] ]? )

<hue> =
<number> |
<angle>

<alpha-value> =
<number> |
<percentage>

示例

将 hsl() 与 conic-gradient() 结合使用

hsl() 函数与 conic-gradient() 配合得很好,因为它们都处理角度。

CSS

css
div {
  width: 100px;
  height: 100px;
  background: conic-gradient(
    hsl(360 100% 50%),
    hsl(315 100% 50%),
    hsl(270 100% 50%),
    hsl(225 100% 50%),
    hsl(180 100% 50%),
    hsl(135 100% 50%),
    hsl(90 100% 50%),
    hsl(45 100% 50%),
    hsl(0 100% 50%)
  );
  clip-path: circle(closest-side);
}

结果

将相对颜色与 hsl() 结合使用

此示例为三个 <div> 元素设置了不同的背景颜色。中间的元素使用了未经修改的 --base-color,而左右两边的元素则使用了该 --base-color 的提亮和变暗版本。

这些变体是使用相对颜色定义的——--base-color 自定义属性被传入一个 hsl() 函数,输出颜色的亮度通道通过一个 calc() 函数被修改以达到预期效果,而色相和饱和度保持不变。提亮后的颜色亮度通道增加了 20%,而变暗后的颜色则减少了 20%。

CSS

css
:root {
  --base-color: orange;
}

#one {
  background-color: hsl(from var(--base-color) h s calc(l + 20));
}

#two {
  background-color: var(--base-color);
}

#three {
  background-color: hsl(from var(--base-color) h s calc(l - 20));
}

/* Use @supports to add in support for old syntax that requires % units to
   be specified in lightness calculations */
@supports (color: hsl(from red h s calc(l - 20%))) {
  #one {
    background-color: hsl(from var(--base-color) h s calc(l + 20%));
  }

  #three {
    background-color: hsl(from var(--base-color) h s calc(l - 20%));
  }
}

结果

输出如下:

旧式语法:逗号分隔值

出于兼容旧式写法的考虑,hsl() 函数接受一种所有值都用逗号分隔的形式。

HTML

html
<div class="space-separated"></div>
<div class="comma-separated"></div>

CSS

css
div {
  width: 100px;
  height: 50px;
  margin: 1rem;
}

div.space-separated {
  background-color: hsl(0 100% 50% / 50%);
}

div.comma-separated {
  background-color: hsl(0, 100%, 50%, 0.5);
}

结果

旧式与现代语法

该示例演示了 hsla() 语法是 hsl() 的别名;现代和旧式(逗号分隔)语法都支持这两种写法。

HTML

html
<div class="modern">HSL</div>
<div class="legacy">HSL</div>
<div class="modernWithAlpha">HSL</div>
<div class="modernHSLA">HSLA</div>
<div class="legacyHSLA">HSLA</div>

CSS

css
div {
  width: 100px;
  min-height: 50px;
  font-family: sans-serif;
  display: flex;
  align-items: center;
  justify-content: center;
}
body {
  display: flex;
  gap: 20px;
}
css
div.modern {
  background-color: hsl(90 80% 50%);
}

div.legacy {
  background-color: hsl(90, 80%, 50%);
}

div.modernWithAlpha {
  background-color: hsl(90 80% 50% / 50%);
}

div.modernHSLA {
  background-color: hsla(90 80% 50% / 50%);
}

div.legacyHSLA {
  background-color: hsla(90, 80%, 50%, 0.5);
}

结果

规范

规范
CSS 颜色模块第五版
# 相对 HSL
CSS 颜色模块第四版
# hsl 表示法

浏览器兼容性

另见