曾经获得其中的一个,“我可以使用CSS做到这一点!” 看着某人展示自己JavaScript肌肉的片刻? 这正是我在CSSconf EU 2018上观看Dag-Inge Aas和Ida Aalen演讲时的感受 。

他们设在挪威, WCAG的可访问性不仅是一种良好的做法,而且实际上是法律所要求的(去,挪威!)。 在开发允许用户选择其主要产品的颜色主​​题的功能时,他们面临一个挑战:根据容器的选定背景颜色自动调整字体颜色。 如果背景较暗,则最好使用白色文本以使其符合WCAG对比度 。 但是,如果选择浅背景色会怎样呢? 文本难以辨认并且无法访问。

他们采用了一种优雅的方法,并使用“ color” npm软件包解决了该问题,添加了有条件的边框并自动生成第二色。

但这是一个JavaScript解决方案。 这是我的纯CSS替代方法。

挑战

这是我要完成的标准:

  • 根据背景颜色将字体color更改为黑色或白色
  • 仅当背景真的很浅时 ,才对边框应用相同的逻辑,使用较深的背景基色变化来提高按钮的可见性
  • 自动生成60°色相旋转的辅助颜色

使用HSL颜色和CSS变量

为此,我想到的最简单的方法就是运行HSL颜色。 将背景声明设置为HSL,其中每个参数都是CSS定制属性,这允许使用一种非常简单的方法来确定亮度并将其用作条件语句的基础。

:root {--hue: 220;--sat: 100;--light: 81;
}.btn {background: hsl(var(--hue), calc(var(--sat) * 1%), calc(var(--light) * 1%));
}

这应该允许我们通过更改变量并运行if / else语句更改前景色来将背景交换为运行时所需的任何颜色。

除了……我们在CSS上没有if / else语句…… 还是我们?

引入CSS条件语句

自从引入CSS变量以来,我们还附带了条件语句。 或类似的。

该技巧基于以下事实: 某些CSS参数设置为最小值和最大值 。 例如,认为不透明。 有效范围是0到1,因此我们通常将其保留在那里。 但是我们也可以声明不透明度为2、3或1000,并且将不透明度设置为1,并以此进行解释。 以相似的方式,我们甚至可以声明一个负的不透明度值,并将其上限设置为0。

.something {opacity: -2; /* resolves to 0, transparent */opacity: -1; /* resolves to 0, transparent */opacity: 2; /*resolves to 1, fully opaque */opacity: 100; /* resolves to 1, fully opaque */
}

将技巧应用于我们的字体颜色声明

HSL颜色声明的明度参数的行为类似,将任何负值的上限设置为0(无论色相和饱和度是什么,都会导致黑色),而任何高于100%的值都上限为100%(始终为白色) )。

因此,我们可以将颜色声明为HSL,从亮度参数中减去所需的阈值,然后乘以100%以强制其超出限制之一(小于零或高于100%)。 由于我们需要将负结果转换为白色,将正结果转换为黑色,因此我们还必须将其乘以-1并将其取反。

:root {--light: 80;/* the threshold at which colors are considered "light." Range: integers from 0 to 100,
recommended 50 - 70 */--threshold: 60;
}.btn {/* Any lightness value below the threshold will result in white, any above will result in black */--switch: calc((var(--light) - var(--threshold)) * -100%);color: hsl(0, 0%, var(--switch));
}

让我们回顾一下这段代码:从80的亮度开始,并考虑60的阈值,相减得出20,再乘以-100%,得出-2000%上限为0%。 我们的背景比阈值浅,因此我们认为它较浅并应用黑色文本。

如果我们将--light变量设置为20,则减法将导致-40,乘以-100%将变为4000%,上限为100%。 我们的浅色变量低于阈值,因此我们将其视为“深色”背景,并应用白色文本以保持较高的对比度。

产生条件边界

如果元素的背景太亮,则很容易在白色背景下丢失。 我们可能有一个按钮,甚至没有注意到它。 为了在真正的浅色上提供更好的UI,我们可以基于完全相同的背景色(只是更深)设置边框。

