[译]原生CSS嵌套使用

news2024/11/23 0:56:30

本文翻译自 CSS Nesting,作者:Ahmad Shadeed, 略有删改。

如果你是一个前端开发人员,那么你应该使用过CSS预处理器以及预处理器中的嵌套特性。它一直是一个受欢迎的功能,我一直都在使用CSS预处理器。

今年所有的主流浏览器都支持原生CSS嵌套:Chrome、Firefox和Safari。这是一个重要的CSS功能,这将使编写CSS更加容易。在本文中我将记录到目前为止我所学到的关于CSS嵌套的知识,并与您分享我的发现,包括使用案例和示例。

介绍

CSS嵌套是许多开发人员期待已久的功能之一。我们曾经依赖于CSS预处理器,如Sass或Less。让我们来回顾一下以前的做法:

请看下面的例子。我们有一个图标嵌套在选择器.nav__item中。

.nav__item {
  .icon {
    display: flex;
    padding: 1rem;
  }
}

以上是一个Sass语法的代码。编译后,它在浏览器中看起来像下面这样:

.nav__item .icon {
  display: flex;
  padding: 1rem;
}

使用原生CSS嵌套,相同的CSS将按原样工作。这里有一个图,显示了原生CSS嵌套和浏览器DevTools之间的比较。

请注意浏览器显示CSS的方式与CSS代码中的显示方式几乎一致。

如果这个CSS是用Sass编译的,浏览器会显示如下:

CSS嵌套的好处

在我看来,嵌套 CSS 有一些很合理的理由,使其变得有用:

  • 更容易阅读CSS
  • 风格一致
  • 确定特定样式的作用域
  • 对没有类或ID的HTML元素添加样式

CSS嵌套规则

为了让你了解CSS嵌套,我将尝试提供不同CSS问题的案例,以及嵌套如何帮助解决这些问题。

首先,你需要学习与符号&。有多数情况下,这个符号是必要的。

嵌套没有类或ID的元素

在这个例子中,<a>元素是通过.nav__item设置样式。要使CSS有效,使用&符号是可选的。

nav__item {
  & a {
    display: block;
    padding: 1.5rem 1rem;
  }
}

/* 等同于 */
.nav__item a {
}

您也可以选择不使用&符号:

.nav__item {
  a {
    display: block;
    padding: 1.5rem 1rem;
  }
}

/* 等同于 */
.nav__item a {
}

请注意这是一个最近的更新,被称为宽松的CSS嵌套。它适用于最新的Chrome Canary和Safari技术预览版。

使用类嵌套元素

以前面的例子为例,但假设<a>元素有一个HTML类。

.nav__item {
  .link {
    display: block;
    padding: 1.5rem 1rem;
  }
}

/* 等同于 */
.nav__item .link {
}

这里不需要使用&,只有类名称也正常生效。

嵌套CSS组合器

CSS原生嵌套的一个好处是可以使用组合器。让我们来看一些例子。

在下面的例子中,我想选择.nav__item的每个元素,它前面有另一个具有相同类的元素。因此我使用了相邻兄弟选择器。

在原生CSS嵌套中,我们可以使用&符号来模拟这种效果。请注意我重复使用了它两次。

.nav__item {
  & + & {
    border-left: 2px solid;
  }
}

魔术发生在第二次重复的&。在这里浏览器将理解我想使用相邻的兄弟选择器。让我给你看一个图表来说明这一点:

另一个例子是嵌套子组合器。它可以选择元素的直接子元素。

.nav__item {
  > a {
    padding: 1rem;
  }
}

嵌套示例:Active, Focus, Hover

:active:focus:hover是通过用户操作激活的CSS伪类。

使用CSS嵌套,可以一次嵌套它们以避免代码重复。让我们以:hover为例:

button {
  &:hover {
    background-color: var(--bg-color);
  }

  &:focus {
    outline: solid 2px;
  }
}

使用预处理器进行嵌套时的区别在于浏览器将像这样渲染它:

button:hover {
  background-color: var(--bg-color);
}

button:focus {
  outline: solid 2px;
}

让我们来看看原生CSS嵌套在Chrome、Safari和Firefox中是如何呈现的。

嵌套示例:Post Content

第一个尝试CSS嵌套的例子之一是对帖子的正文内容设置样式。想象一下,一篇文章有正文标题、文本、图像、引用等等。

