Published on

通过例子来学习CSS组合器

Authors
  • avatar
    Name
    祝你好运
    Twitter

CSS的组合器并不是很好学习,我认为最好的学习方法就是通过一些例子,最好是在实际开发中可能会遇到的例子来学习。

组合器概览

首先要说明,组合器并不是选择器,它只是用来组合选择器的,所以叫组合器(combinator)。

后代组合器(Descendant combinator)

  • (空格)组合器,选择前一个元素的后代节点
  • > 直接子代组合器(Child combinator),选择前一个元素的直接后代节点
  • + 紧邻兄弟组合器(Adjacent sibling combinator),选择相邻元素,即后一个元素紧跟在前一个之后,并且共享同一个父节点。
  • ~ 一般兄弟组合器(General sibling combinator),选择兄弟元素,也就是说,后一个节点在前一个节点后面的任意位置,并且共享同一个父节点。罗里吧嗦说这么多就是为了强调,不需要挨着,不像上面的紧邻兄弟组合器

组合器使用举例

需求

纵向排列一些div,这些div中间需要有8px的间隙,但是第一个div距离顶部不要有空隙。这其实是一个很常见的需求,实现方法也有很多,这里主要是演示用CSS的组合器来做。

为了方便我们使用如下的HTML结构:

<div class="container">
  <div class="row">
  line 1
  </div>
  <div class="row">
  line 2
  </div>
  <div class="row">
  line 3
  </div>
</div>

同时为了方便观察,我们给他们加上边框和背景色:

.container {
  border: 1px solid black;
}

.row {
  background-color: lightblue;
}

现在的效果如图:

initial-effect-of-divs

我们想要的效果:

initial-effect-of-divs

方法一 紧邻兄弟组合器

我们只需要给.row加上.row + .row选择器,就可以选中除了line 1以外的row,也就是line 2line 3,代码看这里

如果我们的这些row中间有空的div(或者别的元素)怎么办?

方法二 一般兄弟组合器

写法跟上面类似,但是~不要求前后节点紧挨着,所以也就不会有上面那个害怕中间有空div的情况:.row ~ .row,代码看这里

方法三 直接子代组合器+伪类选择器

这里需要两步,一步是为row添加margin-top: 8px,第二步就是为最上面的row清除margin-top,代码看这里

当然这里选择第一个row,可以像上面代码中那样用first-of-type,可以用first-child,也可以用nth-child(1)(注意这里的下标是从1开始的)。

参考:

  1. CSS 选择器
  2. :nth-child
  3. What does the “~” (tilde/squiggle/twiddle) CSS selector mean?
  4. https://stackoverflow.com/questions/2094508/is-there-a-css-selector-for-the-first-direct-child-only
  5. CSS Child vs Descendant selectors
  6. Add space between HTML elements only using CSS