元素查询,以及今天如何使用它们

已发表: 2022-03-10
快速总结 ↬一段时间以来,我们遇到了CSS 的极限。 那些构建响应式布局的人会坦率地承认 CSS 的挫折和缺点,迫使我们使用 CSS 预处理器、插件和其他工具来帮助我们编写单独使用 CSS 无法编写的样式。 即便如此,我们仍然遇到了当前工具帮助我们完成的限制。

想一想一个物理结构。 如果你正在用薄弱的材料建造一座大型建筑,则需要大量外部支撑来将其固定在一起,并且必须过度建造以保持坚固。 当您使用 HTML、CSS 和 JavaScript 构建网站时,这种外部支持可能看起来像框架、插件、预处理器、转译器、编辑工具、包管理器和构建过程。

跳跃后更多! 继续往下看↓

我没有在堆栈顶部添加另一个插件,而是想知道是否可以通过扩展其中一种核心语言 CSS来加强构建网站的材料,开发更好、更强大的网站,而这些网站需要更少的外部支持和工具建造。

元素查询的当前状态

使用诸如 CSS 预处理器之类的工具,我们以简写形式编写 CSS,以便稍后扩展为完整形式(在浏览器中查看之前)。 插件能够在页面上与它们影响的元素一起操作,但要应用样式,它们要么将 CSS 样式直接写入 HTML,要么切换应用不同 CSS 规则的类名。 在这两种情况下,我们都需要在页面实际加载之前编写或生成我们需要的 CSS。

问题

这种方法的问题在于,即使是最好的插件也经常需要在您使用的每个布局中进行自定义和配置。 此外,当 JavaScript 为您编写样式时,在重构或重用代码时,很难将基于插件的逻辑和 CSS 样式保持在一起。

预处理器的另一个问题是,一旦 CSS 扩展为完整形式,任何以简写形式编写的错误都会迅速膨胀成更大的混乱。 使用插件时,我们会添加许多潜在的故障点。 我们可能会使用多个插件来完成一些不同的事情,如果 CSS 更强大一点,这些事情可能都是不必要的。 这给开发人员维护、浏览器渲染和用户下载带来了额外的负担。

Web 开发的未来有希望吗?

2013 年,Tyson Matanich 写了一篇题为“Media Queries Are Not the Answer: Element Query Polyfill”的文章,向广大受众介绍了元素查询的概念。 它引发了关于如何构建插件和 polyfill 以绕过 CSS 缺点的讨论。

从那时起,在我们等待 CSS 功能发展的同时,已经发布了许多插件,允许开发人员以几种不同的方式使用元素查询。

什么是元素查询?

元素查询类似于媒体查询,只是它们的规则适用于实际元素的属性,而不是浏览器视口的属性。

EQCSS 是如何产生的

2013 年末,我发现自己正在开发一个 Ruby on Rails Web 应用程序的前端。 该应用程序需要向用户显示详细信息,其目标是构建一个响应式界面,该界面在手机、平板电脑和桌面浏览器上表现同样出色。 这带来了一些挑战,其中之一是要显示的大部分重要内容最好显示在表格中——是的,实际的table元素(显示金融交易、体育记录等)。

EQCSS 项目是对元素媒体查询的研究的结果。 现在,它终于发布了,您今天可以使用它。 检查演示。

我使用媒体查询创建了响应式样式,这些查询为不同大小的浏览器正确显示了table元素。 但是,一旦其中一个响应式表格显示在包含侧边栏的模板中,突然间我所有的响应式断点都变成响应式断点。 他们根本没有考虑到 200 像素宽的侧边栏,导致内容重叠并出现损坏。

另一个障碍:用户名的长度从 3 到 20 个字符不等,我发现自己希望能够根据每个用户名包含的字符数自动调整每个用户名的字体大小。 我需要将每个用户名放在侧边栏中,要选择一个小到足以容纳 20 个字符的用户名但又大到足以让查看者看到 3 个字符的用户名的字体大小是很棘手的。

