当前位置: 首页 > Web前端 > CSS

玩转CSS变量_0

时间:2023-03-30 14:01:46 CSS

如果说CSS预处理器变量为初入前端的我打开了新世界的大门,那么CSS变量对我来说无疑是晴天霹雳。它的功能不仅可以优雅地处理以前不好处理或者不适合js的业务需求。它还在富有创造力的前端开发人员手中大放异彩。基本用法在前端领域,标准的实现总是比社区的约定慢很多,前端框架最喜欢的$就是Sass变量使用的。而最常用的@也被Less使用了。为了让CSS变量可以在Sass和Less中使用,官方只好妥协——。red

bluepurple我们可以在业务项目中定义和替换CSS变量,可以参考mvp.css。该库大量使用CSS变量,并允许您根据需要对其进行修改。:root{--border-radius:5px;--box-shadow:2px2px10px;--颜色:#118bee;--颜色强调:#118bee0b;--颜色背景:#fff;--color-bg-secondary:#e9e9e9;--color-secondary:#920de9;--color-secondary-accent:#920de90b;--颜色阴影:#f4f4f4;--颜色文本:#000;--color-text-secondary:#999;--字体系列:-apple-system、BlinkMacSystemFont、“SegoeUI”、Roboto、Oxygen-Sans、Ubuntu、Cantarell、“HelveticaNeue”、无衬线字体;--悬停亮度:1.2;--justify-important:center;--justify-normal:左;--行高:150%;--width-card:285px;--width-card-medium:460px;宽:800px;--width-content:1080px;}我们可以看出,基于CSS变量,可以更加友好的结合设计者的设计意图。修改起来也很方便,在业务项目中合理使用,无疑可以事半功倍。实现默认配置仔细想想,我无法想象CSS预处理器+CSS变量的组合可以实现组件样式的默认配置。这里先介绍一下这个函数的两个前置知识点:其实CSS变量的var()函数也可以用第二个参数来表示变量的默认值。如果该变量之前未定义或具有无效值,则将使用此默认值。/*--primary-color未设置,颜色默认为#7F583F*/color:var(--primary-color,#7F583F);CSS变量虽然目前不是新属性,但毕竟不是所有浏览器都支持的,对于CSS变量,这里还是要考虑优雅降级。/*对于不支持CSS变量的浏览器,可以使用如下的写法。*/a{/*颜色默认值*/color:#7F583F;/*不支持则不识别规则*/color:var(--primary);}结合CSS处理器+CSS变量,实现组件样式默认配置。这里参考优秀的VantWeapp的做法。代码theme.less如下:首先导入所有Less变量@import(reference)'./var.less';//使用正则表达式将Less变量替换为CSS变量.theme(@property,@imp){@{property}:e(replace(@imp,'@(\[^()\]+)','@{$1}','ig'));@{property}:e(replace(@imp,'@(\[^()\]+)','var(--$1,@{$1})','ig'));}的效果函数如下:@import'../common/style/theme.less';.van-button{//...otheromitting.theme(height,'@button-default-height');.theme(line-height,'@button-line-height');.theme(font-size,'@button-default-font-size');}//=>less编译生成.van-button{//...其他省略height:44px;高度:var(--button-default-height,44px);行高:20px;行高:var(--按钮行高,20px);字体大小:16px;font-size:var(--button-default-font-size,16px);}我们可以看到每次调用Less函数都会编译成两个属性。第一个属性的设置可以直接用于不支持CSS变量的设备。如果当前设备支持CSS变量,则使用CSS变量,但由于当前CSS变量未定义,因此将使用变量的默认值。虽然'@button-default-height也是一个变量,但是这个变量只是一个less变量,最终生成的代码中并没有--button-default-height这样的变量。此时我们可以在使用样式的位置或者:root中添加变量--button-default-height。这种方式更适合组件化开发,因为这种方案没有声明任何css变量,只是保留了css变量名和默认属性。这样,无论开发人员的选择器优先级有多低,代码都可以轻松覆盖默认属性。因为我们只是使用css的默认值。有时你可能会想,这样的话,我们不是有更多的代码吗?其实也不一定,其实我们可以直接在页面内部定义变量样式。其他组件通过样式直接使用页面中的变量。当然,其实代码写了多少,重点在于想控制默认样式的粒度。粒度越小,每个组件内部需要写入的变量就越多,粒度越大,我们就不用想太多。SpaceToggle逻辑切换CSS没有逻辑切换似乎是一个共识,但是我们可以使用复选框(单选和多选)和CSS变量来实现判断逻辑。我们先来看看如何使用CSS变量。<样式>.red-box{--toggler:;--red-if-toggler:var(--toggler)红色;背景:var(--red-if-toggler,green);/*会是红色的!*/}.green-box{--toggler:initial;--red-if-toggler:var(--toggler)红色;背景:var(--red-if-toggler,green);/*将是绿色的!*/}
这是因为一个变量生成的--toggler使用空格或者initial得到不同的结果,基于这样的结果,不难想象我们可以通过触发变量的修改来产生不同的结果。这不是错误,也不是黑客攻击。他的原理完全在CSSCustomProperties规范中。此值序列化为空字符串,但实际上将一个空值写入自定义属性,如--foo:;,是一个有效(空)值,而不是保证无效的值。如果出于某种原因,想要手动将变量重置为保证无效的值,使用关键字initial就可以做到这一点。解释如下,其实-foo:;此变量不是无效值,它是空值。initial是CSS变量的无效值。其实这也是可以理解的。css中没有所谓的空字符串,空白不代表无效。只能使用特定值来指示变量无效。这个时候我们再回头看看原来的CSS代码。.red-box{/*当前为空*/--toggler:;/*因为var(--toggler)变空了,所以结果是--red-if-toggler:red*/--red-if-toggler:var(--toggler)red;/**变量为红色,绿色不会被使用*/background:var(--red-if-toggler,green);/*会是红色的!*/。green-box{/**当前无效值*/--toggler:initial;/**仍然是无效数据,因为var只有在参数不是初始值时才会被替换*/--red-if-toggler:var(--toggler)red;/**最终无效值没有用,变绿*/background:var(--red-if-toggler,green);/*将是绿色的!*//*根据目前的功能,我们甚至可以实现and和or的逻辑*--tog1--tog2--tog3同时为空时为红色*/--red-if-togglersalltrue:var(--tog1)var(--tog2)var(--tog3)红色;/**--tog1--tog2--tog3当任何值为空时为红色*/--red-if-anytogglertrue:var(--tog1,var(--tog2,var(--tog3)))red;}新媒体查询当我们需要开发一个响应式网站时,我们必须使用媒体查询@media。让我们开始以传统方式编写这个基本的响应式CSS:.breakpoints-demo>*{width:100%;背景:红色;}@media(最小宽度:37.5em)和(最大宽度:56.249em){.breakpoints-demo>*{宽度:49%;}}@media(min-width:56.25em)and(max-width:74.99em){.breakpoints-demo>*{width:32%;}}@media(min-width:56.25em){.breakpoints-demo>*{背景:绿色;}}@media(min-width:75em){.breakpoints-demo>*{width:24%;}}同样,我们可以使用css变量来优化代码结构,我们可以这样写代码:/**mobile-firststylerules*/.breakpoints-demo>*{/**小于37.5em,宽度100%*/--xs-width:var(--media-xs)100%;/**小于56.249em,宽度49%*/--sm-width:var(--media-sm)49%;--md-宽度:var(--media-md)32%;--lg-width:var(--media-gte-lg)24%;宽度:var(--xs-width,var(--sm-width,var(--md-width,var(--lg-width))));--sm-and-down-bg:var(--media-lte-sm)红色;--md-and-up-bg:var(--media-gte-md)绿色;background:var(--sm-and-down-bg,var(--md-and-up-bg));}可以看出第二个CSS代码非常清晰清晰,数据和逻辑都保存在一个CSS规则中,而不是被@media切割成多个块。这不仅更容易编写,而且开发人员也更容易阅读。详情请参考css-media-vars。代码库只有3kb大小,但是整个代码的写法却是完全不同的风格。原理如下:/***css-media-vars*BSD2-ClauseLicense*Copyright(c)James0x57,PropJockey,2020*/html{--media-print:initial;--媒体屏幕:初始;--media-speech:初始;--media-xs:初始;--media-sm:初始;--media-md:初始;--media-lg:初始;--media-xl:初始;...*/--media-pointer-fine:initial;--media-pointer-none:initial;}/*将当前变量更改为空值*/@mediaprint{html{--media-print:;}}@mediascreen{html{--media-screen:;}}@mediaspeech{html{--media-speech:;}}/*将当前变量更改为空值*/@media(max-width:37.499em){html{--media-xs:;--media-lte-sm:;--media-lte-md:;--media-lte-lg:;}}其他继CSSkeyloggers暴露后CSS安全问题,CSSvariables又一次让我见识到了玩转技术是什么感觉。CSSSpaceToggle技术不仅可以应用于以上功能,甚至可以编写UI库augmented-ui和扫雷游戏。它让我大开眼界。在我有限的开发生涯中,很难找到一种设计意图和用法差异如此之大的类似于css的技术。CSS很有趣,而CSS的有趣之处在于,最终呈现出来的技能强弱与你自己的思维方式和创造力息息相关。以上只是介绍了CSS变量的一些玩法。可能还有更多有趣的玩法,但这需要大家发挥创意。参考saugmented-uicss-media-varscs-sweeper