为啥CSS不会支持双斜杠(//)注释?

更新日期: 2023-06-12阅读: 1.4k标签: 注释

众所周知,css 仅支持多行注释,也就是/**/注释

/* 这是CSS注释 */
div{
  color: red;
}

习惯了 SCSS或者LESS这些预处理器的同学,肯定非常希望有双斜杠注释

// SCSS注释
div{
  color: red; // SCSS注释
}

很明显这种写法要比/**/简洁的多,那么,为啥官方迟迟不支持双斜杠注释呢?

下面就来探讨一下这个问题以及关于 CSS 语法的一些思考。


一、语法冲突

CSS 中大部分属性和值都比较简单,乍一看,好像没有什么语法有双斜杠//,其实不然,只是非常少,但并不是没有。

举个例子,下面是border-image的一些写法

/* source | slice */
border-image: linear-gradient(red, blue) 27;

/* source | slice | repeat */
border-image: url("/images/border.png") 27 space;

/* source | slice | width */
border-image: linear-gradient(red, blue) 27 / 35px;

/* source | slice | width | outset | repeat */
border-image: url("/images/border.png") 27 23 / 50px 30px / 1rem round space;

看到第 4 中语法没,出现了两个斜杠,关键是,两斜杠中间的width还可以省略,这一点从border-image的语法规范可以看出

border-image = 
  <'border-image-source'>                             ||
  <'border-image-slice'> [ / <'border-image-width'> | / <'border-image-width'>? / <'border-image-outset'> ]?  ||
  <'border-image-repeat'>   

看到<'border-image-width'>后面的问号没?这个就表示可选的意思,所以理论上border-image可以有以下的写法

border-image: 0//0;

这种写法其实等同于

border-image-source: none;
border-image-slice: 0;
border-image-width: 1;
border-image-outset: 0;
border-image-repeat: stretch;

我们可以打开控制台来验证一下这个语法的合法性


可以看到,这种写法完全是有效的(暂不考虑实际功能)

所以,双斜杠语法可能会造成语法冲突

还有一个和border-image比较像的属性,叫做-webkit-mask-box-image,也可以实现双斜杠语法

-webkit-mask-box-image - CSS: Cascading Style Sheets | MDN (mozilla.org)
-webkit-mask-box-image: 0//0;

不过这种毕竟是小部分,如果有新规范,也很容易规避这个问题。更要命的其实是下面这个原因,如果要是支持了,可能会让以前的CSS规范全部崩塌!


二、无法兼容现版本

为啥说这个问题更大呢?我们可以换个角度来思考,如果现在CSS支持了双斜杠语法会怎么样?

举个例子:

<div>CSS COMMENT</div>

下面加了一行注释

div{
  font-size: 30px; // 字号
  background-color: yellow;
  color: blue;
}

如果浏览器支持这个特性,那非常符合直觉,那如果浏览器不支持(现阶段),你觉得最终的样式是?

A. 30px字号,黄色背景,蓝色文字
B. 30px字号,蓝色文字
C. 黄色背景,蓝色文字
D. 蓝色文字
E. 全部不生效,默认样式

思考两分钟...答案是 B,你猜对了吗?

为啥会这样呢?这要“归功”于 CSS 强大且精准的“容错”解析规则:

CSS 解析中并不存在换行规则,每个属性和对应值通过分号;区分,在选择器内部,如果碰到非法语句,则会依次寻找到下一个;为止,也可以通过{}进行分块区分。

上面这一段是我自己总结的一套规则,可能还是有些不好理解,拿上面那个例子来说,你可以把两行连起来看,实际上等同于

div{
  font-size: 30px; 
  // 字号 background-color: yellow;
  color: blue;
}

也就是// 字号 background-color当成了一个新的属性,但是这个属性无效,所以最终的表现就是30px字号,蓝色文字

这样就带来了一个非常严重的问题,在不支持注释的浏览器上产生了不符合预期的解析错误,也就是说,一般的不兼容语法只是不起作用,但是这种注释却影响到了其他样式,这才是最要不得的


三、注释的其他写法

再来看一些常见的注释写法,看看有什么副作用

<div>CSS COMMENT</div>

首先是最常见的注释

div{
  // font-size: 30px; 
  background-color: yellow;
  color: blue;
}

这种写法其实是符合预期的,在目前阶段也是可以正常解析,因为//会向后找到第一个;,也就是整行 // font-size: 30px; 无效

然后是这种注释

div{
  // 标题
  font-size: 30px; 
  background-color: yellow;
  color: blue;
}

根据前面的分析,其实可以等同于

div{
  // 标题 font-size: 30px; 
  background-color: yellow;
  color: blue;
}

所以第一行就无效了,结果和前面一致

如果需要不影响现有样式,可以在后面加上;,直接终止解析,如下

div{
  // 标题;
  font-size: 30px; 
  background-color: yellow;
  color: blue;
}

然后是选择器外面的写法

<div>CSS COMMENT</div>
<p>CSS COMMENT</p>
// 标题 
div{
  font-size: 30px; 
  background-color: yellow;
  color: blue;
}
p{
  color: red
}

这种会如何解析呢?

其实你可以将这个注释想象成一个选择器,也就是和下面的div连起来了

// 标题 div{
  font-size: 30px; 
  background-color: yellow;
  color: blue;
}
p{
  color: red
}