为了解决这些问题,我经常发现自己复制了整个媒体查询,复制了我的代码库的大部分,仅仅是因为我需要一种更智能的方法来在每个布局中应用响应式样式。 我依赖 JavaScript 作为另一种临时解决方案,编写了许多几乎相同的函数来监视页面并在 CSS 无法到达的地方应用样式。 过了一段时间,所有这些重复代码所增加的负担开始拖累代码库,使更改变得困难。

我知道必须有更好的解决方案,过了一会儿我开始思考:我不需要媒体查询——我需要的是元素查询!

研究与开发

到 2014 年,我开始尝试不同的方式来告知 CSS 元素出现在页面上的属性,以便我可以应用更好的样式。 我希望找到一种方法,可以让我编写将 CSS 的美感与 JavaScript 的强大功能相结合的样式。

我放弃的一些废弃方法包括向 HTML 标记添加属性以添加响应式支持,并尝试找到将整个 CSS 代码块嵌入基于 JavaScript 的if语句的方法,以产生某种从 JavaScript 拼凑在一起的科学怪人怪物和 CSS。

但是,我所有失败的方法并没有让事情变得更容易,而是有一个共同点:它们增加了更多的工作! 我知道正确的解决方案会简化并减少需要完成的工作,所以我一直在寻找。 通过这些实验,我最终对元素查询正常工作所需的语法类型有了一个改进的想法。

如前所述,对于由 HTML、CSS 和 JavaScript 构建的网站,外部支持以框架、插件、预处理器、转译器、编辑工具、包管理器和构建过程的形式出现。 我没有在堆栈顶部添加另一个插件,而是想知道,通过扩展其中一种核心语言 CSS,我们是否可以加强构建网站的材料,构建更好、更强大的网站,需要更少的外部支持和构建工具。

语法的诞生

到 2014 年底,由于对所需语法有了更好的了解,我联系了出色的 JavaScript 代码高尔夫球手 Maxime Euziere,询问他对在运行时在浏览器中使用 JavaScript 扩展 CSS 的可能性的看法。 他不仅告诉我这是可能的,而且还主动提出帮助我做到这一点! 我们将语法命名为 EQCSS,是“元素查询 CSS”的缩写。 这个名字也是对“过剩”这个词的一种认可,因为它所做的一切都超出了 CSS 所能做的。

需要

我对语法的要求是它尽可能接近 CSS——如此接近以至于语法高亮会被愚弄以为它是标准 CSS。 因此,我为有意义的元素查询制定了 CSS 语法——人们感到惊讶的那种语法并不存在。

我知道,如果我们要使用 JavaScript 扩展浏览器对 CSS 的支持,那么插件需要尽可能轻量和简单才能完成工作,这排除了使用 jQuery 等库来构建插件的可能性。 我需要一个纯 JavaScript 库,它将将来我想要的功能添加到我今天必须支持的浏览器中。

这时候CSS社区的讨论主要集中在自定义@规则上,关于元素查询的讨论还处于初步阶段。 对于此类功能,我们可能距离任何官方 CSS 规范还有好几年的时间,即使在规范之后,我们仍然需要等待足够的浏览器支持才能在网站中使用这些功能。

当我们今天需要这些功能来构建和修复网站时,等待这些功能添加到 CSS 中是没有意义的。

结果

这项研究的结果是创建了一种语法,其中包括一组新的高级响应条件、范围样式和用于定位元素的新选择器,以及一个名为 EQCSS.js 的纯 JavaScript 库。 另外,在可选的外部 polyfill 中提供了对 Internet Explorer (IE) 8 的支持。 插件和 polyfill 都在 MIT 许可下发布,所有人都可以免费使用。

元素查询用例

插件开发者

在创建 UI 组件和小部件时,开发人员经常发现自己受到媒体查询的限制。 我们经常不得不在构建许多不同的布局之间做出选择,这些布局可以由使用插件的人进行配置,以及将界面简化到可以构建一刀切的解决方案的地步。

但是在设计带有元素查询的插件和界面时,我们可以轻松地编写响应式样式来涵盖我们预期的所有情况,从而使它们真正防弹,无论用户放入什么内容或插件出现在哪里。 假设我们可以为一个 150 到 2000 像素宽的布局设置样式。 然后,无论该小部件显示在网站的哪个位置,它总是看起来很棒。