具有基于该背景色的深色边框的浅色背景。

为此,我们可以使用相同的技术,但将其应用于HSLA声明的alpha通道。 这样,我们可以根据需要调整颜色,然后使颜色完全透明或完全不透明。

:root {/* (...) */--light: 85;--border-threshold: 80;
}.btn {/* sets the border-color as a 30% darker shade of the same color*/--border-light: calc(var(--light) * 0.7%);--border-alpha: calc((var(--light) - var(--border-threshold)) * 10);border: .1em solid hsla(var(--hue), calc(var(--sat) * 1%), var(--border-light), var(--border-alpha));
}

假设色相为0且饱和度为100%,则上面的代码将在背景亮度高于80时以原始亮度的70%提供完全不透明的纯红色边框,或者提供完全透明的边框(因此,在全部)如果天黑了。

设置第二种60°色相旋转的颜色

可能是最简单的挑战。 有两种可能的方法:

  1. 过滤器:hue-rotate(60):这是第一个想到的方法,但这不是最佳解决方案,因为它会影响子元素的颜色。 如有必要,可以反向旋转反向。
  2. HSL色相+ 60:另一种选择是获取我们的色相变量并将其添加60。 由于hue参数在360时没有这种限制行为,而是可以环绕(就像任何CSS <angle>类型一样),因此它应该可以正常工作。 认为400deg=40deg480deg=120deg

考虑到这一点,我们可以为第二色元素添加一个修饰符类,该修饰符类将色相值增加60。 由于自修改变量在CSS中不可用(即,没有--hue: calc(var(--hue) + 60)这样的东西),我们可以为我们的基本样式和在背景和边框声明中使用它。

.btn {/* (...) */--h: var(--hue);background: hsl(var(--h), calc(var(--sat) * 1%), calc(var(--light) * 1%));border:.1em solid hsla(var(--h), calc(var(--sat) * 1%), var(--border-light), var(--border-alpha));
}

然后在修饰符中重新声明其值:

.btn--secondary {--h: calc(var(--hue) + 60);
}

这种方法的最好之处在于,由于CSS自定义属性的作用域,它会自动将所有计算结果调整为新的色调并将其应用于属性。

我们到了。 综上所述, 这是我针对所有三个挑战的纯CSS解决方案 。 这应该像一种魅力,并且可以避免我们包含外部JavaScript库。

请参见Pen CSS自动切换字体颜色,具体取决于元素背景…。 FAIL由法昆多考拉蒂尼( @facundocorradini )上CodePen 。

除非不是。 有些色调得到真正的问题(特别是黄色和青色),因为它们显示方式亮度比其他人(如红色和蓝色),尽管具有相同的亮度值。 结果,尽管有些颜色非常亮,但仍将某些颜色视为深色并给出白色文本。

CSS的名字到底是怎么回事?

引入感知的亮度

我敢肯定,你们中的很多人可能已经注意到了这一点,但是对于我们其他人来说,我们发现的亮度与HSL的亮度并不相同 。 幸运的是,我们有一些方法可以权衡色调的亮度并调整我们的代码,使其对色调也能做出响应。

要做到这一点,我们需要通过给三种系数分别对应于人眼感知其亮度的系数来考虑三种原色的感知亮度。 这通常称为亮度

有几种方法可以实现此目的。 在某些情况下,有些比其他更好,但没有哪一种是100%完美的。 因此,我选择了两个最受欢迎的,它们足够好

  • sRGB亮度(ITU Rec。709) : L =(红色* 0.2126 +绿色* 0.7152 +蓝色* 0.0722)/ 255
  • W3C方法(工作草案) : L =(红色* 0.299 +绿色* 0.587 +蓝色* 0.114)/ 255

实施亮度校正的计算

采用亮度校正方法的第一个明显含义是,由于CSS没有本机方法来访问HSL声明的RGB值,因此我们不能使用HSL。

