当前位置: 首页 > 科技观察

如果您觉得自己是CSS变量的新手,请添加以下内容!

时间:2023-03-18 16:56:38 科技观察

CSS变量(又名自定义属性)在Web浏览器中的支持已经将近四年了。我一般也是根据项目情况来使用的。它们非常有用且易于使用,但它们经常被前端开发人员误用或误解。简介CSS变量是在CSS文档中定义的值,目的是为了可重用性和减少CSS值中的冗余。下面是一个基本的例子。.section{border:2pxsolid#235ad1;}.section-title{color:#235ad1;}.section-title::before{content:"";display:inline-block;width:20px;height: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{/*Otherstyles*/background-color:var(--color-primary);}是不是比以前干净多了?--color-primary变量是全局变量,因为我们在:root元素中定义了它。但是,我们也可以将变量范围限定为整个文档中的某些元素。命名变量类似于编程语言命名变量,CSS变量的有效名称应包含字母数字字符、下划线和破折号。另外,值得一提的是CSS变量是区分大小写的。/*法定名称*/:root{--primary-color:#222;--_primary-color:#222;--12-primary-color:#222;--primary-color-12:#222;}/*Illegalnaming*/:root{--primarycolor:#222;/*Spacingsarenotallowed*/--primary$%#%$#}作用域CSS变量也有自己的作用域,这一概念类似于其他编程语言。以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);保证金底部:var(--unit);}/*覆盖章节标题样式*/.featured-authors.section-title{--primary-color:#d16823;}.latest-articles.section-title{--primary-color:#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%;}这里的按钮通过减小变量--primary-b变暗。用例三:比例调整如果您使用过Photoshop、Sketch、Figma或Adob??eXD等设计程序,那么我们需要在调整元素大小时按住Shift键以避免扭曲它。在CSS中,没有直接的方法可以做到这一点,但我们有一个简单的解决方法,即使用CSS变量。假设有一个图标,它的宽度和高度应该相等。我为宽度和高度定义了变量--size。.icon{--size:22px;width:var(--size);height:var(--size);}现在您可以通过简单地更改--size变量的值来模拟Shift调整大小效果。用例四:CSS网格CSS变量对于网格非常有用。假设您希望网格容器根据定义的首选宽度显示其子项。使用变量比为每个变体创建类并复制CSS更容易做到这一点。.wrapper{--item-width:300px;display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--item-width),1fr));grid-gap:1rem;}。wrapper-2{--item-width:500px;这样,我们就可以创建一个完整的、灵活的、易于维护的、可以在其他项目中使用的网格系统。相同的概念可以应用于grid-gap属性。wrapper{--item-width:300px;--gap:0;display:grid;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:leftcenter;background:#ccclinear-gradient(#000,#000)no-repeat;background-size:var(--size)var(--size);背景-position:var(--pos);}用例七:在浅色模式和深色模式之间切换现在,网站比以往任何时候都更需要深色和浅色模式。使用CSS变量,我们可以存储它们的两个版本,并根据用户或系统偏好在它们之间切换。:root{--text-color:#434343;--border-color:#d2d2d2;--main-bg-color:#fff;--action-bg-color:#f9f7f7;}/*添加到``元素类*/.dark-mode{--text-color:#e9e9e9;--border-color:#434343;--main-bg-color:#434343;--action-bg-color:#363636;}用例八:设置默认值在某些情况下,您需要使用JavaScript设置CSS变量。假设我们需要获取可扩展组件的高度。变量--details-height-open为空,它将被添加到特定的HTML元素中。当JavaScript由于某种原因失败时,提供适当的默认值或回退值很重要。.section.is-active{max-height:var(--details-height-open,auto);}auto值是JS失败时的fallback值,没有定义CSS变量--details-height-open。用例9:控制包装器宽度网站包装器可以有多种变体。有时需要一页小包,另一页大包。在这种情况下,合并CSS变量可能会有用。.wrapper{--size:1140px;max-width:var(--size);}.wrapper--small{--size:800px;}用例11:动态网格项我们可以添加--item-width变量,仅此而已。例如,这种方法可以帮助制作网格原型。HTML

CSS.wrapper{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--item-width),1fr));grid-gap:1rem;}示例:https://codepen.io/shadeed/pen/7d3e0d575a5cecb86233fc7d72fa90d4用例十二:用户头像另一个有用的用例是调整元素大小。假设我们需要四种不同大小的用户头像,并且只能使用一个变量来控制它们的大小。.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变量的元素都会根据视口大小改变其间距,这是不是很棒?用例十四:继承是的,CSS变量确实可以继承。如果在父元素中定义了CSS变量,则子元素将继承相同的CSS变量。让我们看下面的例子:HTML

css.parent{--size:20px;}.child{font-size:var(--尺寸);}。子元素可以访问变量--size,因为它是从父元素继承的。很有意思,那么在实际项目中有什么用呢?我们有一组具有以下要求的操作项。更改变量可以更改所有项目的大小。间距应该是动态的HTML
CSS.actions{--size:50px;display:flex;gap:calc(var(--size)/5);}.actions--m{--size:70px;}.actions__item{width:var(--size);height:var(--size);}请注意,这里是如何将变量--size用于flexbox间隙属性。这意味着间距可以是动态的并且取决于--size变量。另一个有用的例子是使用CSS变量继承来自定义CSS动画:@keyframesbreath{from{transform:scale(var(--scaleStart));}to{transform:scale(var(--scaleEnd));}}。walk{--scaleStart:0.3;--scaleEnd:1.7;animation:breath2salternate;}.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;height:50px;background:#222;--offset:0;transform:translateX(var(--offset));animation:moveBox1sinfinitealternate;}@keyframesmoveBox{0%{--offset:0;}50%{--offset:50px;}100%{--offset:100px;}}动画无法顺利进行。它只会对值(0、50px、100px)进行动画处理。根据CSS规范:@keyframes规则中使用的任何自定义属性都将被动画污染,这将影响它在通过动画属性中的var()函数引用时的处理方式。如果我们想让上面的动画起作用,我们应该用老式的方法来做。这意味着,我们需要用我们想要动画的实际CSS属性替换变量。@keyframesmoveBox{0%{transform:translateX(0);}50%{transform:translateX(50px);}100%{transform:translateX(100px);}}计算你可能不知道可以使用CSS变量进行计算.考虑以下示例:.c-avatar{display:inline-block;width: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变量的内容,希望对大家有所帮助,二次创作不易,请点赞+转发。作者:AhmadShadeed译者:FrontendXiaozhi来源:ishadeed原文:https://ishadeed.com/article/css-vars-101/关注。转载本文请联系大千世界公众号。