本文推荐 PC 端阅读~
本文版权归 “公众号 | 前端一万小时” 全部,未经受权,请勿转载!
复制代码
css_11
复制代码
1. 有几种定位方式?分别是如何实现定位的?参考点是什么?使用场景是什么?
2. z-index 有什么做用?如何使用?
3. BFC 是什么?如何生成 BFC?BFC 有什么做用?举例说明。
4. 在什么场景下会出现外边距合并?如何合并?如何不让相邻元素外边距合并?给个父子外边距合并的范例?
复制代码
前言: 这一篇咱们主要探讨“定位”和 BFC 是怎样让“盒子”动起来的。
学习方法依然是:打开 JS Bin ,拷贝代码运行查看效果,而后搞定每一行代码的前世此生。css
“定位”就是经过设置 position 属性的值来脱离正常的文档流。html
🔗源码及效果展现
html前端
<div class="box1">1</div>
<div class="box2">2</div>
<div class="box1">3</div>
复制代码
css面试
.box1, .box2 {
width: 50px;
height: 50px;
border: 2px solid;
}
.box2 {
position: relative;
/* 🚀relative 是相对于它本来正常流的位置进行偏移, 视觉上看它是移动了,但它本来所占用的文档流的空间是没有变化的, 对其余元素来讲,它仍是在那里的,故其余元素位置是不会有变化的 */
top: 10px;
left: 10px;
}
复制代码
当你设置为绝对定位后,文档流上的其余元素就看不见你了。就认为你不存在!若是存在多个绝对定位元素,那么这些绝对定位元素也互相看不见。
🔗源码及效果展现
html浏览器
<div class="box1">1</div>
<div class="box2">2</div>
<div class="box1">3</div>
复制代码
cssbash
.box1, .box2 {
width: 50px;
height: 50px;
border: 2px solid;
}
.box2 {
position: absolute;
top: 10px;
left: 10px;
/*❓这个值是相对于谁作偏移呢? 答:首先它会从本身的父元素里边去找, 看看本身的父元素里边有没有定位,这个定位包括 relative 、absolute 、fix , 若是有的话就相对于它; 若是没有的话,就再从父元素的父元素里边去找,若是有的话就相对于它; 若是再没有,就一直找到咱们的 body 。*/
}
复制代码
🔗源码及效果展现
htmlide
<div class="container">
<div class="box1">1</div>
<div class="box2">2</div>
<div class="box1">3</div>
</div>
复制代码
css布局
html {
border: 3px solid blue;
/*3️⃣最后,若是都没有,那么 box2 的绝对定位值就相对于这里,到头了。*/
}
body {
margin: 40px;
border: 1px solid red;
/*2️⃣其次,若是下边 container 没有 position , 而这里有定位(relative 、absolute 、fixed), 那么 box2 的绝对定位值就相对于这里: position: relative; */
}
container {
margin-top: 40px;
padding: 40px;
background: yellow;
/*1️⃣首先,若是 box2 父元素这里有定位(relative 、absolute 、fixed), 那么 box2 的绝对定位值就相对于这里: position: relative; ⚠️而这里用 relative 是最好的,由于一个元素自己设置 relative , 却不设置值的话,就等同于没设置。 那它就依然在普通流中,它仍是一个普通元素, 那它本身的位置也没发生变更,却能够给其子元素做为相对的锚点。 */
}
.box1, .box2 {
width: 50px;
height: 50px;
border: 2px solid;
}
.box2 {
position: absolute;
top: 0px;
left: 10px;
}
/*⚠️因此,咱们在使用绝对定位的时候,必定要设置好定位的参考点(锚点)。 通常来讲,咱们绝对定位的参考点都是相对于其父容器。 因此原则上是:一个元素设置绝对定位 absolute , 那它的父容器设置定位为 relative */
复制代码
元素使用了绝对定位后,就如浮动同样,有了“块盒子”的特性。post
因为使用绝对定位以后,产生元素覆盖的问题,z-index 能够解决元素之间覆盖顺序的问题,设置它的层叠顺序。同级元素,数值越大,越靠近视觉点;不一样父元素,只要父元素越大,那么总体就越靠近视觉点,而无论其子元素大小状况。学习
显示器显示的图案是一个二维平面,用 x 轴和 y 轴来表示位置属性。
为了表示三维立体的概念,如显示元素的上下层的叠加顺序,引入了 z-index 属性来表示 z 轴上一个元素在叠 加顺序上的上下立体关系。
z-index 值较大的元素将叠加在 z-index 值较小的元素之上。对于未指定此属性的定位对象,z-index 值为正数的对象会在其之上,而 z-index 值为负数的对象在其之下。
z-index 属性适用于定位元素(position 属性值为 relative 或 absolute 或 fixed 的对象),用来肯定定位元素 在垂直于显示屏方向(称为 Z 轴)上的层叠顺序,也就是说若是元素是没有定位的,对其设置的 z-index 会是无效的。
相同 z-index 谁上谁下?
父子关系处理:
position: fixed;
复制代码
相对于浏览器的窗口进行定位。所以当滚动产生时,固定定位元素依然处于窗口的某个位置不动。
大布局、自适应,用“浮动”————浮动通常和响应式结合的比较多;
小元素、固定宽高,用“定位”————通常只适用于一些很小的 icon ;
🏆结合实际状况是关键。
好比说,网页头像上的未读消息,咱们通常都是选择用“定位”才能很好的实现。凡是能盖住其余东西的也是“绝对定位”。
🔗源码及效果展现
html
<nav>
<ul>
<li><a href="#">首页</a></li>
<li><a href="#">做品</a></li>
<li><a href="#">更多</a>
<ul class="child">
<li><a href="#">GitHub</a></li>
<li><a href="#">博客</a></li>
<li><a href="#">知乎</a></li>
</ul>
</li>
</ul>
</nav>
复制代码
css
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
a {
color: #333;
text-decoration: none;
}
nav {
width: 500px;
margin: 10px auto 0;
box-shadow: 0px 2px 4px 1px rgba(0,0,0,0.3);
/*🚀这里边的这几个值:第1、二个值表示这个阴影的水平、垂直的偏移; 4px 表示模糊度;1px 是这个模糊的一个延展;rgba 是这个模糊的颜色。*/
}
nav::after {
content: '';
display: block;
clear: both;
}
/*🚀因为咱们用了浮动,咱们须要清除浮动来撑开父容器。*/
nav>ul>li {
position: relative;
/*🚀🚀🚀给下边 .child 的绝对定位”偏移值“加一个“锚点”。*/
float: left;
/*🚀把这个选择器层级里的 li 水平排列。*/
}
nav>ul>li:hover .child {
display: block;
}
/*🚀🚀 .child 默认是隐藏的,当我鼠标放到“更多”这个 li 上的时候才显示, 并显示为 block 。*/
nav a {
display: block;
padding: 10px 10px;
/*记着,咱们要想点击的范围很大,咱们是须要在 a 连接上来加 padding 的。 若是在 li 上加 padding ,那么点击范围依然在字上。*/
/*但要注意,因为 a 连接是个行内元素,因此若是这里只单单加 padding , 那其实他的宽高是没有变化的,只是背景色变大了,它会出现不少诸如“遮挡”的后果。 故,咱们须要让其显示为 block 。*/
/*咱们没有用 inline-block 是由于:用 inline-block 即它同时仍是有行内特性, 会致使"收缩"——即宽度由文本内容宽度决定。 想要撑开,而不受内容宽度影响,那就须要用 block 。*/
min-width: 50px;
/*这里加了一个“最小的宽度”的用途是把这个 a 连接里边的文字内容撑开, 使任何一个可点击的文本都不换行。*/
}
nav a:hover {
color: #fff;
background: rgba(0,0,0,0.4);
}
nav .child {
position: absolute;
/*🚀🚀🚀设置了绝对定位,咱们才能够想把这个 .child 放哪里就放哪里, 由于父容器发现不了它。而其余方式(好比浮动、或不用)是达不到理想的效果的。*/
top: 100%;
/*100% 就表示按照 li 的高度。*/
box-shadow: 0px 2px 4px 1px rgba(0,0,0,0.3);
display: none;
/*🚀🚀 .child 默认是"隐藏"的——display: none , 当我鼠标放到“更多”这个 li 上的时候再显示。*/
}
复制代码
⚠️相关前置知识,请先阅读文章:
《CSS——CSS 基本视觉格式化:① “块盒子”格式化》
《CSS——CSS 基本视觉格式化:② “行内盒子”格式化》
每一个渲染区域用 fomating context 表示,它决定了其子元素如何去定位,以及和其余元素的关系和相互做用。
BFC 全称 Block Formating Context 。
display 属性为 block 、list-item 、table 的元素,会产生 BFC 。也就是“块元素”。
若是一个元素增长了一个属性叫 float ,那这个元素自己也产生了一个块级格式化上下文。
咱们之因此要了解这个 BFC ,是由于咱们但愿经过了解它的特性来实现咱们须要的一些效果。或者当出现了某个问题的时候,咱们可以去解释这个问题,知道是为何,进而解决它或找到替代方案。
① 在 BFC 中,盒子从顶部开始垂直地一个接一个的排列。
② 盒子垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻盒子的 margin 会发生重叠。
③在 BFC 中,每个盒子的左外边距应该和包含块的左边接触(对于从左往右的格式化,不然相反)。即便存在浮动也是如此!
④ BFC 的区域不会与浮动的盒子产生交集,且是紧贴浮动的边缘。
⑤ 计算 BFC 的高度时,浮动盒子的高度也参与计算。
⑥ BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此!
对应规则:⑤ 计算 BFC 的高度时,浮动盒子的高度也参与计算。
对应规则:② 盒子垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻盒子的 margin 会发生重叠。
对应规则: ③ 在 BFC 中,每个盒子的左外边距应该和包含块的左边接触(对于从左往右的格式化,不然相反)。即便存在浮动也是如此! ④ BFC 的区域不会与浮动的盒子产生交集,且是紧贴浮动的边缘。
❌问题:
🔗源码及效果展现
<ul class="navbar">
<li><a href="#">1首页</a></li>
<li><a href="#">2产品</a></li>
<li><a href="#">3服务</a></li>
<li><a href="#">4关于</a></li>
</ul>
复制代码
.navbar {
list-style: none;
border: 1px solid #ccc;
/*加一个背景色也没效果: background: pink;*/
}
.navbar>li {
float: left;
margin-left: 15px;
}
/*🚀因为浮动元素脱离了文档流,因此他的父元素是看不见他的。 这里对于 navbar 来讲,他认为里边没有什么 li 来把它撑开, 由于 li 已经浮动了,那没有东西撑开它,它就会认为高度为 0。*/
复制代码
✔️解决方式:
经过“清除浮动”来解决——在文章《CSS——让盒子动起来:①浮动》中已做解答;
经过给父元素建立 BFC ,添加 overflow: hidden;
样式:
对应规则:⑤ 计算 BFC 的高度时,浮动盒子的高度也参与计算。
<ul class="navbar">
<li><a href="#">1首页</a></li>
<li><a href="#">2产品</a></li>
<li><a href="#">3服务</a></li>
<li><a href="#">4关于</a></li>
</ul>
复制代码
.navbar {
list-style: none;
border: 1px solid #ccc;
overflow: hidden;
}
.navbar>li {
float: left;
margin-left: 15px;
}
复制代码
❌问题:
在文章《CSS——CSS 基本视觉格式化:① 块盒子格式化》中,咱们知道:
垂直格式化的另外一个重要方面是垂直相邻 margin 的合并。 这种合并行为只应用于 margin,若是元素有 padding 和边框,padding 和边框是不会合并的。当两个或更多垂直 margin 相遇时,他们将造成惟一一个 margin,这个 margin 的高度等于两个发生叠加的 margin 的高度中的较大者。
⚠️注意:当一个元素包含在另外一个元素中时,彼此相邻的 margin-bottom 和 magin-top 也会发生叠加,取较大者。
<div class="box1">1</div>
<div class="box2">2</div>
复制代码
.box1 {
color: #fff;
width: 100px;
height: 100px;
margin-bottom: 50px;
background: blue;
}
.box2 {
color: #fff;
width: 100px;
height: 100px;
margin-top: 100px;
background: pink;
}
复制代码
✔️解决方式:
将垂直方向上的盒子放在不一样的 BFC 中,margin 就不会重叠了。
对应规则:② 盒子垂直方向的距离由 margin 决定,属于同一个 BFC 的两个相邻盒子的 margin 会发生重叠。
<div class="box1">1</div>
<div class="ct">
<div class="box2">2</div>
</div>
<!--🚀咱们在 box2 的外层包裹一层容器,并触发该容器生成一个 BFC 。 那么两个 box 就不属于同一个 BFC ,就不会发生 margin 重叠了! -->
复制代码
.ct {
overflow: hidden; /*🚀触发该容器生成一个 BFC */
}
.box1 {
color: #fff;
width: 100px;
height: 100px;
margin-bottom: 50px;
background: blue;
}
.box2 {
color: #fff;
width: 100px;
height: 100px;
margin-top: 100px;
background: pink;
}
复制代码
❓问题:
在文章《CSS——让“盒子”动起来:① 浮动》中,咱们经过加 margin-left
或 margin-right
的方式制做“有缝隙”的两栏布局的效果。
❗️但若是要求两栏布局中间没有缝隙,该怎么办呢?
❌因为:
③ 在 BFC 中,每个盒子的左外边距应该和包含块的左边接触(对于从左往右的格式化,不然相反)。即便存在浮动也是如此!
<div class="aside">侧边栏固定宽度</div>
<div class="main">Hey guys, 我正在这个平台发放“前端一万小时”这个专栏的一系列文章。<br>
这个专栏我已经完成了“从零基础到就业”相关的文章。<br>
"从零基础到就业"包含 150+ 篇干货文章,300+ 道经典笔试、面试题。<br>
若是你对本系列文章感兴趣,欢迎关注 「公众号:前端一万小时」,
并点击菜单栏“获取所有文章”来加入咱们的“一万小时计划”!祝顺利^^……
</div>
复制代码
.aside {
color: #fff;
width: 150px;
height: 100px;
background: red;
float: left;
}
.main {
color: #fff;
background: blue;
height: 200px;
}
复制代码
✔️解决方式:
④ BFC 的区域不会与浮动的盒子产生交集,且是紧贴浮动的边缘。
经过触发 main 生成 BFC ,来实现自适应无缝隙两栏布局:
.main {
overflow: hidden; /*🚀触发 BFC */
}
.aside {
color: #fff;
width: 150px;
height: 100px;
background: red;
float: left;
}
.main {
color: #fff;
background: blue;
height: 200px;
}
复制代码
后记:经过两篇兄弟文章,咱们算是让“盒子”动了起来,接下来 3 篇文章,咱们就让“这个能够动的盒子”更优雅的“展现”。
祝好,qdywxs ♥ you!