因此,我们需要切换到背景的RBG声明,从我们选择的任何方法中计算亮度,并将其用于我们的前景颜色声明中,该颜色可以(并且将仍然是HSL)。

:root {/* theme color variables to use in RGB declarations */--red: 200;--green: 60;--blue: 255;/* the threshold at which colors are considered "light". Range: decimals from 0 to 1, recommended 0.5 - 0.6 */--threshold: 0.5;/* the threshold at which a darker border will be applied.Range: decimals from 0 to 1, recommended 0.8+ */--border-threshold: 0.8;
}.btn {/* sets the background for the base class */background: rgb(var(--red), var(--green), var(--blue));/* calculates perceived lightness using the sRGB Luma method Luma = (red * 0.2126 + green * 0.7152 + blue * 0.0722) / 255 */--r: calc(var(--red) * 0.2126);--g: calc(var(--green) * 0.7152);--b: calc(var(--blue) * 0.0722);--sum: calc(var(--r) + var(--g) + var(--b));--perceived-lightness: calc(var(--sum) / 255);/* shows either white or black color depending on perceived darkness */color: hsl(0, 0%, calc((var(--perceived-lightness) - var(--threshold)) * -10000000%));
}

对于条件边框,我们需要将声明转换为RGBA,然后再次使用alpha通道使其完全透明或完全不透明。 与以前几乎相同,只是运行RGBA而不是HSLA。 通过从每个通道中减去50获得较暗的阴影。

如果在速记边框声明的RGBA参数中使用变量,iOS上的WebKit上确实存在一个奇怪的错误,它将显示黑色边框而不是适当的颜色。 解决方案是长期宣布边界。
感谢Joel指出错误!

.btn {/* (...) *//* applies a darker border if the lightness is higher than the border threshold */ --border-alpha: calc((var(--perceived-lightness) - var(--border-threshold)) * 100);border-width: .2em;border-style: solid;border-color: rgba(calc(var(--red) - 50), calc(var(--green) - 50), calc(var(--blue) - 50), var(--border-alpha));
}

由于我们丢失了最初的HSL背景声明,因此需要通过色相旋转来获得我们的次要主题颜色:

.btn--secondary {filter: hue-rotate(60deg);
}

这不是世界上最好的事情。 除了将色相旋转应用于如前所述的潜在子元素外,这还意味着切换到黑/白和次要元素上的边框可见性将取决于主要元素的色相,而不是其自身。 但据我所知,JavaScript实现存在相同的问题,因此我将其称为足够接近

到此为止,我们已经拥有了。

见笔取决于元件背景CSS自动WCAG对比度字体颜色由法昆科拉迪尼( @facundocorradini )上CodePen 。

一个纯CSS解决方案,可以达到与原始JavaScript方法相同的效果,但是可以大大减少占用空间。

浏览器支持

IE由于使用CSS变量而被排除在外。 Edge没有我们一直使用的上限行为。 它会看到该声明,将其视作废话,并将其完全丢弃,就像它会破坏或未知的规则一样。 其他所有主要浏览器均应正常工作。

翻译自: https://css-tricks.com/switch-font-color-for-different-backgrounds-with-css/

