-------------------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

结论  

  一般开发的网站时会遇到非常复杂的文章,通常包括类别标题,简介文本或嵌套布局等元素。使用相邻的兄弟选择器和唯一的margin-top可以在解决复杂的设计要求的同时保持CSS可理解, 方便之后再添加或调整规则。

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

使用CSS兄弟选择器完成复杂垂直边距(vertical margins)的设计的更多相关文章

  1. css兄弟选择器,+ ~选择器的区别

     壹 ❀ 引 实习生在写搜索框下拉提示时,遇到了不知道怎么解决的问题,所以来问我.效果不难,鼠标选中输入框(focus)时,展示搜索关键字相关提示,看了眼dom结构是这样的: 在她的理解里面,选中父元 ...

  2. CSS后代选择器、子元素选择器、相邻兄弟选择器区别与详解

    派生选择器用的很多,派生选择器具体包括为后代选择器.子元素选择器.相邻兄弟选择器,我们来理解一下他们之间的具体用法与区别. 1.css后代选择器语法:h1 em {color:red;} 表示的是从h ...

  3. 理解css相邻兄弟选择器

    今天在菜鸟教程看到了css组合选择符的“相邻兄弟选择器”,刚开始对这个概念有些不太理解,通过查阅资料并且经过一些试验总算有了些头绪. 原文解释是“相邻兄弟选择器(Adjacent sibling se ...

  4. 前端学习笔记之CSS后代选择器、子元素选择器、相邻兄弟选择器区别与详解

    派生选择器用的很多,派生选择器具体包括为后代选择器.子元素选择器.相邻兄弟选择器,我们来理解一下他们之间的具体用法与区别. 1.css后代选择器语法:h1 em {color:red;} 表示的是从h ...

  5. CSS系列之后代选择器、子选择器和相邻兄弟选择器

    后代选择器比子选择器的范围大,包含子选择器,且包含子选择器的“子孙”选择器,后代选择器使用"空格"符号间隔选择器 子选择器:子选择器只是父选择器的一级子元素,使用"> ...

  6. CSS 相邻兄弟选择器

    相邻兄弟选择器(Adjacent sibling selector)可选择紧接在另一元素后的元素,且二者有相同父元素. 选择相邻兄弟 如果需要选择紧接在另一个元素后的元素,而且二者有相同的父元素,可以 ...

  7. CSS相邻兄弟选择器

    相邻兄弟选择器定义:选择紧接在另一个元素后的元素,而且两者有着相同的父元素. 代码一:<body> <h1>This is a heading.</h1> < ...

  8. CSS后代选择器,子选择器和相邻兄弟选择器

    平时在代码练习中,经常用到后代选择器,子选择器也会用到,这里做个总结: 1,后代选择器和子选择器区别: ①写法不一样:后代选择器的标识为:空格 如:ul li{width:150px;} [ul和li ...

  9. web CSS的知识- 关于后代选择器,子选择器,兄弟选择器的使用

    1. 后代选择器官方解释:后代选择器可以选择作为某元素后代的元素.理解:选择某一标签的后代中,所有的此标签标记例:ul em {color:red;}就是选择,h1标签后代中中,所有的em.代码如下: ...

随机推荐

  1. 使用new Image()进行预加载

    概述 这篇博文记录了用new Image()进行预加载的总结,供以后开发时参考,相信对其他人也有用. 旧的预加载 一般我们为了让背景图更快的加载,我们常常把背景图放在一个display:none的im ...

  2. Swift5 语言指南(十八) 可选链接

    可选链接是一个查询和调用当前可选的可选项的属性,方法和下标的过程nil.如果optional包含值,则属性,方法或下标调用成功; 如果是可选的nil,则返回属性,方法或下标调用nil.多个查询可以链接 ...

  3. 分布式任务调度系统xxl-job相关问题补充

    搭建xxl-job时可能会遇到的问题 邮箱配置不起作用报异常 以163邮箱为例,接收邮件需要开启POP3/STMP服务 光开启服务还不够,需要添加授权码 授权码为手动输入,可以与登录密码不同,所以服务 ...

  4. Liferay7 BPM门户开发之20: 理解Asset Framework

    Asset框架用于将您开发的门户内容添加Liferay的核心系统功能.打个比方,你开发了一个事件TodoList管理的插件,在列表显示的时候,你可以集成Asset框架,让你的自定义内容支持Tag标签. ...

  5. jQuery操作select下拉框的text值和value值的方法

    1.jquery获取当前选中select的text值 $("#select1").find("option:selected").text(); 2.jquer ...

  6. Python内置类型(6)——生成器

    上节内容说到Python的for语句循环本质上就是通过调用Iterable可迭代对象的__iter()__方法获得一个Iterator迭代器对象,然后不断调用Iterator迭代器对象__next() ...

  7. 课程四(Convolutional Neural Networks),第一周(Foundations of Convolutional Neural Networks) —— 0.Learning Goals

    Learning Goals Understand the convolution operation Understand the pooling operation Remember the vo ...

  8. 函数isNaN() parseFloat() parseInt() Math对象

    isNaN() 定义和用法 isNaN() 函数用于检查其参数是否是非数字值. isNaN(x) x 是特殊的非数字值 NaN(或者能被转换为这样的值) console.log(isNaN(NaN)) ...

  9. .NetCore使用skywalking实现实时性能监控

    一.简介 很久之前写了一篇 <.Net Core 2.0+ InfluxDB+Grafana+App Metrics 实现跨平台的实时性能监控>关于NetCore性能监控的文章,使用Inf ...

  10. android_安装包_NoClassDefFoundError

    说说这个问题出现的地方吧: 能够成功的打包安装包,但是在安装包安装后,准备运行时出现了这个问题. 查看了这篇文章,讲得有理有据,并没有解决我的问题. 通过谷歌查找到这个stackoverflow,解决 ...