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

CSS变量由浅入深,提高效率必备知识!

时间:2023-03-30 17:10:06 CSS

作者:AhmadShadeed译者:前端小智来源:ishadeed有梦想,有干货,微信搜索【大千世界】关注这位凌晨还在洗碗的洗碗智慧。本文已收录到GitHubhttps://github.com/qq449245884/xiaozhi,里面有完整的测试站点、资料和我的一线厂商访谈系列文章。近四年来,Web浏览器一直支持CSS变量(又名自定义属性)。我一般也是根据项目情况来使用的。它们非常有用且易于使用,但它们经常被前端开发人员误用或误解。简介CSS变量是在CSS文档中定义的值,目的是为了可重用性和减少CSS值中的冗余。下面是一个基本的例子。.section{border:2pxsolid#235ad1;}.section-title{color:#235ad1;}.section-title::before{content:"";显示:内联块;宽度:20px;高度:20px;background-color:#235ad1;}在此代码段中,#235ad1使用了3次。想象一下,对于一个大型项目,不同的CSS文件,如果有一天他们被要求更改颜色。我们能做到的最好和最快的方法是“查找和替换”。使用CSS变量,可以更快地解决这个问题。要定义变量名,您需要以--开头。首先,我们现在将在:root或元素中定义变量。:root{--color-primary:#235ad1;}.section{border:2pxsolidvar(--color-primary);}.section-title{color:var(--color-primary);}.section-title::before{/*其他样式*/background-color:var(--color-primary);}是不是比上一个干净多了?--color-primary变量是全局变量,因为我们在:root元素中定义了它。但是,我们也可以将变量范围限定为整个文档中的某些元素。命名变量类似于编程语言命名变量,CSS变量的有效名称应包含字母数字字符、下划线和破折号。另外,值得一提的是CSS变量是区分大小写的。/*法定名称*/:root{--primary-color:#222;--_原色:#222;--12-原色:#222;--primary-color-12:#222;}/*非法命名*/:root{--primarycolor:#222;/*Spacingsarenotallowed*/--primary$%#%$#}ScopeCSS变量也有自己的作用域,这个概念和其他编程语言类似。以JS为例::root{--primary-color:#235ad1;}.section-title{--primary-color:d12374;color:var(--primary-color);}可变元素是全局的,因此可以在cool()函数内部访问。但是,只能在cool()函数中访问变量otherElement。:root{--primary-color:#235ad1;}.section-title{--primary-color:d12374;color:var(--primary-color);}变量--primary-color是一个全局变量,可以从文档中的任何地方访问。变量--primary-color只能在.section-title中访问,因为它是在.section-title中定义的。下面是一个更直观的示例图,可以加强我们的理解:变量--primary-color用于标题颜色。我们想自定义作者姓名和最新文章标题的颜色,所以我们需要重写--primary-color。这同样适用于--unit变量。/*全局变量*/:root{--primary-color:#235ad1;--unit:1rem;}/*section-title默认颜色和间距*/.section-title{color:var(--primary-color);margin-bottom:var(--unit);}/*覆盖章节标题样式*/.featured-authors.section-title{--primary-color:#d16823;}.latest-articles.section-title{--原色:#d12374;--unit:2rem;}Fallbackscheme这里的fallback并不是不支持CSS变量的fallback,而是CSS变量可以支持的fallbackscheme。考虑以下示例:.section-title{color:var(--primary-color,#222);}注意var()有多个值。第二个#221仅在变量--primary-color由于某种原因未定义时才有效。不仅如此,我们还可以将var()嵌套在另一个var()中。.section-title{color:var(--primary-color,var(--black,#222));}此功能在变量值取决于操作的情况下很有用。当变量没有值时,为变量提供回退很重要。用例一:控制组件的大小在设计系统中,按钮通常有多种尺寸。通常,按钮可以具有三种尺寸(小、正常、大)。使用CSS变量并不容易:.button{--unit:1rem;padding:var(--unit);}.button--small{--unit:0.5rem;}.button--large{--unit:1.5rem;}通过更改按钮组件范围内的变量--unit,我们创建按钮的不同变体。用例二:CSS变量和HSL颜色HSL代表色调、饱和度、亮度。Hue的值决定颜色,Saturation和Lightness的值可以控制颜色的深浅。:root{--primary-h:221;--primary-s:71%;--primary-b:48%;}.button{background-color:hsl(var(--primary-h),var(--primary-s),var(--primary-b));transition:background-color0.3sease-out;}/*使背景更暗*/.button:hover{--primary-b:33%;}这里Ho通过减小变量--primary-b使按钮变暗。用例三:比例调整如果您使用过Photoshop、Sketch、Figma或Adob??eXD等设计程序,那么我们需要在调整元素大小时按住Shift键以避免扭曲它。在CSS中,没有直接的方法可以做到这一点,但我们有一个简单的解决方法,即使用CSS变量。假设有一个图标,它的宽度和高度应该相等。我为宽度和高度定义了变量--size。.icon{--size:22px;宽度:var(--size);height:var(--size);}现在您可以通过简单地更改--size变量的值来模拟Shift调整大小的效果。用例四:CSS网格CSS变量对于网格非常有用。假设您希望网格容器根据定义的首选宽度显示其子项。使用变量比为每个变体创建类并复制CSS更容易做到这一点。.wrapper{--item-width:300px;显示:网格;网格模板列:重复(自动填充,minmax(var(--item-width),1fr));网格间隙:1rem;}。wrapper-2{--item-width:500px;这样,我们就可以创建一个完整的、灵活的、易于维护的、可以在其他项目中使用的网格系统。相同的概念可以应用于grid-gap属性。包装器{--item-width:300px;--差距:0;显示:网格;grid-template-columns:repeat(auto-fill,minmax(var(--item-width),1fr));}.wrapper.gap-1{--gap:16px;}用例五:全值声明,CSS渐变是用全值表示的,比如像渐变这样的东西。如果渐变或背景在整个系统中使用,将它们存储到CSS变量中可能是一件好事。:root{--primary-gradient:linear-gradient(150deg,#235ad1,#23d1a8);}.element{background-image:var(--primary-gradient);}或者我们可以存储一个值。以角度为例:.element{--angle:150deg;background-image:linear-gradient(var(--angle),#235ad1,#23d1a8);}.element.inverted{--angle:-150deg;}用例六:背景位置我们可以在其中包含多个值一个CSS变量,当我们需要根据特定上下文将元素放置在不同位置时,它很有用。.table{--size:50px;--pos:左中;背景:#ccc线性梯度(#000,#000)不重复;背景大小:var(--size)var(--size);background-position:var(--pos);}用例七:在浅色和深色模式之间切换现在,网站比以往任何时候都更需要深色和浅色模式。使用CSS变量,我们可以存储它们的两个版本,并根据用户或系统偏好在它们之间切换。:根{--文本颜色:#434343;--边框颜色:#d2d2d2;--main-bg-color:#fff;--action-bg-color:#f9f7f7;}/*添加到``元素的类*/.dark-mode{--text-color:#e9e9e9;--边框颜色:#434343;--main-bg-颜色:#434343;--action-bg-color:#363636;}用例八:设置默认值在某些情况下,您需要使用JavaScript设置CSS变量。假设我们需要获取可扩展组件的高度。变量--details-height-open为空,它将被添加到特定的HTML元素中。当JavaScript由于某种原因失败时,提供适当的默认值或回退值很重要。.section.is-active{max-height:var(--details-height-open,auto);}auto值是JS失败时的回退值,没有定义CSS变量--details-height-open。用例九:控制包装器的宽度网站包装器有多种变体。有时需要一页小包,另一页大包。在这种情况下,合并CSS变量可能会有用。.wrapper{--size:1140px;max-width:var(--size);}.wrapper--small{--size:800px;}用例十一:动态网格项我们可以添加--item-width变量,仅此而已。例如,这种方法可以帮助制作网格原型。HTML