模板生成器

当您对网站进行原型设计时,通常会重新组织页面上的设计元素并将设计视为模块化组件的集合。 如果您编写了 CSS 媒体查询,有时这可能是过早优化的情况。 通过使用元素查询进行设计,您可以保持响应条件与布局无关,从而为您提供更大的灵活性来移动事物,而无需重新设计样式。

我发现使用元素查询设计或模拟特别有用的东西包括:

  • 导航栏,
  • 模态,
  • 注册和登录表格,
  • 页脚,
  • 定价图表,
  • 登陆页面,
  • 表,
  • 标签框,
  • 手风琴,
  • 侧边栏小部件,
  • 媒体播放器,
  • 推荐部分。

任何设计元素都可以被“限定”并移植到任何地方——页面到页面或网站到网站。

设备支持

在移动设备上支持 Web 时,您面临的问题之一是大量的硬件。 设备市场比以往任何时候都更加分散,新设备每天都在出现。 我们无法再维护我们支持的浏览器和设备的列表,因此了解设计适用于任何地方至关重要,即使在尚未发布的设备上也是如此。

通过使用元素查询,您可以以更好的方式设计网站并消除其中一些跨浏览器差异。

最近撰写的许多关于元素查询需求的文章都详细说明了许多用例。 那么,让我们继续了解如何使用它们吧!

如何编写元素查询

EQCSS 入门很容易。 开始使用 EQCSS 语法所需要做的就是在 HTML 的某处包含 JavaScript。

下载 EQCSS.js

如果你想从 GitHub 克隆 EQCSS 项目,你可以输入:

 git clone https://github.com/eqcss/eqcss.git

如果您使用 npm,您可以使用以下命令将 EQCSS 添加到您的项目中:

 npm install eqcss

将 EQCSS.js 添加到您的 HTML

下载 EQCSS 后,您可以使用script标签将其添加到 HTML:

 <script src="EQCSS.js"></script>

此文件 ( EQCSS.js ) 包括对所有当前浏览器的支持,包括 IE 9 及更高版本。 为了支持 IE 8,我们不得不使用很多其他的 polyfill。 请记住,IE 8 甚至不支持没有 polyfill 的 CSS 媒体查询,所以我们能够让元素查询也在那里工作真是太神奇了。 要包含对使用 EQCSS 的网站的 IE 8 支持,请在指向主插件的链接之前添加以下链接:

 <!‐‐[if lt IE 9]><script src="EQCSS‐polyfills.js"></script><![endif]‐‐>

运行 EQCSS

默认情况下,EQCSS 插件将在页面加载后计算它找到的任何样式,并且每当它检测到浏览器正在调整大小时,类似于媒体查询。 您还可以随时使用 JavaScript 手动调用EQCSS.apply()以重新计算样式,这在页面上更新内容后会很有用。

编写元素查询 CSS

EQCSS.js 插件可以通过几种不同的方式读取样式。 您可以在 HTML 页面上的任何style标签中包含 EQCSS。 您还可以在外部 CSS 样式表中编写 EQCSS。

如果您想将 EQCSS 驱动的代码与 CSS 分开,您可以使用类型设置为text/eqcssscript标签加载 EQCSS 语法。 您可以在这样的标记中内联添加样式,或者使用<script type=“text/eqcss” src=styles.eqcss></script>链接到外部.eqcss样式表,这将加载名为styles.eqcss的文件.

元素查询剖析

样式范围

EQCSS 中用于编写元素查询的语法与 CSS 媒体查询的格式非常相似,但我们以@element开始查询,而不是@media 。 我们需要提供的唯一其他信息是这些样式应该应用于的至少一个选择器。 以下是为名为<div class=“widget”>的元素创建新范围的方法:

 @element '.widget' { }

引号之间的元素(在本例中为.widget )可以是任何有效的 CSS 选择器。 通过这个查询,我们在.widget元素上创建了一个新范围。 我们还没有为作用域包含任何响应条件,因此像这样的查询中的任何样式都将始终应用于作用域元素。