标题

我们倾向于像下面这样设计标题:

.post-content h1,
.post-content h2,
.post-content h3,
.post-content h4 {
  /* styles here */
}

使用CSS嵌套,它更简单:

.post-content {
  h1,
  h2,
  h3,
  h4 {
    color: var(--heading-color);
    font-weight: var(--heading-font-bold);
    margin-bottom: var(--size-2);
  }
}

我们也可以使用:is()选择器来做同样的事情。

.post-content {
  :is(h1, h2, h3, h4) {
    color: var(--heading-color);
    font-weight: var(--heading-font-bold);
    margin-bottom: var(--size-2);
  }
}

段落元素

一个常见的情况是设置段落内部的链接样式。在这种情况下,CSS的嵌套功能非常好用。

.post-content {
  & p {
    color: var(--color-black);

    & a {
      font-weight: bold;
      text-decoration: underline;
    }
  }
}

链接可能也需要悬停或焦点效果。

.post-content {
  & p {
    color: var(--color-black);

    & a {
      font-weight: bold;
      text-decoration: underline;

      &:hover {
        /* hover styles */
      }
    }
  }
}

我们还可以用在嵌套媒体查询。

.post-content {
  & p {
    /* base styles */

    @media (min-width: 400px) {
      /* do something */
    }
  }
}

帖子图片

帖子图包含一个图像和一个可选的<figcaption>来显示图像的描述。

在我的示例中,如果<figure>有标题,我需要对它进行不同的样式设置。可以通过嵌套CSS :has() 实现。

.post-content {
  & figure {
    & img {
      /* the figure's image styles */
    }

    /* changes to the <figure> container, if it has a figcaption element */
    &:has(figcaption) {
      display: flex;
      align-items: start;
    }

    & figcaption {
      /* caption styling */
    }
  }
}

文章列表

我需要为所有列表项添加边框,除了最后一个。为此,我使用了:not()选择器。

.post-content {
  li {
    &:not(:last-child) {
      border-bottom: 1px solid;
    }
  }
}

要使用:not(),我们需要在它前面附加一个&符号。

自定义标题间距

如果<h3><h4>之后是代码片段,我需要减少它们下方的间距。

.post-content {
  & h3 + [class*="language-"],
  & h4 + [class*="language-"] {
    margin-top: 0.5rem;
  }
}

嵌套示例:卡片组件

我将演示一个简单的卡片组件,它使用CSS嵌套来实现所需的样式。

假设有一个默认或基本样式的.card元素,我将继续演示CSS嵌套的使用。

.card {
  /* default card styles */
}

如果容器宽度大于400px,我希望卡片成为一个Flex容器。

.card {
  /* default card styles */

  /* if the container width is 400px or bigger */
  @container card (min-width: 400px) {
    display: flex;
  }
}

嵌套示例:表单输入

一种常见的情况是对输入的占位符进行样式设置。问题是每个浏览器都有自己的前缀。

由于前缀样式需要一个双冒号,我们需要使用与号&,否则样式将中断。

input {
  --placeholder-color: #969696;
  /* other styles */

  &::-webkit-input-placeholder {
    color: var(--placeholder-color);
  }

  &::-moz-placeholder {
    color: var(--placeholder-color);
    opacity: 1;
  }

  &:-moz-placeholder {
    color: var(--placeholder-color);
  }
}

我在探索CSS嵌套时发现的错误

使用不带&号的通用选择器

假设我们有一张卡片,我们想选择其中的所有元素。使用CSS原生嵌套,这应该可以工作:

.card {
  * {
    /* styles here */
  }
}

我发现这在Chrome稳定版中不起作用,但在Chrome Canary 121、Safari 17.1和Firefox 119中工作正常。

.card {
  & * {
    /* styles here */
  }
}

使用不带&号的自定义属性

在这个问题中,选择一个不带&号的自定义属性将不会呈现预期的结果。

.card {
  [data-type="featured"] {
    /* styles here */
  }
}

我发现这在Chrome稳定版中不起作用,但在Chrome Canary 121、Safari 17.1和Firefox 119中工作正常。

为了解决这个问题,我们需要附加一个&符号:

.card {
  &[data-type="featured"] {
    /* styles here */
  }
}

这两个bug都在Chrome Canary中的宽松CSS嵌套版本中得到了修复。