使用CSS切换不同背景的字体颜色相关推荐

  1. html 改变文本框字体颜色,CSS更改文本框的字体颜色

    我已搜索和搜索,但不能很好地得到这个权利.我在我的网站上有一个文本框,在我的CSS/HTML中,我将它定义为一个类,就像其他任何东西一样,并给它一个背景图像没有问题.我决定我需要改变字体颜色,但不管我 ...

  2. [css] 如何更改placeholder的字体颜色和大小?

    [css] 如何更改placeholder的字体颜色和大小? <style>/* Chrome浏览器 */input::-webkit-input-placeholder {color: ...

  3. Solar-PuTTY修改背景、字体颜色和字体大小

    Solar-PuTTY设置背景.字体颜色和字体大小 第一步.找到设置 第二步 第三部.这里是修改字体大小和字体类型 第四步.修改背景.字体颜色 第五步.保存(最重要)

  4. html字体边缘怎么带颜色,带有html背景和字体颜色问题的MathJax

    当使用html背景和字体颜色时,以下html文件在显示模式下不显示LaTex表达式(分数a/b).另外,在内联模式下,使用背景和字体颜色时,分母会将较低的边缘切割一点(如下图所示).感谢您为我们提供M ...

  5. HTML如何修改span里面的字体颜色,怎么用span css设置div内部分字体颜色?

    本篇文章给大家带来的内容是关于怎么用span css设置div内部分字体颜色,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 用span标签设置div内放一段文字中的部分文字字体颜色方 ...

  6. html代码设置span字体颜色,怎么用span css设置div内部分字体颜色?

    本篇文章给大家带来的内容是关于怎么用span css设置div内部分字体颜色,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 用span标签设置div内放一段文字中的部分文字字体颜色方 ...

  7. css字体颜色span,怎么用span css设置div内部分字体颜色?

    原文:http://www.php.cn/css-tutorial-413189.html 本篇文章给大家带来的内容是关于怎么用span css设置div内部分字体颜色,有一定的参考价值,有需要的朋友 ...

  8. css①字体颜色正常显示,背景透明②字体颜色与背景均为透明的设置方法

    ①字体颜色正常显示,背景颜色透明 color:#fff; background:rgba(0,0,0,0.5);​ ②​字体颜色与背景颜色均为透明 color:#fff; background:#00 ...

  9. Hexo+next的侧边栏背景与字体颜色设置方法

      由于next主题经过了几次更新,查阅了许多资料都说要修改 custom.styl 这个配置文件,但是我的主题内没有此文件,经过翻阅大量的资料,终于找到了侧边栏的配置文件位置.   对于 Muse ...

最新文章

  1. android+4.2+mtp+在此设备上不支持+文件类型,Nexus 4无法通过MTP显示文件
  2. pythonflask configlist.py_Python+Flask.0004.FLASK配置管理之三种方式加载外部配置
  3. link linux 跨设备,Linux中的两种link方式
  4. php debug_print_backtrace,php中debug_backtrace、debug_print_backtrace和匿名函数用法实例
  5. java 切换目录,java-使用SVNKit,如何将目录切换到其他分支?
  6. c++设置一个二维字符组初值_C语言 | 统计一段话中的字符
  7. python备份文件
  8. kali安装QQ音乐
  9. 电信光猫 友华PT921G 研究
  10. 小米手机 Toast显示带应用名称问题解决方法
  11. 向公有云迁移,需要注意哪些问题
  12. nodejs使用node-ffi-napi 访问dll文件
  13. pip20恢复官方源出现bug:confirming the ssl certificate: HTTPSConnectionPool(host=‘pypi.org‘, port=443)
  14. BZOJ 1062: [NOI2008]糖果雨(二维树状数组)
  15. 少儿编程 中国电子学会scratch等级考试一级历年真题解析【已更新至2023年3月 持续更新】
  16. docker命令讲解
  17. hibernate中的dialect解释
  18. 数据分析在电商的5个最佳应用
  19. mysql line separator_java输出换行的标准姿势line.separator
  20. 开放式激光振镜运动控制器(一):ZMC408SCAN接口与功能

热门文章

  1. 【机器学习】线性回归(超详细)
  2. iOS 图表工具charts之LineChartView
  3. 从零开始学 Web 之 HTML5(一)HTML5概述,语义化标签
  4. 什么是量化交易接口?
  5. WIFI模块连接手机
  6. 【推荐】2021腾讯数字生态大会(共183份,演讲PPT【68份】+白皮书+解决方案+其他资料,980M)
  7. 解决主机无法通过网络访问虚拟机的问题
  8. fps射击HTML网页游戏,HTML网页游戏测试
  9. 企业安全攻击面分析工具
  10. SVG互动排版公众号图文『点击播放GIF展开长图』模板代码