由于并不存在// 标题 div这样的选择器,并且也不是一个合法的选择器(斜杠需要转义),所以整个DIV样式完全无效,但并不影响后面选择器(p)的样式


如果需要不影响现有样式,需要在后面加上{},告诉浏览器这是一个区块,如下

// 标题{}
div{
  font-size: 30px; 
  background-color: yellow;
  color: blue;
}
p{
  color: red
}


四、CSS 语法其实从未改变

CSS 发展这么多年,各种属性和新特性层出不穷,其实最核心的语法规则从未改变过,这也是设计之初就决定好的。

像之前出现的CSS变量

:root{
  --c: red;
}

本质上其实就是一个特殊的属性,即便旧浏览器不支持也不会有其他影响,就相当于不存在一样。

这也是为啥 CSS 为何不能像 SASS 那样直接将语法放在最外层,就像这样

--c: red;
div{
  color: var(--c)
}

如果按照 CSS 的解析规则,必然导致连同下面的 div样式整体失效

还有一些@符号的新语法,例如@property

@property --speed{
  syntax: '<number>';
  inherits: false;
  initial-value: 0;
}

其实从结构上来讲,和@font-face并没有什么区别

@font-face {
  font-family: "Trickster";
  src: xxx;
}

或者说也满足下面这种更通用格式

选择器 {
  属性1: 值;
  属性2: 值;
}

所以即使不支持,也不会影响其他 CSS 语句。再想想看,有什么新特性会让其他样式“挂掉”?


五、最后总结一下

这下大概能明白为啥不支持双斜杠语法了吧,以上就是关于CSS语法的一些思考了,相信大家对 CSS 的语法又有了一个新的认识,下面总结一下

  1. 有部分属性值会出现双斜杠语法,比如border-image、-webkit-mask-box-image
  2. 不支持双斜杠注释最主要的原因是无法兼容现版本,会对现有 CSS 带来副作用
  3. 为了兼容现有版本,CSS 新特性不能影响其他 CSS 语句,语法规则也从未改变过

可以肯定地说,CSS 以后也不会有双斜杠注释的规则。另外,本文的很多观点和结论都是归纳总结而来,并没有追究官方资料,可能有少许不准确或者有误的地方,欢迎评论区赐教。

欢迎关注我的公众号:前端侦探
原文:https://segmentfault.com/a/1190000043885414


链接: https://fly63.com/article/detial/12508

php代码中注释的含义

最近在梳理和优化手上的项目代码,这个项目已经走过好几任了,每一任的开发人员多多少少都有一些差异和各自的习惯,所以代码逻辑和写法上都有点【乱】。在代码中,注释是一个非常重要的信息

HTML 注释 和 实体字符

在HTML中还有一种特殊的标签——注释标签。如果需要在HTML文档中添加一些便于阅读和理解但又不需要显示在页面中的注释文字,就需要使用注释标签

条件注释的两种形式_下层隐藏与下层显示

条件注释 (conditional comment) 是于HTML源码中被 Microsoft Internet Explorer 有条件解释的语句。条件注释可被用来向 Internet Explorer 提供及隐藏代码。条件注释最初于微软的 Internet Explorer 5浏览器中出现

JS正则与注释的冲突

最近在写一款前端组件的时候,无意发现正则与注释之间的一点冲突,现分享下。猜测应该是正则没有使用引号,导致JS解析时将正则里边的*/做为了注释的结尾。

html代码中如何写注释?

HTML中的注释通常用于解释标记。在编辑源代码时,它将帮助您和其他人快速轻松地选择或查找文档中的特定部分;浏览器不会显示注释。那么如何在html代码中如何写注释?下面本篇文章就来给大家介绍一下,希望对大家有所帮助

javascript注释有几种?

代码注释对长久维护的项目来说很重要,随着前端代码逻辑日趋复杂,合理的文档注释能提高维护开发效率。尤其在多人团队中,良好的注释能降低沟通成本。

html注释代码怎么写?

HTML注释:不被程序执行的代码。用于程序员标记代码,在后期的修改,以及他人的学习时有所帮助。对关键代码的注释是一个良好的习惯。在开发网站或者功能模块开发时,代码的注释尤其重要。

如何在javascript中添加注释?

代码注释对长久维护的项目来说很重要,随着前端代码逻辑日趋复杂,合理的文档注释能提高维护开发效率。尤其在多人团队中,良好的注释能降低沟通成本。

如何写好代码注释?

对于代码注释来说,在不同的教程或者原则中有不同的规定或者解释。有的原则是需要使用 JavaDoc 来描写每个方法,而有的原则是要求每一个属性标注命名

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!