检测CSS嵌套支持

可以使用@supports来检查CSS嵌套支持。在我们的例子中,我们想检查浏览器是否识别&可以使用以下代码。

@supports selector(&) {
  .post-content {
    & h2 {
      /* styles here. */
    }
  }
}

对我来说,现在还在使用PostCSS嵌套插件,它将原生CSS嵌套编译为普通CSS。一旦它可以安全的使用后,就可以不再使用插件了。

结论

CSS嵌套是一个重要的功能,它将增强我们编写CSS的能力。目前使用嵌套是可行的,但需要注意受众情况,因为目前对支持程度仍然较新。


看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~

专注前端开发,分享前端相关技术干货,公众号:南城大前端(ID: nanchengfe)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1288444.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

zabbix6.4监控交换机发现ICMP报错Ping item must have target or host interface specified

报错信息&#xff1a; 查看监控项&#xff1a; 修改键值&#xff1a; 保存再次检查&#xff0c;发现又报错/usr/sbin/fping: [2] No such file or directory 原因是&#xff0c;zabbix-server上没有安装fping工具 解决方法&#xff1a;yum install fping -y 之后数据采集正常…

网络安全等级保护V2.0测评指标

网络安全等级保护&#xff08;等保V2.0&#xff09;测评指标&#xff1a; 1、物理和环境安全 2、网络和通信安全 3、设备和计算安全 4、应用和数据安全 5、安全策略和管理制度 6、安全管理机构和人员 7、安全建设管理 8、安全运维管理 软件全文档获取&#xff1a;点我获取 1、物…

Java 控制台命令导入本地jar包到maven本地库中

1、新建POM文件&#xff0c;在maven库路径下创建POM文件 注意&#xff1a;这个路径需要与第2点导入命令中的grouoId、artifactId和version写法对应 Path&#xff1a;D:\RomanData\repository\com\sae\mail\1.0.0\mail-1.0.0.pom <?xml version"1.0" encoding&q…

公募REITs交易规则详解

普通投资者是否可以参与基础设施公募REITs交易&#xff1f; 基础设施公募 REITs 采取封闭式运作,符合法定条件并经交易所依法审核同意后&#xff0c;可以上市交易。基础设施公募 REITs 的认购和交易实施适当性管理制度。尽管对普通投资者参与基础设施公募 REITs 的认购和交易没…

intel AX201 网卡驱动报错56解决办法,亲测解决

&#xff08;这是我已经解决了网卡驱动问题&#xff0c;来这里发一篇博客&#xff0c;方便大家之后也掉驱动&#xff0c;找办法修复&#xff09; 笔记本不知道为什么&#xff0c;开机忽然报错了&#xff0c;找了好多办法都没解决&#xff0c;最后在看了其他大神的博客之后解决…

2022年第十一届数学建模国际赛小美赛A题翼龙如何飞行解题全过程文档及程序

2022年第十一届数学建模国际赛小美赛 A题 翼龙如何飞行 原题再现&#xff1a; 翼龙是翼龙目中一个已灭绝的飞行爬行动物分支。它们存在于中生代的大部分时期&#xff1a;从三叠纪晚期到白垩纪末期。翼龙是已知最早进化出动力飞行的脊椎动物。它们的翅膀是由皮肤、肌肉和其他组…

【踩坑记录】from natten import NeighborhoodAttention1D

在配置forecast-mae环境的时候。 ./forecast-mae/src/model/layers/agent_embedding.py文件中 导入包的时候from natten import NeighborhoodAttention1D 报错&#xff0c; 解决办法&#xff0c;默认安装的是__version__ "0.14.2"版本的 出现这个问题可能是包损坏…

介绍一款在线文件格式转换工具

原因: 今天要将一个pdf格式的文件转为docx格式,结果我用破解版的WPS无法再不登录的情况下转换,所以就搜索了一款在线工具实现功能。 网站地址: Convertio — 文件转换器 使用流程: 1)选择要转换的文件 2)选择要转换的格式 3)点击转换 4)等待上传 5)等待转换 6)下载到本地

易点易动设备管理系统--提升设备备品备件管理效率的工具

设备备品备件管理是市场推广人员关注的重要问题之一。为了帮助市场推广人员提升设备备品备件管理效率&#xff0c;易点易动设备管理系统应运而生。本文将详细介绍易点易动设备管理系统的功能和优势&#xff0c;以及如何借助该系统提高设备备品备件管理效率&#xff0c;提升企业…

uniapp使用vue-i18n国际化多国语言

前言&#xff1a;uniapp是自带有i18n这个插件的&#xff0c;如果没有npm安装即可 此插件需要自己去给每一个需要国际化的字符去手动配置key&#xff0c;所以如果是已经完成的项目可能工作量就稍微有点大了 第一步&#xff1a; 语言命名是有规范的不能乱取名&#xff0c;具体可…

【SpringCloud】通过Redis手动更新Ribbon缓存来解决Eureka微服务架构中服务下线感知的问题

文章目录 前言1.第一次尝试1.1服务被调用方更新1.2压测第一次尝试1.3 问题分析1.4 同步的不是最新列表 2.第二次尝试2.1调用方过滤下线服务2.2压测第二次尝试2.3优化 写到最后 前言 在上文的基础上&#xff0c;通过压测的结果可以看出&#xff0c;使用DiscoveryManager下线服务…

springboot——自动装配

自动装配 Condition: Condition内置方法&#xff1a;boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata)&#xff0c;返回值为布尔型 重写matches方法的类&#xff1a;SpringBootCondition等 SpringBootCondition&#xff1a;springboot自带的实现类…

4.数据库

目录 一、数据库的基本信息 1.1 数据库的定义 1.2数据库的分类 1.2.1 关系型数据库 1.2.2 非关系型数据库 1.3 SQL介绍 1.3.1 概念 1.3.2 SQl语言分类 1.3.3 SQL注释 1.3.4 数据库操作命令DDL 1.3.5 数据表操作命令DDL 1.3.6 数据表操作命令DML 1.3.7 数据表中内容…

电容电感特性的理解

04730电子技术基础 语雀 在前面&#xff0c;我们提到过电容元件具有隔直通交&#xff0c;通高阻低的特性&#xff0c;电感元件具有隔交通直&#xff0c;通低阻高的特性。那么如何理解这两句话呢&#xff1f;下面我们一一剖析 电容元件的隔直通交&#xff0c;通高阻低的特性 …

Faster Transformer

Faster Transformer FasterTransformer包含transformer块的高度优化版本的实现&#xff0c;该块包含编码器和解码器部分。基于高效率的开发语言和工具&#xff1a; C, CUDA, cuBLAS and cuBLASlt支持的模型数据格式&#xff1a;FP32, FP16, BF16, INT8 (limited models) and F…

智能优化算法应用:基于人工水母算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于人工水母算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于人工水母算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.人工水母算法4.实验参数设定5.算法结果6.参考…

C语言-详解指针

目录 一.内存 1.内存的定义 2.内存的结构图 二.地址 1.什么是地址 2.什么是变量的地址 三.什么是指针 1.指针的定义 四.如何获取数据存储空间的地址 1.&运算符 五.指针变量 1.什么是指针变量&#xff08;一级指针变量&#xff09; 2.指针变量的定义 3…

Opencv库如何检测图片中鸡蛋数量

Opencv库检测图片中鸡蛋数量 由于需要写一个检测鸡蛋数量的程序&#xff0c;用了几个opencv中的经典方法&#xff0c;实现了图片中鸡蛋的检测。在一步步实现的同时&#xff0c;同时说明每个方法的用途。希望能给学习opencv的小伙伴一些帮助。下图为原始图和实现后的检测边框。…

ubuntu20.04找不到#include<opencv/cv.h>文件

编译ROS包的时候出现错误&#xff1a;fatal error&#xff1a;opencv/cv.h : No such file or directory #include<opencv/cv.h> 查看opencv4版本&#xff1a; pk-config --modversion opencv4: 在opencv4中opencv2的cv.h融合进了imgproc.hpp里: 把源码中的#include …

字节跳动开源基于SD1.5的 MagicAnimate 一张照片秒变真人舞蹈视频

项目地址&#xff1a;https://github.com/magic-research/magic-animate 显卡要求&#xff1a;12G MagicAnimate是一项利用先进的扩散模型实现人体图像动画的创新性项目。其核心优势在于确保生成内容的时间一致性&#xff0c;通过提供预训练的稳定扩散V1.5和MSE微调的VAE基础…