如果无法将样式范围限定为一个或多个元素(而不是一次覆盖整个页面),我们将无法仅将响应式查询应用于这些元素。 一旦我们创建了元素级别的范围,使用 EQCSS 语法的更高级的特性就变得很容易了——例如$parent元选择器——因为 JavaScript 现在有一个参考点来计算像范围的parentNode这样的东西元素。 这是巨大的!

确实,CSS 已经包含一个直接后代选择器,带有> ,它允许我们选择作为指定元素的直接子元素的元素。 但是 CSS 目前没有提供沿家族树的另一个方向向上移动的方法,以选择包含另一个元素的元素,人们将其称为其父元素。 “CSS Selectors Level 4”规范现在包括一个:has()选择器,它的工作方式类似于 jQuery 的:has()选择器,但目前浏览器支持为零。 Scoped CSS 使不同类型的父选择器成为可能。

现在我们已经在.widget元素的上下文中打开了一个作用域,我们可以从它的角度编写样式来定位它自己的父元素:

 @element '.widget' { $parent { /* These styles apply to the parent of .widget */ } }

可以在任何元素查询中使用的特殊选择器的另一个示例是$prev$next选择器,它们表示前一个和下一个兄弟元素。 尽管 CSS 可以使用.widget + *之类的选择器到达我们小部件的下一个兄弟,但 CSS 中无法向后到达并选择直接位于另一个元素之前的元素。

 <section> <div>This will be the previous item</div> <div class="widget">This is the scoped element</div> <div>This will be the next item</div> </section> <style> @element '.widget' { $prev { /* These styles apply to the element before .widget */ } $next { /* These styles apply to the element after .widget */ } } </style>

元素查询

开发人员最常使用 CSS 媒体查询进行响应式设计,方法是根据浏览器视口的高度或宽度应用样式。 EQCSS 语法支持许多新类型的响应条件。 除了单独使用浏览器的宽度和高度之外,您还可以根据元素自身的属性编写适用于元素的样式,例如元素包含多少子元素,或者元素中当前有多少字符或文本行.

将这些响应条件添加到您的作用域样式类似于格式化媒体查询的方式:您将为要检查的每个条件添加and (condition: value) 。 在此示例中,我们将检查是否有任何.widget元素在页面上显示至少 500 像素宽。

 @element '.widget' and (min‐width: 500px) { /* CSS rules here */ }

元素查询的语法分解如下:

  • 元素查询@element selector_list [ condition_list ] { css_code }
  • 选择器列表" css selector [ "," css selector ]* "
  • 条件列表and ( query_condition : value ) [ "and (" query condition ":" value ")" ]*
  • 数值number [ css unit ]
  • 查询条件min-height | max-height | min-width | max-width | min-characters | max-characters | min-lines | max-lines | min-children | max-children | min-scroll-y | max-scroll-y | min-scroll-x | max-scroll-x min-height | max-height | min-width | max-width | min-characters | max-characters | min-lines | max-lines | min-children | max-children | min-scroll-y | max-scroll-y | min-scroll-x | max-scroll-x
  • css 单位% | px | pt | em | cm | mm | rem | ex | ch | pc | vw | vh | vmin | vmax % | px | pt | em | cm | mm | rem | ex | ch | pc | vw | vh | vmin | vmax

作为另一个例子,下面是如何编写一个查询,当.widget元素达到 500 像素宽时将body元素变为红色:

 @element '.widget' and (min‐width: 500px) { body { background: red; } }

请注意,当.widget达到一定宽度时, body元素会发生变化,而不是.widget元素本身!

元素查询条件

以下是 EQCSS 支持的响应条件的完整列表。

基于宽度的条件

  • 像素min-width演示,百分比的演示
  • 像素max-width演示,百分比的演示

基于身高的条件

  • 像素min-height演示,百分比演示
  • 像素max-height演示,百分比演示

基于计数的条件

  • 块元素min-characters演示,表单输入的演示
  • 块元素max-characters演示,表单输入的演示
  • min-lines演示
  • max-lines演示
  • min-children演示
  • max-children演示