CSS。包装器{显示:网格;网格模板列:重复(自动填充,minmax(var(--item-width),1fr));grid-gap:1rem;}示例:https://codepen.io/shadeed/pe...用例十二:用户头像另一个有用的用例是调整元素大小。假设我们需要四种不同大小的用户头像,并且只能使用一个变量来控制它们的大小。.c-avatar{display:inline-block;width:calc(var(--size,1)*30px);height:calc(var(--size,1)*30px);}用例十三:媒体查询结合CSS变量和媒体查询对于调整整个站点使用的变量非常有用。我能想到的最简单的例子是改变间距值。:root{--gutter:8px;}@media(min-width:800px){:root{--gutter:16px;}}任何使用--gutter变量的元素都会根据viewportsize,这不是很好吗?用例十四:继承是的,CSS变量确实继承。如果在父元素中定义了CSS变量,则子元素将继承相同的CSS变量。让我们看下面的例子:HTML

css.parent{--size:20px;}.child{font-size:变量(--大小);}。子元素可以访问变量--size,因为它是从父元素继承的。有意思,那么在实际项目中有什么用呢?我们有一组具有以下要求的操作项更改一个变量以更改所有项的大小间距应该是动态的HTML
CSS。行动{--size:50px;显示:弹性;间隙:计算(var(--size)/5);}.actions--m{--size:70px;}.actions__item{width:var(--size);height:var(--size);}注意这里变量--size是如何用于flexbox的gap属性的。这意味着间距可以是动态的并且取决于--size变量。另一个有用的例子是使用CSS变量继承来自定义CSS动画:@keyframesbreath{from{transform:scale(var(--scaleStart));}到{变换:比例(var(--scaleEnd));}}.walk{--scaleStart:0.3;--scaleEnd:1.7;动画:呼吸2s交替;}.run{--scaleStart:0.8;--scaleEnd:1.2;animation:breath0.5salternate;}需要定义两次@keyframes,它将继承.walk和.run元素的自定义CSS变量。CSS变量如何工作当CSS变量在var()函数中无效时,浏览器将根据使用的属性将其替换为初始值或继承值。:root{--main-color:16px;}.section-title{color:var(--main-color);}我使用16px作为颜色属性的值。这是完全错误的。由于颜色属性是继承的,浏览器会做以下事情:这个属性是否可以继承?如果是,父节点是否拥有该属性?是,继承值否:设置为初始值否:设置为初始值下面的流程图解释了浏览器的工作。URL值我们可能无法控制网页中的所有资源,其中一些资源必须在线托管。在这种情况下,您可以将链接的URL值存储在CSS变量中。:root{--main-bg:url("https://example.com/cool-image.jpg");}.section{background:var(--main-bg);}但是,想知道CSS可以使用url()插入变量。考虑以下内容:root{--main-bg:"https://example.com/cool-image.jpg";}.section{background:url(var(--main-bg));}Sincevar(--main-bg)被认为是url本身,因此没有效果。当浏览器计算出这个值时,它就不再有效并且不会按预期运行。存储多个值CSS变量也可以表示多个值,看下面的例子::root{--main-color:35,90,209;}.section-title{color:rgba(var(--main-color),0.75);}在示例中我们有一个rgba()函数,RGB值存储在以逗号分隔的CSS变量中。如果我们想根据元素调整alpha值,这样做可以提供灵活性。唯一的缺点是您不能使用DevTools颜色选择器来调整rgba值。另一个例子是将它与背景属性一起使用。:root{--bg:linear-gradient(#000,#000)center/50px;}.section{background:var(--bg);}.section--unique{background:var(--bg)no-repeat;}@keyframes规则中的动画变量如果您阅读过CSS变量规范,您可能遇到过“动画污染”一词。这个想法是,当在@keyframes规则中使用时,CSS变量不能被动画化。htmlCSS.box{width:50px;高度:50px;背景:#222;--偏移量:0;变换:translateX(var(--offset));动画:moveBox1s无限交替;}@keyframesmoveBox{0%{--offset:0;}50%{--offset:50px;}100%{--offset:100px;}}动画运行不流畅。它只会对值(0、50px、100px)进行动画处理。根据CSS规范:@keyframes规则中使用的任何自定义属性都将被动画污染,这将影响它在通过动画属性中的var()函数引用时的处理方式。如果我们想让上面的动画起作用,我们应该用老式的方法来做。这意味着,我们需要用我们想要动画的实际CSS属性替换变量。@keyframesmoveBox{0%{变换:translateX(0);}50%{转换:translateX(50px);}100%{转换:translateX(100px);}}计算你可能不知道可以使用CSS变量进行计算。考虑以下示例:.c-avatar{display:inline-block;宽度:calc(var(--size,1)*30px);height:calc(var(--size,1)*30px);}.c-头像大小会有所不同。我将默认值设置为1,因此默认大小为(30px*30px)。请注意不同的类别变化以及更改--size值如何导致头像大小发生变化。.c-avatar--small{--size:2;}.c-avatar--medium{--size:3;}.c-avatar--large{--size:4;}Devtools和CSS变量我们您可以在浏览器DevTools中使用一些有用的技巧来简化CSS变量的处理。当颜色使用CSS变量时,查看颜色或背景值的视觉指示器是否有用?Chrome和Edge证明了这一点。计算值要查看CSS变量的计算值,只需将鼠标悬停或单击即可。禁用CSS变量当我们需要从所有使用它的元素中禁用CSS变量时,我们可以通过从定义它的元素中取消选中它来实现。见下图:本文介绍了很多CSS变量的内容,希望对大家有所帮助,二次创作不易,请点赞+转发。代码部署后可能存在的bug,无法实时获知。事后为了解决这些bug,花费了大量的时间在日志调试上。顺便推荐一个好用的bug监控工具Fundebug。原文:https://ishadeed.com/article/...交流有梦想,有干货,微信搜索【伟大的走向世界】关注这位凌晨还在洗碗的洗碗智慧。本文GitHubhttps://github.com/qq44924588...已收录,有完整的测试站点、资料和我的一线厂商访谈系列文章。