使用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
结论
一般开发的网站时会遇到非常复杂的文章,通常包括类别标题,简介文本或嵌套布局等元素。使用相邻的兄弟选择器和唯一的margin-top可以在解决复杂的设计要求的同时保持CSS可理解, 方便之后再添加或调整规则。
英文原文:https://hackernoon.com/advanced-vertical-margins-4ac69f032f79
使用CSS兄弟选择器完成复杂垂直边距(vertical margins)的设计的更多相关文章
- css兄弟选择器,+ ~选择器的区别
壹 ❀ 引 实习生在写搜索框下拉提示时,遇到了不知道怎么解决的问题,所以来问我.效果不难,鼠标选中输入框(focus)时,展示搜索关键字相关提示,看了眼dom结构是这样的: 在她的理解里面,选中父元 ...
- CSS后代选择器、子元素选择器、相邻兄弟选择器区别与详解
派生选择器用的很多,派生选择器具体包括为后代选择器.子元素选择器.相邻兄弟选择器,我们来理解一下他们之间的具体用法与区别. 1.css后代选择器语法:h1 em {color:red;} 表示的是从h ...
- 理解css相邻兄弟选择器
今天在菜鸟教程看到了css组合选择符的“相邻兄弟选择器”,刚开始对这个概念有些不太理解,通过查阅资料并且经过一些试验总算有了些头绪. 原文解释是“相邻兄弟选择器(Adjacent sibling se ...
- 前端学习笔记之CSS后代选择器、子元素选择器、相邻兄弟选择器区别与详解
派生选择器用的很多,派生选择器具体包括为后代选择器.子元素选择器.相邻兄弟选择器,我们来理解一下他们之间的具体用法与区别. 1.css后代选择器语法:h1 em {color:red;} 表示的是从h ...
- CSS系列之后代选择器、子选择器和相邻兄弟选择器
后代选择器比子选择器的范围大,包含子选择器,且包含子选择器的“子孙”选择器,后代选择器使用"空格"符号间隔选择器 子选择器:子选择器只是父选择器的一级子元素,使用"> ...
- CSS 相邻兄弟选择器
相邻兄弟选择器(Adjacent sibling selector)可选择紧接在另一元素后的元素,且二者有相同父元素. 选择相邻兄弟 如果需要选择紧接在另一个元素后的元素,而且二者有相同的父元素,可以 ...
- CSS相邻兄弟选择器
相邻兄弟选择器定义:选择紧接在另一个元素后的元素,而且两者有着相同的父元素. 代码一:<body> <h1>This is a heading.</h1> < ...
- CSS后代选择器,子选择器和相邻兄弟选择器
平时在代码练习中,经常用到后代选择器,子选择器也会用到,这里做个总结: 1,后代选择器和子选择器区别: ①写法不一样:后代选择器的标识为:空格 如:ul li{width:150px;} [ul和li ...
- web CSS的知识- 关于后代选择器,子选择器,兄弟选择器的使用
1. 后代选择器官方解释:后代选择器可以选择作为某元素后代的元素.理解:选择某一标签的后代中,所有的此标签标记例:ul em {color:red;}就是选择,h1标签后代中中,所有的em.代码如下: ...
随机推荐
- 使用new Image()进行预加载
概述 这篇博文记录了用new Image()进行预加载的总结,供以后开发时参考,相信对其他人也有用. 旧的预加载 一般我们为了让背景图更快的加载,我们常常把背景图放在一个display:none的im ...
- Swift5 语言指南(十八) 可选链接
可选链接是一个查询和调用当前可选的可选项的属性,方法和下标的过程nil.如果optional包含值,则属性,方法或下标调用成功; 如果是可选的nil,则返回属性,方法或下标调用nil.多个查询可以链接 ...
- 分布式任务调度系统xxl-job相关问题补充
搭建xxl-job时可能会遇到的问题 邮箱配置不起作用报异常 以163邮箱为例,接收邮件需要开启POP3/STMP服务 光开启服务还不够,需要添加授权码 授权码为手动输入,可以与登录密码不同,所以服务 ...
- Liferay7 BPM门户开发之20: 理解Asset Framework
Asset框架用于将您开发的门户内容添加Liferay的核心系统功能.打个比方,你开发了一个事件TodoList管理的插件,在列表显示的时候,你可以集成Asset框架,让你的自定义内容支持Tag标签. ...
- jQuery操作select下拉框的text值和value值的方法
1.jquery获取当前选中select的text值 $("#select1").find("option:selected").text(); 2.jquer ...
- Python内置类型(6)——生成器
上节内容说到Python的for语句循环本质上就是通过调用Iterable可迭代对象的__iter()__方法获得一个Iterator迭代器对象,然后不断调用Iterator迭代器对象__next() ...
- 课程四(Convolutional Neural Networks),第一周(Foundations of Convolutional Neural Networks) —— 0.Learning Goals
Learning Goals Understand the convolution operation Understand the pooling operation Remember the vo ...
- 函数isNaN() parseFloat() parseInt() Math对象
isNaN() 定义和用法 isNaN() 函数用于检查其参数是否是非数字值. isNaN(x) x 是特殊的非数字值 NaN(或者能被转换为这样的值) console.log(isNaN(NaN)) ...
- .NetCore使用skywalking实现实时性能监控
一.简介 很久之前写了一篇 <.Net Core 2.0+ InfluxDB+Grafana+App Metrics 实现跨平台的实时性能监控>关于NetCore性能监控的文章,使用Inf ...
- android_安装包_NoClassDefFoundError
说说这个问题出现的地方吧: 能够成功的打包安装包,但是在安装包安装后,准备运行时出现了这个问题. 查看了这篇文章,讲得有理有据,并没有解决我的问题. 通过谷歌查找到这个stackoverflow,解决 ...