基于滚动的条件

  • min-scroll-y演示
  • max-scroll-y演示
  • min-scroll-x演示
  • max-scroll-x演示

您可以在元素查询中组合任意数量的这些条件,以获得真正的多维响应式样式。 这使您可以更灵活地控制元素的渲染方式。 例如,当可显示的空间少于 600 像素时,要缩小超过 15 个字符的标题的字体大小,您可以组合max‐characters: 15max‐width: 600px的条件:

 h1 { font‐size: 24pt; } @element 'h1' and (min‐characters: 16) and (max‐width: 600px) { h1 { font‐size: 20pt; } }

元选择器

一旦开始使用响应条件编写作用域样式,您可能会遇到的问题之一是,当同一选择器的多个实例位于页面上时,在元素查询中使用该选择器会将样式应用于该选择器上的所有实例任何一个符合条件的页面。 以前面的.widget示例为例,假设我们在页面上有两个小部件(可能一个在侧边栏中,另一个全宽显示),我们这样编写元素查询:

 @element '.widget' and (min‐width: 500px) { .widget h2 { font‐size: 14pt; } }

这意味着当页面上的.widget元素至少有 500 像素宽时,该样式将应用于这两个.widget元素。 在大多数情况下,这可能不是我们想要发生的。 这就是元选择器的用武之地!

组成我们的元素查询的两个部分是选择器和响应条件。 因此,如果我们只想定位页面上同时匹配选择器响应条件的元素,我们可以使用元选择器$this 。 我们可以重写上一个示例,使样式仅适用于匹配min‐width: 500px条件的.widget元素:

 @element '.widget' and (min‐width: 500px) { $this h2 { font‐size: 14pt; } }

EQCSS 语法支持许多不在常规 CSS 中的新选择器。 以下是完整列表:

  • $this演示
  • $parent演示
  • $root演示
  • $prev演示
  • $next演示

这些选择器仅适用于元素查询。

