首页 > 代码库 > 使用CSS兄弟选择器完成复杂垂直边距(vertical margins)的设置

使用CSS兄弟选择器完成复杂垂直边距(vertical margins)的设置

—相邻的sibling选择器如何在完成复杂设计要求的同时,保持可读的CSS

这是web前端开发任务中开始简单,但是在过程中变的复杂的一个例子:将一篇文章中的所有元素应用垂直边距(vertical margins),例如由复杂markdown编译来的博客文章。

大多数情况下,你必须要处理很多例外和相关,比如:标题和图片上下通常需要更多空白,但是如果两个图片上下挨着,那两图间空白就改变少。h2标签和h3标签直接的距离要比两个h2之间要小。

当原作者几年前刚开始做前端的时候,所有这些异常和依赖关系总是导致复杂的代码,视觉不一致和意想不到的行为。google了好多回为啥margin-top不起作用。

第一步

一篇简单的html如下:

<article class="article">
  <h1>Hello World</h1>
  <p>Lorem ipsum dolor sit amet</p>
  <p>Lorem ipsum dolor sit amet</p>
  <img src="…" alt="…">
  <p>Lorem ipsum dolor sit amet</p>
  <ul>
    <li>Lorem</li>
    <li>Ipsum</li>
    <li>Dolor</li>
  </ul>

我通常拿出两段来调整它们之间的垂直边距,达到预期效果后,使用该值作为所有元素的基础边距。

.article > * + * { 
    margin-top: 1.5rem;
}

上述css代码给.article中全部有相邻兄弟元素的子元素添加margin-top。只给直系元素添加margin-top属性避免了不想要的效果,比如上述html中ul将被添加margin-top,而不是li。

http://codepen.io/sebastianeberlein/pen/JWqbpX

技术分享

第二步

在这一步中会添加更具体的css规则,如:

.article > img + * { 
    margin-top: 3rem;
}

img之后的任何元素都会接收到特定的margin-top,效果类似于直接向img应用margin-bottom。 但是使用相邻的兄弟选择器和边缘顶部有两个优点:

1.不必从最后一个子进程中删除margin-bottom

2.并避免折叠边距( collapsing margins.)

http://codepen.io/sebastianeberlein/pen/yMWVKr

技术分享

 

第三步

在此步骤中,将规则添加到特定元素,例如:

.article > * + h2 { 
    margin-top: 4rem;
}
.article > * + img { 
    margin-top: 3rem;
}

有相邻兄弟的h2和img,会收到一个特定的margin-top。 

http://codepen.io/sebastianeberlein/pen/aJrBGd

技术分享

第四步

在这最后一步中我处理有特殊相关性的样式

.article > img + img { 
    margin-top: 1rem; 
}

改变相邻图片间的距离

http://codepen.io/sebastianeberlein/pen/vxwyjJ

技术分享

如果需要还可以添加精确的css选择器,如:

.article > img + img + img + h2 { 
    margin-top: 5rem;
}

如果一个h2排列在在连续三个图像,它会收到一个特定的margin-top。 幸运的是,这这只是一个特殊案例, 但是很高兴知道相邻的兄弟选择器可以解决这种复杂的依赖问题。

高级使用

为了提高可读性,使用(SCSS)嵌套并将每条规则写入一行。 不用对具有相同值的选择器进行分组,因为CSSO会在之后构建任务中处理它。

.article {
    > * + * { margin-top: 1.5rem }
    > h2 + * { margin-top: 1rem }
    > img + * { margin-top: 3rem }
    > * + h2 { margin-top: 4rem }
    > * + h3 { margin-top: 3.5rem }
    > * + img { margin-top: 3rem }
    > img + img { margin-top: 1rem }
    > h2 + h3 { margin-top: 4.5rem }
}

这种技术也适用于SASS或CSS,例如基线网格。 如果所有margin都是是一个指定margin变量计算的,只需要更改该变量来增加或减少整体空白。

http://codepen.io/sebastianeberlein/pen/NpVbMO

结论

一般开发的网站通常有非常复杂的文章,不仅包括编译的降序,还包括类别标题,简介文本或嵌套布局等元素。
使用相邻的兄弟选择器和唯一的边框顶部可以帮助我解决复杂的设计要求,同时保持可理解的CSS规则。 方便稍后再添加或调整规则。

英文原文:https://hackernoon.com/advanced-vertical-margins-4ac69f032f79

使用CSS兄弟选择器完成复杂垂直边距(vertical margins)的设置