新手容易混淆的小 CSS 知识点

Avatar of Chris Coyier
Chris Coyier 发布

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 200 美元的免费额度!

如果您是一位专业人士,很容易忘记在刚开始学习 CSS 时遇到的困惑。 只是为了好玩,让我们尝试回忆一些那些奇怪且令人困惑的时刻。 我先列出一些我记得的以及最近在帮助他人时遇到的随机例子。 然后大家在评论中继续讨论。

这些都不是像 IE 中的布局错误或应该使用哪些供应商前缀这样的大问题。 而是那些小的基础知识,比如语法上的细微差异,却会带来很大的意义变化。

标签限定

这两者有什么区别?

.class    {   }
p.class   {   }

第一个将选择具有该类名的任何元素。 第二个只会选择具有该类名的段落元素。

第一个更通用。 使用该类应用的样式可能对多种类型的元素有用。 即使今天没有,明天也可能会有。 对于浏览器来说,理解和应用它也更快。

很少有情况需要使用第二个示例。 只有当您想对多个元素重复使用相同的类名,但希望它们执行不同操作时才会用到。

p.stand-out { background: yellow; }
span.stand-out { font-weight: bold; }

选择器顺序很重要

为什么它们如此不同?

.class div { color: red; }

div.class  { color: green; }

第一个示例之所以如此不同,是因为 .classdiv 之间存在空格字符。 空格之前的内容和空格之后的内容选择不同的元素。 第一个部分是“选择任何具有此类名的元素”,第二个部分是“选择任何 div”。 将它们与空格放在一起,您将得到“选择任何作为具有此类名的任何元素的后代的 div”。

第二个不涉及任何后代业务。 它是一个像上面讨论的那样的标签限定选择器。

如果上面的 CSS 是页面上唯一的 CSS,则结果将如下所示

<div class="class">
   <h2>
      <div>Would be red</div>
   </h2>
   <div>Would be red</div>
   Would be green
</div>
<div>Would be black</div>

为什么要使用 ID?

就 CSS 而言,使用类和使用 ID 看起来似乎完全相同。

#id    { color: red; }
.class { color: green; }

它只是一个属性,并且根据您使用哪一个,语法上的差异似乎是任意的。 结果是可预测的

<div id="id">Would be red</div>
<span id="id">Would be red</span>

<div class="class">Would be green</div>
<span class="class">Would be green</span>

您可能已经了解到 ID“应该”是唯一的,也就是说,每个页面上只有一个元素使用它。 但是您之前可能犯过错误,而且似乎无关紧要,CSS 仍然可以正常应用。

然后您开始获得相互矛盾的信息。 一些 工具理念 教导说 ID 不适合用于样式化。 一些 文章 告诉您它们是最有效的。 也许您与 JavaScript 开发人员合作,他们告诉您需要在所有内容上使用 ID,因为这使他们的工作变得更容易。

这里充满了困惑。 事实证明,每个人都多少是对的。 以下是事实

  • 就实际应用样式而言,CSS 并不太关心您使用哪一个。 从技术上讲,ID 对浏览器渲染引擎来说更快,但除了最极端的情况外,您可能永远不会注意到速度差异。
  • JavaScript 非常关心 ID。 JavaScript 通过 ID 查找元素的速度明显更快。 这就是“唯一性”非常重要的原因。 JavaScript 只会找到具有该 ID 的“第一个”元素,因此,如果您在页面上有多个,可能会导致混乱。
  • ID 具有比类更高的 特异性值。 如果一个元素同时具有 ID 和类,并且两者都应用了样式,则 ID 应用的样式将优先于类应用的样式。 这可能很有用,也可能是一个障碍。

我个人的理念是在绝对知道只有一个不会从与其他元素共享的类名属性中受益的内容上使用 ID。

隐藏的悬停效果

这里发生了什么?

div           { color: red; }
div:hover div { color: green; }

:hover 是一个选择器,只有当鼠标悬停在特定元素上时才会应用自身。 奇怪的是,您不一定非要将样式应用于正在悬停的元素。 在这种情况下,我们只在父 div 悬停时将样式应用于后代 div。 所以

<div>

   I will be red all the time

   <div>
      I will be red, unless that top
      div is hovered (but not necessarily me)
      and then I'll be green.
   </div>

   I will be red all the time

</div>

空格符无关紧要

这个

div{color:red}

与这个完全相同

div            {
      color       :       red

}

您确实需要在选择器中使用空格来创建后代选择器(例如 ulli { }ul li { } 完全不同),但除此之外,您可以根据使查看和使用 CSS 更舒适的方式使用空格。

请注意上面示例中缺少的分号。 如果它是组中的最后一个属性,则可以省略它。 我个人从不这样做,因为如果您稍后添加更多属性/值并忘记在上一行添加分号,就会出现问题。 因为空格是如此自由,它会继续将下一行读取为上一行值的组成部分。

问题示例

div {
  -webkit-border-radius: 10px
  -moz-border-radius:    10px
  border-radius:         10px
}

空格是可以的。 最后一个没有分号是可以的。 但是前两个属性/值对没有分号,并且会完全搞砸并且无法工作。

属性覆盖

div 将具有什么字体大小?

div {
   font-family: Sans-Serif;
   font-size: 18px;
   font-weight: bold;
   font-style: italic;
   color: red;
   margin: 0 0 20px 0;
   font-size: 21px;
   padding: 10px;
}

将是 21px。 您不小心列出了两次,第二个将获胜。

CSS 文件中的顺序很重要

如果您有两个具有完全相同特异性的选择器,如下所示

.red   { color: red; }
.green { color: green; }

然后它们应用于相同的元素,CSS 中后面的选择器将始终获胜。 HTML 中的类名顺序无关紧要

<div class="red green">Will be green</div>
<div class="green red">Will be green</div>

什么是语义类名?

前面的示例使用“red”和“green”作为类名。 这不是很有语义。 为什么不呢? 这是一个很大的话题,留到下周讨论! 大概吧!