打开 JavaScript 和 CSS 之间的门户

  • eval(')演示

EQCSS 的最后一个也是最后一个特性是最狂野的: eval(') 。 通过这个入口,可以从 CSS 访问 JavaScript 的所有功能。 尽管 JavaScript 可以将样式应用于元素,但它目前很难实现某些东西,例如:before:after伪元素。 但是如果 CSS 可以从另一个方向到达 JavaScript 呢? 如果 CSS 可以感知 JavaScript,而不是 JavaScript 设置 CSS 属性,那会怎样?

这就是eval(')用武之地。您可以访问和评估任何 JavaScript,是否使用 CSS 中 JavaScript 变量的值来执行 JavaScript 单行(如eval('new Date().getFullYear()') ),以确定有关浏览器的值和 JavaScript 可以测量的其他元素(如eval('innerHeight') )或运行 JavaScript 函数并使用它在 CSS 样式中返回的值。 这是一个在<footer>元素中输出2016的示例:

 @element 'footer' { $this:after { content: " eval('new Date().getFullYear()')"; } }

在 eval(') 中使用 $it

在评估 JavaScript 时, eval(')还可以在活动范围元素的上下文中工作,即$this的样式适用于同一元素。 你可以在用eval(')编写的 JavaScript 中使用$it作为作用域元素的占位符,如果它可以帮助你构造代码,但如果省略,它会以相同的方式工作。 例如,假设我们有一个div ,其中包含单词“hello”。 以下代码将输出“hello hello”:

 <div>hello</div> <style> @element 'div' { div:before { content: "eval('$it.textContent') "; } } </style>

在这里, $it指的是div ,因为它是当前作用域的选择器。 您也可以省略$it并编写以下代码来显示相同​​的内容:

 @element 'div' { div:before { content: "eval('textContent') "; } }

eval(')在 CSS 不知道页面加载后发生的测量或事件的情况下会很有帮助。 例如,用于嵌入 YouTube 视频的 iframe 元素具有指定的宽度和高度。 虽然您可以在 CSS 中将宽度设置为auto ,但当视频扩展以填充可用空间时,没有简单的方法来保持正确的宽高比。

在缩放时保持响应式纵横比的常见解决方法是将需要保持其纵横比的内容放置在包装器中,然后使用基于您想要保持的宽高比的值向包装器添加填充。 这可行,但需要您提前知道所有视频的纵横比,并且需要为每个要响应式嵌入的视频添加更多 HTML 标记(包装器元素)。 在每个具有响应式视频的网站上乘以它,如果 CSS 稍微聪明一点,那就不需要存在很多麻烦了。

也许更好的响应式纵横比方法是将每个视频放在一个没有填充的包装器中,然后编写一个 JavaScript 库来计算它找到的每个视频的纵横比,并将正确的填充量应用于每个包装器。

但是如果 CSS可以直接访问这些测量值呢? 我们不仅可以将所有不同纵横比的 CSS 合并到一个规则中,而且如果我们可以在页面加载后对其进行评估,我们可以编写一个规则来响应式地调整我们将来提供的任何视频的大小。 我们可以在没有任何包装器的情况下完成这一切!

如果这看起来好得令人难以置信,请检查一下。 以下是在 EQCSS 中编写无包装响应式调整 iframe 元素大小的简单方法:

 @element 'iframe' { $this { margin: 0 auto; width: 100%; height: eval('clientWidth/(width/height)'); } }

这里, widthheight指的是 HTML 中 iframe 中的width=“”height=“”属性。 JavaScript 可以执行(width/height)的计算,这给了我们纵横比; 并将其应用于任何宽度,我们只需将 iframe 元素的当前宽度除以比率。

这具有 CSS 的简洁性和易读性,以及 JavaScript 的所有功能。 不需要额外的包装器,不需要额外的类,也不需要额外的 CSS。

不过要小心eval(') 。 CSS表达式在过去被认为是危险的是有原因的,我们尝试这个想法也是有原因的。 如果您不注意将它们应用到页面上的元素数量或重新计算样式的频率,那么 JavaScript 最终运行的东西可能比需要的多数百倍。 幸运的是,EQCSS 允许我们调用EQCSS.apply()EQCSS.throttle()来手动重新计算样式,这样我们就可以更好地控制样式何时更新。

危险地带!

如果您创建具有冲突条件或样式的查询,则可能会出现其他问题。 EQCSS 和 CSS 一样,使用特定的层次结构从上到下阅读。 尽管 CSS 是一种声明性语言,但它确实包含一些高级功能。 它距离图灵完备的编程语言只有几步之遥。 到目前为止,调试 CSS 是一件非常简单的事情,但是 EQCSS 将 CSS 从简单的解释性声明性语言转变为动态样式表语言,在 CSS 和浏览器之间增加了一个解释层。 伴随着这个新领域而来的是各种潜在的新陷阱。

这是 EQCSS 中的互惠循环的示例,普通的 CSS 媒体查询在设计上是免疫的:

 @element '.widget' and (min‐width: 300px) { $this { width: 200px; } }

我称之为jekyll: hide; CSS。 但除了一种风格不断触发自身之外,还有可能编写多个相互触发的查询,在我们所说的“双向倒数循环”中,这是最讨厌的:

 @element '.widget' and (min‐width: 400px) { $this { width: 200px; } } @element '.widget' and (max‐width: 300px) { $this { width: 500px; } }

从理论上讲,那个不幸的小部件会卡在一个循环中,在 200 到 500 像素之间调整大小直到时间结束,无法确定宽度。 对于这样的情况,EQCSS 只是按照评估顺序计算规则,奖励获胜者并继续前进。 如果你要重新排列这些规则出现的顺序,如果它们具有相同的特异性,后一种风格总是会获胜。

有人说创建循环(甚至是双倒数倒数循环)的能力是一个设计缺陷,但为了防止循环成为可能,您需要限制 EQCSS 的功能,以消除大部分语法提供的值。 另一方面,在 JavaScript 中创建无限循环非常容易,但这并不被视为该语言的缺陷——它被视为其强大功能的证明! 元素查询也是如此。

调试元素查询

目前,调试元素查询有点像在我们拥有像 web 检查器这样的工具来向我们展示在页面上计算的样式之前调试媒体查询。 目前,调试和开发元素查询需要开发人员维护一个应该发生的响应行为的心理模型。 未来可能会构建支持 EQCSS 的开发者工具,但目前所有主流浏览器的开发者工具都只知道 EQCSS 已经应用到页面元素上的样式,并不知道EQCSS 正在观察的响应条件。

如何使用元素查询进行设计

使用元素查询的最简单方法是将使用媒体查询的现有设计转换为元素查询,从一个布局中“解放”元素及其响应式样式,并使其易于在其他页面和项目中重用该代码。 以下媒体查询和元素查询可能意味着相同的事情:

 footer a { display: inline-block; } @media (max‐width: 500px) { footer a { display: block; } }
 footer a { display: inline-block; } @element 'footer' and (max‐width: 500px) { $this a { display: block; } }

不同之处在于,在原始示例中,页脚链接保持为display: block直到浏览器至少有 500 像素宽。 第二个例子,使用元素查询,看起来是一样的,但前提是footer元素是全宽的。

在将这种样式从其原始媒体查询中解放出来之后,我们现在可以将页脚放置在任何宽度的容器中,并确保当页脚需要应用响应式样式时(即,当它小于 500 像素时),它将是应用。

  1. 确保EQCSS.js存在于目标文档的 HTML 中。
  2. 在 CSS 中将@media替换为@element
  3. 将 CSS 选择器添加到每个@element查询的范围内。
  4. 可选:在元素查询中用$this替换出现的作用域元素。

除非您要转换的设计组件最初设计为使用浏览器视口的全宽显示,否则您可能必须在转换为元素查询后调整断点。

避免锁定

编写 EQCSS 样式的体验与编写常规 CSS 的体验类似:所有您最喜欢的 CSS 属性和技术仍然存在,只是有一些额外的功能可以帮助它们以新的方式协同工作。 因为 EQCSS 将标准 CSS 输出到浏览器,所以您的浏览器内置支持的任何 CSS 功能在与 EQCSS 一起使用时都可以使用。 如果有一天元素查询和范围样式等功能在 CSS 中指定并在浏览器中得到支持,那么您将能够立即开始在 EQCSS 代码中使用它们,同时仍然依赖 EQCSS 来实现浏览器不支持的其他功能但原生支持。

因为您可以直接在 CSS 中以及在其自己的脚本中使用 EQCSS 语法,类型为text/eqcss ,如果 CSS 曾经为原生元素查询开发过语法,您仍然可以将 EQCSS 作为脚本加载并避免冲突.

展望未来,浏览器开发人员目前正在试验的一种解决方案是 Houdini,它将为插件开发人员打开以新方式扩展 CSS 的访问权限,例如添加对浏览器本身的支持。 有一天,可能会编写出更高效的插件来解释 EQCSS 语法,并以比当前 JavaScript 库所允许的更直接和高效的方式将这些功能带到浏览器中。

那么,我们还应该使用媒体查询吗?

是的,尽管元素查询提供了许多新的和令人兴奋的方式来定位具有样式的元素,但媒体查询(尽管有限)在浏览器中的运行速度总是比依赖 JavaScript 计算的样式快。 然而,CSS 媒体查询不仅仅是为屏幕设置 HTML 样式。 CSS 媒体查询还支持基于打印的查询和网站显示信息的其他方式。 EQCSS 可以与打印样式等媒体查询结合使用,因此无需因为元素查询现在也可以使用而停用媒体查询!

2020愿景进行设计

对于 CSS 的未来,我们能做的最好的事情就是在今天尽可能多地尝试这些想法。 再多的关于这些特性的头脑风暴和理论分析都不会像实际尝试实现它们并投入使用,发现使它们有用和强大的技术一样有用。

除了为元素查询提供解决方案外,EQCSS.js 还有望作为扩展 CSS 的其他实验的平台。 如果您对新的响应条件、新的 CSS 属性或在代码中使用的新选择器有想法,则分叉 EQCSS.js 并对其进行修改以包含您的想法可以让您轻松完成大部分工作。

模块化设计

In designing layouts using element queries, the biggest shift is learning how to stop viewing the DOM from the top down and from the perspective of only the root HTML element, and to start thinking about individual elements on the page from their own perspectives within the document.

The old paradigms of “desktop-first” and “mobile-first” responsive design aren't relevant any longer — the new way of building layouts approaches design “element-first.” Using element queries enables you to work on the individual parts that make up a layout, in isolation from one another, styling them to a greater level of detail. If you are using a modular approach for your back-end code already but have so far been unable to package your CSS with your modules because of the difficulties of styling with media queries alone, then element queries will finally allow you to modularize your styles in the same way.

Thinking Element-First

Element-first design is in the same spirit as the atomic design principle but looks different in practice from how most people have implemented atomic design in the past.

For example, let's say you have some HTML like the following, and the desired responsive behavior can be explained as, “The search input and button are displayed side by side until the form gets too narrow. Then, both the input and the button should be stacked on top of each other and displayed full width.”

 <form> <input type=search> <input type=button value=Search> </form>

Desktop-First Approach

In a desktop-first mindset, you would write styles for the desktop layout first and then add responsive support for smaller screens.

 input { width: 50%; float: left; } @media (max‐width: 600px) { input { width: 100%; float: none; } }

移动优先方法

In a mobile-first mindset, you would design the mobile view first and add support for the side-by-side view only when the screen is wide enough.

 input { width: 100%; } @media (min‐width: 600px) { input { width: 50%; float: left; } }

Element-First Approach

In the first two examples, the media breakpoint was set to 600 pixels, and not because that's how wide the inputs will be when they switch. Chances are, the search input is probably inside at least one parent element that would have margins or padding. So, when the browser is 600 pixels wide, those inputs might be somewhere around 550 or 525 pixels wide on the page. In a desktop-first or mobile-first approach, you're always setting breakpoints based on the layout and how elements show up within it. With an element-first layout, you're saying, “I don't care how wide the browser is. I know that the sweet spot for where I want the inputs to stack is somewhere around 530 pixels wide.” Instead of using a media query to swap that CSS based on the browser's dimensions, with element-first design, we would scope our responsive style to the form element itself, writing a style like this:

 input { width: 100% } @element 'form' and (min‐width: 530px) { $this input { width: 50%; float: left; } }

The code is similar to that of the two previous methods, but now we are free to display this search input anywhere — in a sidebar or full width. We can use it in any layout on any website, and no matter how wide the browser is, when the form itself doesn't have enough room to display the inputs side by side, it will adapt to look its best.

入门资源

EQCSS-Enabled Template

 <!DOCTYPE html> <html> <head> <meta charset="utf‐8"> <title></title> <style></style> </head> <body> <!‐‐[if lt IE 9]><script src="https://elementqueries.com/EQCSS‐polyfills.min.js"></script><![endif]‐‐> <script src="https://elementqueries.com/EQCSS.min.js"></script> </body> </html>

演示

  • 响应纵横比
  • Sticky Scroll Header
  • Blockquote Style
  • 日历
  • 内容演示
  • Counting Children Demo
  • Date Demo
  • Zastrow-style Element Query Demo Demo
  • Flyout Demo
  • Headline Demo
  • Media Player Demo
  • Message Style Demo
  • Modal Demo
  • Nav Demo
  • Parent Selector Demo
  • Pricing Chart Demo
  • Responsive Tables Demo
  • Scroll-triggered Blocker Demo
  • Signup Form Demo
  • Testimonials Block Demo
  • Tweet-Counter Demo
  • JS Variables Demo
  • Responsive Scaling Demo
  • Geometric Design Demo
  • Responsive Order Form
  • Element Query Grid
  • JS Functions in CSS
  • Responsive Content Waterfall

延伸阅读

You can find the EQCSS project on GitHub, demos, documentation and articles on the EQCSS website. An ever-growing number of Codepens use EQCSS, and you can create your own pen by forking the batteries-included template that comes hooked up with EQCSS. You can also play with the EQCSS tool that I built to preview if your EQCSS code is working as expected.

快乐黑客!