相关文章推荐
眉毛粗的毛衣  ·  client.invoke_shell.re ...·  3 月前    · 
const btn = document.getElementById('modeBtn'); btn.addEventListener('click', (e) => { const body = document.body; if (e.target.innerHTML === '天亮了') { body.style.backgroundColor = 'black'; body.style.color = 'white'; e.target.innerHTML = '天黑了'; } else { body.style.backgroundColor = 'white'; body.style.color = 'black'; e.target.innerHTML = '天亮了';}
  • 版本二核心代码,完整demo代码
  • const btn = document.getElementById('modeBtn');
    btn.addEventListener('click',(e)=>{
    const body = document.body;
    if(body.className !=='night'){
        body.className='night';
    }else{
        body.className='';
    
  • 版本三核心代码,完整demo代码
  • /*当input框为选中状态时时,content内容的样式;在css选择时,":"表示当前input框的值,即checked"+"表示相邻元素,即当前元素的下一元素*/
    #modeCheckBox:checked + .content {
        background-color: black;
        color: white;
        transition: all 1s;
    #modeBtn::after {
        content: '天亮了';
    #modeCheckBox:checked + .content #modeBtn::after { /*点击按钮之后,就选择.night的样式,则图标改变*/
        content: '天黑了';
    /*隐藏掉原来的checkbox*/
    #modeCheckBox {
        display: none;
    

    在以上三个一键切换主题色的深夜食堂例子中,月影老师给我们总结了一个编程思路:

  • HTML/CSS/JS各司其职
  • 应当避免不必要的由JS直接操作样式
  • 可以用class来表示状态
  • 纯展示类交互寻求零JS方案
  • 回顾完毕,虽然月影老师建议纯展示类交互寻求零JS方案(这偏向于实战和工作当中),在学习阶段我们应该寻求多种实现方案。那么CSS变量将带来《深夜食堂:版本四》。

    什么是CSS变量?

    CSS变量,即CSS variable。官方的名称是级联变量的CSS自定义属性,即CSS custom properties for cascading variables 。适当的使用CSS变量可以使得代码更易于阅读、管理和维护,因为看起来随意的、固定的值有了一个变量名作为提示信息。

    css变量和预处理器中的变量有什么不同?

    css变量是运行在浏览器中的动态css属性,而预处理器变量会被编译成普通的css代码。

  • 浏览器原生特性,无需经过任何转译就可直接运行
  • dom对象成员,极大便利了css与js之间的联系
  • css变量不同于预处理器变量,css变量只能用于属性值,不能用于属性名
  • 如何使用css变量

    声明一个css变量,变量名要以两根连词线(--)开始,变量值则可以是任何有效的CSS值,CSS变量写在规则集{}之内,如下:

    body{
        --them_color: black; /**声明一个变量名为--main-bg-color,变量值为black的CSS变量*/
    

    同时CSS变量是大小写敏感的,--Them_color和--them_color 是两个不同的css变量。

  • 属性名可以包含数字,字母,以及下划线或者短横线,也可以是中文,日文或者韩文
  • 读取CSS变量

    var()函数用于读取变量

    var(第一个参数,第二个参数),第一个参数是CSS变量,第二个参数是可选的,表示默认值

    body{
        --them_color: black; /**声明一个变量名为--main-bg-color,变量值为black的CSS变量*/
        background-color:var(--them_color);/**读取变量--main-bd-color的值 */
    

     var()函数还可以使用第二个参数,表示变量的默认值。如果该变量未声明、未赋值,就使用这个默认值

    body{
        --them_colorr: black; /**声明一个变量名为--them_color,变量值为black的CSS变量*/
        background-color:var(--them_color,#FFFFFF);
        /**读取变量--them_color的值 ,
        如果变量--them_color只声明了变量名、未设置变量值,或者忘记声明该变量时,浏览器就会使用var()的第二个参数作为背景色*/
    

     CSS变量备用值,通过把var()函数作为var()函数的第二个参数,可以设置多个备用值,例如:

    .two {
      color: var(--my-var, red); /* 如果--my-var 未定义,则color为红色 */
    .three {
      background-color: var(--my-var, var(--my-background, pink)); /* 如果--my-var,--my-background未定义,则background-color为pink */
    .three {
      background-color: var(--my-var, --my-background, pink); /* 这种写法是无效的,var()函数只能存在两个参数 */
    

    CSS变量在拼接计算中引用

    如果变量都是字符串,可以直接拼接

    :root{
        --text-one:'hello';
        --text-two:'world'
    .box:after{
        content: var(--text-one)' 'var(--text-two);
    

    变量和单位不能直接拼接

    :root{
        --size-one:14;
    .box{
        font-size:var(--size-one)px; /**无效**/
    

    计算结果将是

    font-size: 14 px;
    

    由上可知,变量和单位直接拼接会多出一个空格,正确的拼接方式是借用calc()函数,进行计算

    {font-size:calc(var(--size-one)*1px);}
    

    当然,calc也可以用作CSS变量值当中

    {--size-two:calc(20px * 2);}
    

    也可以在CSS变量中使用另一个CSS变量

    body{
    --top-color: orange;
    --bottom-color: yellow;
    --my-gradient: linear-gradient(var(--top-color), var(--bottom-color));
    

    CSS变量有效性

     在没有CSS变量以前,CSS有效性和属性是绑定的,但这对CSS变量来说并不适用,因为当CSS变量被解析,浏览器不知道它们什么时候会被使用,所以会默认这些值都是有效的。而且通过var()函数调用时,也要根据上下文环境确定是否有效。

    当CSS属性-值对中存在语法错误,该行则会被忽略。然而如果自定义属性的值无效,它并不会被忽略,从而会导致该值被覆盖为默认值。

    点我查看css变量有效性示例

  • 优先级别:内联样式 > ID选择器 > 类选择器 = 属性选择器 = 伪类选择器 > 标签选择器 = 伪元素选择器
  • 常见默认值:

  • background 默认值是 transparent
  • width 默认值是 auto
  • position 默认值是 static
  • opacity 默认值是 1
  • display 默认值是 inline
  • CSS变量兼容性

    虽然现在主流浏览器都已支持css变量,但顽强的 ie11仍未支持,所以为了代码的健壮性,需要检测一下当前浏览器对css变量是否支持。

    1、@supports命令

    @supports ( (--a: 0)) {
      /** 支持css变量字体为蓝色**/
      section{
        --my-color:blue;
        color:var(--my-color);
    @supports ( not (--a: 0)) {
      /* 不支持css变量字体为灰色 */
      section{
        color:gray;
    

    2、使用具有虚拟查询条件(dummy conditional query)的@supports代码块

    section {
      color: gray;
    @supports(--css: variables) {
      section {
        --my-color: blue;
        color: var(--my-color, 'blue');
    

    3、JS检测是否支持

    const isSupported = window.CSS && window.CSS.supports && window.CSS.supports('--masterColor', 'red');
    if (isSupported) {
    	/* supported */
    	console.log('当前浏览器支持CSS变量')
    } else {
    	/* not supported */
    	console.log('当前浏览器不支持CSS变量')
    

     JS更新CSS变量

    获取css变量

    getPropertyValue()获取CSS变量

    document.documentElement.style.getPropertyValue('--testColor')
    

    注意:上面语句只能获取到内联样式的css变量值,要想获取任意位置的CSS变量可以使用下面方法

    getComputedStyle(document.documentElement).getPropertyValue('--testcolor')
    

    获取某一标签上的css变量

    var divEle=document.querySelector('div');
    var divSty=window.getComputedStyle(divEle);
    var diveleVal=divSty.getPropertyValue('testcolor');
    

    上面代码展示了获取定义在div标签中testcolor变量的值。 

    setProperty()修改css变量

    document.documentElement.style.setProperty('--testcolor', color);
    

    上面代码展示了修改属性名为 testcolor的值。需要注意的是当定义了多个同名css变量,在对变量值修改时需要指明具体修改变量,代码如下

    body{
    --testcolor:red;
    div{
    --testcolor:black;
    document.querySelector('div').style.setProperty('--testcolor', yellow);
    

     上述代码把div里的testcolor值修改成了黄色,因为body,div有同名css变量testcolor,所以在修改的指明了只修改div里的。

    CSS变量之深夜食堂

    下面将展示如何通过css变量实现深色、浅色模式一键切换

    核心代码,完整demo代码

    body{
    --them_color:black;
    --them_bgcolor:white;
    background-color: var(--them_bgcolor);
    color: var(--them_color);
    const btn = document.getElementById('modeBtn');
    btn.addEventListener('click', (e) => {
        const them_bgcolor = window.getComputedStyle(document.body).getPropertyValue('--them_bgcolor')
        if (them_bgcolor === 'white') {
            document.body.style.setProperty('--them_bgcolor', 'black');
            document.body.style.setProperty('--them_color', 'white');
            e.target.innerHTML = '天黑了';
    } else {
        document.body.style.setProperty('--them_bgcolor', 'white');
        document.body.style.setProperty('--them_color', 'black');
        e.target.innerHTML = '天亮了';}
    

    document.querySelector(':root') === document.documentElement

    优先级: js设置值>内联样式>:root选择器>html选择器

    document.documentElement.style.getPropertyValue只能获取内联样式的值,而且document.documentElement.style.setProperty('css变量名', '变量值');方式设置CSS变量会添加到内联样式中去

    如果CSS变量不是内联样式定义,document.documentElement.style.getPropertyValue就获取不到

    getComputedStyle(document.documentElement).getPropertyValue获取到的始终是实际的值

    跪求大佬解答:js修改css变量后是否都默认把属性添加到内联样式中?

    在我这个demo实例里 为啥第一次点击按钮不会切换主题色,直到第二次点击按钮才会变换主题色。

    上面截图是我第一次点击按钮之前的,此时html 中的body并无内联样式,而是body标签样式。

    上面截图是我第一次点击按钮之后的。在我点击一次按钮后,body标签的样式不可用,而html中的body多了内联样式。

    分类:
    阅读
    标签: