目录
预处理器变量的限制
Preprocessor variables aren’t live
预处理器变量不能级联(层叠)
预处理器变量不继承
预处理器变量不能相互协作
自定义属性有何不同
实际案例
媒体查询的响应式特性
语境样式
创建例外
跟React学
最大限度的减少副作用
管理全局names
结束语
首页 web前端 html教程 [ISUX译]为什么我为css变量如此兴奋_html/css_WEB-ITnose

[ISUX译]为什么我为css变量如此兴奋_html/css_WEB-ITnose

Jun 21, 2016 am 09:01 AM

几个星期前,CSS Variables ——CSS 变量草案发布在了W3C官方 ,更准确的应该叫 CSS 自定义属性 ,目前在 Chrome Canary 版里面已经支持,开启该功能见附[1]

当Chrome浏览器工程师 Addy Osmani 第一时间把这消息发布在twitter后,遭到了数万人的 否定 、 敌视 和 怀疑 。于我而言,更多的感到是一个惊喜,因为这个功能实在让人太兴奋了。

快速的扫了一遍之后,发现99%人抱怨的无外乎这两点:

  • 语法太丑和不够简洁
  • Sass 、Less早就有这些玩意了,不太care

虽然我承认我也对这语法很反感,更重要的是理解语法不只是反复无常的在选择。CSS工作组讨论很久语法的长度,他们 提取了一些点 ,考虑到CSS的语法兼容不会与未来增加的其他语言冲突。

CSS 预处理器是一个非常出色的工具,但是它们的变量是静态的,有语法作用域。Native CSS 变量,从另一面来看,它们是一个完全不同类型的变量:因为它们是动态的,他们的作用域是DOM,事实上,这也是困惑该不该称他们为变量,它们实际上是CSS 属性,这也给了他们一个机会,来解决这个功能完全不同的问题。

在这篇文章中,我将讨论一些CSS 自定义属性这个功能,而且不用CSS 预处理器来做。当然我还演示一些新的设计模式,自定义功能的启用。文章最后讨论一下,我认为在未来最有可能的是预处理变量和自定义变量一起使用,两个东西取长补短,珠联璧合。

注意:这篇文章不是介绍CSS 自定义属性,如果你还从来没听说过他们,不熟悉他们是如何工作的,可以看看 这里

预处理器变量的限制

在继续写之前,我想强调的是,我真的很喜欢CSS 预处理器,我的所有项目都在使用它。预处理器做了一件非常了不起的事情,即时你知道他最终出来的就是原始的CSS,任然可以感受这个神器的时代。

任何工具,都有他的局限性,有一个炫酷的外观会让人惊喜而忽略了其中的限制,特别是新用户。

Preprocessor variables aren’t live

也许受预处理限制,在媒体查询中,最常见的新手也无力吐槽定义变量或使用 @extend

<code>$gutter: 1em; @media (min-width: 30em) {  $gutter: 2em;} .Container {  padding: $gutter;}</code>
登录后复制

如果你编译上面的代码,你得到是:

.Container {  padding: 1em;}
登录后复制

如你所见,媒体查询被废弃,变量赋值被忽略。

从理论上讲,虽然sass 负责申明条件变量,但这样做也是一个挑战,枚举所有Permutations—exponentially 会增加CSS的最终大小。

预处理器变量不能级联(层叠)

每当你使用变量,作用域的范围不可避免,这个变量应该全局吗?应该是file/module?还是块作用域?

CSS 最终是为HTML的样式,事实证明还有另外一种有用的方法是变量的范围:DOM 元素,但是preprocessors不能运行在浏览器且从未看见标记

参考一个网站,试图给 的元素添加一个 class user-setting-large-text 他们更倾向于更大的文本大小 。

一旦这个class设置,更大 $font-size 变量赋值就会运用:

$font-size: 1em; .user-setting-large-text {  $font-size: 1.5em;} body { font-size: $font-size;}
登录后复制

但是,就像上面媒体查询例子,Sass 直接忽略变量赋值, 意味着这种事是不可能的。他输出的:

body {  font-size: 1em;}
登录后复制

预处理器变量不继承

虽然继承是级联的一部分,但是我还是要提一下,因为很多次我想使用这个功能都未能用成。

有一种情况,你有Dom元素在颜色风格基础上有什么的变化时候,你可以用在他们的父元素上。

.alert { background-color: lightyellow; }.alert.info { background-color: lightblue; }.alert.error { background-color: orangered; } .alert button { border-color: darken(background-color, 25%);}
登录后复制

上面的Sass代码是无效的,但你应该能理解这代码试图要完成什么。

它最后试图使用sass的 darken 函数用在 background-color 属性,但button元素继承它的父class元素 .alert 。如果class info 或者 error 已经添加到 alert (或者通过JavaScript设置背景颜色或用户样式),按钮元素希望能够得到这两个颜色。

现在这个虽然不会在sass 运行,因为预处理器不知道DOM结构,但还是希望搞清楚这类型的东西可能有哪些用处。

说一个特定的用例:这也是在继承DOM属性的可访问性运行color 函数的原因。举个栗子,为了确保文本总是可读,且充分与背景颜色形成鲜明对比。通过自定义属性和新的 CSS Color函数 ,这将很快成为可能!

预处理器变量不能相互协作

这是一个明显呈下降趋势的预处理器,如果你用PostCSS 建立一个网站,你想使用第三方组件,不好意思,你只有通过Sass的 themeable

与第三方分享预处理器变量在不同的工具集成或第三方托管的CND样式与都非常困难(至少不容易)

本地CSS自定义属性将与任何CSS预处理或者原CSS正好相反。

自定义属性有何不同

你可能已经猜到了,我上面列出的适用于CSS 自定义属性没有任何限制,但也许更重要的不是说他们不适用,而是为什么他们不用。

CSS自定义属性就像常规的CSS属性一样,他们的操作方式完全相同

像普通的CSS属性,自定义属性是动态的,他们可以在运行时修改,也可以在媒体查询时通过更改DOM添加一个新类,同时也可以指派内联元素和一个常规CSS里申明选择器。还可以通过正常的cascade规则或者使用JavaScript覆盖。最主要的是,他们的可以继承的,所以当他们应用到DOM元素的时候,他们的子元素也会继承属性。

为了更简洁,预处理器变量是语法作用域和编译后静态。自定义属性作用域是DOM,他们都很灵活。

实际案例

如果你仍然不确定自定义属性可以做到这一点,而预处理器不行,我这里给一些例子。

不论真假,有大量非常好的例子我都很想展示,但为了不让这篇文章太丑,我选了两个。

我选择这些例子不仅仅因为它们的理论,它们也是我们过去实际面临的挑战,我依然记得试图用预处理器,但这是不可能的。现在好了,直接自定义属性走起。

媒体查询的响应式特性

很多网站在项目布局使用“ gap ”和“ gutter ” 定义默认间距和填充页面各个部分,很多时候,你想要这个“ gutter ”的值根据浏览器窗口的大小而不同。在大屏幕上你想要每一项之间有足够的空间,但小屏幕又负担不起那么大的空间,所以“ gutter ”的值要较小。

正如我上面提到的,在媒体查询里面Sass 不能正常运行,所以你必须每个单独处理。

下面的例子定义了变量 $gutterSm , $gutterMd 和 $gutterLg ,然后给每个变量申明一个单独的规则:

/* Declares three gutter values, one for each breakpoint */ $gutterSm: 1em;$gutterMd: 2em;$gutterLg: 3em; /* Base styles for small screens, using $gutterSm. */ .Container { margin: 0 auto; max-width: 60em; padding: $gutterSm;}.Grid { display: flex; margin: -$gutterSm 0 0 -$gutterSm;}.Grid-cell { flex: 1; padding: $gutterSm 0 0 $gutterSm;} /* Override styles for medium screens, using $gutterMd. */ @media (min-width: 30em) { .Container { padding: $gutterMd; } .Grid { margin: -$gutterMd 0 0 -$gutterMd; } .Grid-cell { padding: $gutterMd 0 0 $gutterMd; }} /* Override styles for large screens, using $gutterLg. */ @media (min-width: 48em) { .Container { padding: $gutterLg; } .Grid { margin: -$gutterLg 0 0 -$gutterLg; } .Grid-cell { padding: $gutterLg 0 0 $gutterLg; }}
登录后复制

使用自定义属性来完成相同的东西,你只需要定义样式即可。你可以使用一个 gutter 属性,然后随着媒体查询的变化,更新 gutter 的值,它就会做出相应的变化。

:root { --gutter: 1.5em; } @media (min-width: 30em) {  :root { --gutter: 2em; }}@media (min-width: 48em) {  :root { --gutter: 3em; }} /* * Styles only need to be defined once because * the custom property values automatically update. */ .Container {  margin: 0 auto; max-width: 60em; padding: var(--gutter);}.Grid { --gutterNegative: calc(-1 * var(--gutter)); display: flex; margin-left: var(--gutterNegative); margin-top: var(--gutterNegative);}.Grid-cell { flex: 1; margin-left: var(--gutter); margin-top: var(--gutter);}
登录后复制

虽然有额外增加的自定义属性语法,但是相比冗长的代码完成同样的事明显好很多。这里只考虑了三个变量,如果变量越多,这将节省更多的代码。

下面的演示使用的是上面的代码自动构建的一个基本的网站布局,gutter的值跟随窗口的变化而变化,浏览器的支持自定义属性的话,效果屌屌的!

View the demo on CodePen: editor view / full page

语境样式

语境样式(样式元素根据它出现在Dom)在CSS里是一个有争议的话题。 一方面,它是最受人尊敬的CSS开发者警告,另一方面,大多数人每天都还要用它。

Harry Roberts 最近写了 这篇 文章以及他对此的看法:

If you need to change the cosmetics of a UI component based on where it is placed, your design system is failing…Things should be designed to be ignorant; things should be designed so that we always just have “this component” and not “this component when inside…

当我站在Harry这一边,我认为大多数人走捷径这种情况可能表面一个更大的问题:CSS 表现能力是有限的,大部分人不满意当前的“最佳实践”。

下面例子显示了大部分人在CSS使用语境样式方法,使用子代选择器

<code><span class="comment">/* Regular button styles. */</span><span class="variable">.Button</span> { } <span class="comment">/* Button styles that are different when inside the header. */</span><span class="variable">.Header</span> <span class="variable">.Button</span> { }</code>
登录后复制

这种方法有很多问题(在我的文章有 解释 ),这种模式一个代码味道,它违反了 open/closed 软件开发原则;修改了一个封闭组件的实现细节

软件体 (类, 模块, 函数等) 扩展开放, 对修改关闭。

自定义属性的改变范围式定义组件是一个有趣的方式,用自定义属性,我们可以在第一次就写一个实际上是开放扩展的组件,这里有一个例子:

.Button {  background: var(--Button-backgroundColor, #eee);  border: 1px solid var(--Button-borderColor, #333); color: var(--Button-color, #333); /* ... */} .Header { --Button-backgroundColor: purple; --Button-borderColor: transparent; --Button-color: white;}
登录后复制

这和子选择器之间的区别很微妙而且很重要。

当使用子选择器我们宣传在页眉按钮会这样,这样不同的按钮如何定义自己,这样的声明是独裁(借Harry’s 的词),很难撤销例外的情况,页眉的一个按钮不需要这样的方式。

另外,自定义属性,按钮组件仍是没有语境且不能完全与header 组件解耦,

按钮组件简单的说申明:无论它们现状如何,我要自己的风格基于这些自定义属性;

header 组件:我要设置这些属性值,由我的子代来确定和如何使用它们。

主要的区别是,该扩展由按钮组件选择,并轻易消除例外情况。

下面的演示说明了语境样式的链接和按钮在网站的标题及内容区

在CodePen查看demo: editor view / full page

创建例外

如果像 .promo 的组件加到header,然后buttons又加到 .promo 里面,使其看起来像一个正常按钮,而不是标题按钮。

如果你用子代选择器,那你将要给header buttons写一大串样式,而且还不能影响promo buttons,混乱,容易出错,而且容易失控的数量会增加:

/* Regular button styles. */.Button { } /* Button styles that are different when inside the header. */.Header .Button { } /* Undo button styles in the header that are also in promo. */.Header .Promo .Button { }
登录后复制

使用自定义属性,你可以简单的更新任何你想要的新按钮属性,或重置他们回默认样式,无视这些例外,改变的方式总是相同的。

.Promo {  --Button-backgroundColor: initial;  --Button-borderColor: initial;  --Button-color: initial;}
登录后复制

跟React学

当我第一次探索自定义属性语境样式的时候,我很怀疑自己。像前面说的,我倾向于喜欢组件自己定义自己的变化,而不是任何属性都继承自父元素。

但是有一件事,动摇了我在CSS自定义属性的观点,那就是React的 props 的

React的 props 依然是动态的,DOM-scoped variables,他们继承,允许组件上下文关联,在React,父组件将数据传递给子组件,然后子组件定义 props ,他们愿意接受和使用它们。这种建筑模型通常被称为one-way data flow。

尽管自定义组件是全新的未测试的领域,我认为React model 给了成功的信心,一个复杂的系统可以建立在属性继承——此外,DOM-scoped variables 是一个非常有用的设计模式。

最大限度的减少副作用

CSS 自定义属性继承默认,在某些情况下,这导致组件的样式可能没有达到他们的预期。

在文章上一节中,我提到可以重置单个属性,这可以防止未知值被应用到元素的子元素:

.MyComponent {  --propertyName: initial;}
登录后复制

尽管这不是规范的一部分,——正在讨论属性附[2],这个可以用来重置所有自定义属性,如果你想白名单几个属性,你可以将他们单独继承,其他的正常即可:

.MyComponent {  /* Resets all custom properties. */  --: initial;   /* Whitelists these individual custom properties */ --someProperty: inherit; --someOtherProperty: inherit;}
登录后复制

管理全局names

如果你一直关注自定义属性,那你可能已经注意到本身带有components-specific前缀的组件,如 --Button-backgroundColor.

与CSS 大多数名字一样,自定义属性是全局,很是有可能将正在使用命名与其他开发团队的名称产生冲突。

有一个简单的方法可以避免这个问题,就是坚持命名约定,我现在团队就是这么做的。

对于更复杂的项目,你可以考虑像 CSS模块 localifies所有全局名称,而且他们最近也 表示有兴趣 支持自定义属性。

结束语

如果你在阅读这篇文章之前,不熟悉CSS 自定义属性,我希望你能给他一个机会。如果你还在怀疑他的必要性,希望我能改变你的想法。

我敢肯定,自定义属性能给CSS带来一系列的强大的功能和面貌,它还有更多的优势等待我们去发现。

自定义属性preprocessor 变量是无可替代的。尽管如此,preprocessor variables 仍然是许多情况下的不二选择。正因如此,我坚信未来很多网站都会结合使用二者。自定义属性为动态主题和预处理器变量静态模板。

我不认为这是二选一的情况,让他们相互竞争,就像对手一样伤害每一个人。

特别感谢 Addy Osmani 和 Matt Gaunt 审查文章 ,Shane Stephens并及时修复了一些bug才能使demo正常运行,再次感谢。

脚注:

1.你可以启用chrome 的”Experimental Web Platform Features”功能,方法是:地址输入 about:flags 然后搜索“Experimental Web Platform Features”,然后点击“开启”按钮

2.使用——属性(如定制相关样式元素)是Atkins 在 github comment 提到的,此外,给www-style 发送 建议邮件 ,也会很快得到处理的。

本文原文地址: http://philipwalton.com/articles/why-im-excited-about-native-css-variables/

来自: http://isux.tencent.com/why-im-excited-about-native-css-variables.html

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1664
14
CakePHP 教程
1423
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
了解HTML,CSS和JavaScript:初学者指南 了解HTML,CSS和JavaScript:初学者指南 Apr 12, 2025 am 12:02 AM

WebDevelovermentReliesonHtml,CSS和JavaScript:1)HTMLStructuresContent,2)CSSStyleSIT和3)JavaScriptAddSstractivity,形成thebasisofmodernWebemodernWebExexperiences。

HTML:结构,CSS:样式,JavaScript:行为 HTML:结构,CSS:样式,JavaScript:行为 Apr 18, 2025 am 12:09 AM

HTML、CSS和JavaScript在Web开发中的作用分别是:1.HTML定义网页结构,2.CSS控制网页样式,3.JavaScript添加动态行为。它们共同构建了现代网站的框架、美观和交互性。

HTML,CSS和JavaScript的未来:网络开发趋势 HTML,CSS和JavaScript的未来:网络开发趋势 Apr 19, 2025 am 12:02 AM

HTML的未来趋势是语义化和Web组件,CSS的未来趋势是CSS-in-JS和CSSHoudini,JavaScript的未来趋势是WebAssembly和Serverless。1.HTML的语义化提高可访问性和SEO效果,Web组件提升开发效率但需注意浏览器兼容性。2.CSS-in-JS增强样式管理灵活性但可能增大文件体积,CSSHoudini允许直接操作CSS渲染。3.WebAssembly优化浏览器应用性能但学习曲线陡,Serverless简化开发但需优化冷启动问题。

HTML的未来:网络设计的发展和趋势 HTML的未来:网络设计的发展和趋势 Apr 17, 2025 am 12:12 AM

HTML的未来充满了无限可能。1)新功能和标准将包括更多的语义化标签和WebComponents的普及。2)网页设计趋势将继续向响应式和无障碍设计发展。3)性能优化将通过响应式图片加载和延迟加载技术提升用户体验。

HTML与CSS vs. JavaScript:比较概述 HTML与CSS vs. JavaScript:比较概述 Apr 16, 2025 am 12:04 AM

HTML、CSS和JavaScript在网页开发中的角色分别是:HTML负责内容结构,CSS负责样式,JavaScript负责动态行为。1.HTML通过标签定义网页结构和内容,确保语义化。2.CSS通过选择器和属性控制网页样式,使其美观易读。3.JavaScript通过脚本控制网页行为,实现动态和交互功能。

HTML:建立网页的结构 HTML:建立网页的结构 Apr 14, 2025 am 12:14 AM

HTML是构建网页结构的基石。1.HTML定义内容结构和语义,使用、、等标签。2.提供语义化标记,如、、等,提升SEO效果。3.通过标签实现用户交互,需注意表单验证。4.使用、等高级元素结合JavaScript实现动态效果。5.常见错误包括标签未闭合和属性值未加引号,需使用验证工具。6.优化策略包括减少HTTP请求、压缩HTML、使用语义化标签等。

HTML与CSS和JavaScript:比较Web技术 HTML与CSS和JavaScript:比较Web技术 Apr 23, 2025 am 12:05 AM

HTML、CSS和JavaScript是构建现代网页的核心技术:1.HTML定义网页结构,2.CSS负责网页外观,3.JavaScript提供网页动态和交互性,它们共同作用,打造出用户体验良好的网站。

HTML:是编程语言还是其他? HTML:是编程语言还是其他? Apr 15, 2025 am 12:13 AM

HTMLISNOTAPROGRAMMENGUAGE; ITISAMARKUMARKUPLAGUAGE.1)htmlStructures andFormatSwebContentusingtags.2)itworkswithcsssforstylingandjavascript for Interactivity,增强WebevebDevelopment。

See all articles