看文章以前,先来看两个例子。这是咱们在项目中最多见的项目布局方式。css
案例一:多个容器按照相同间距水平排列。bash
案例二:常见的菜单导航微信
看到这两个案例时,你能够先短暂的想一想平时都是如何实现的,不少同窗的答案应该是这样的。布局
// 案例一
<div class="demo">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
.demo {
padding: 1em 0;
width: 470px;
background-color: #e5e5e5;
overflow: hidden;
}
.item {
float: left;
margin-left: 10px;
width: 150px;
height: 100px;
background-color: #fff;
border: 1px solid #999999;
box-sizing: border-box;
}
.item:first-child {
margin-left: 0;
}
//案例二
<div class="demo2">
<a href="" class="nav">导航1</a>
<a href="" class="nav">导航2</a>
<a href="" class="nav">导航3</a>
</div>
.demo2 {
width: 200px;
background-color: cadetblue;
}
.nav {
display: block;
width: 100%;
border-bottom: 1px solid #000;
color: #fff;
}
复制代码
效果咱们是作到了,可是这里全部像素都是你本身固定计算的。学习
好比第一个例子中,父容器的宽度为 470 = 3*150 + 20。若是在不使用 flex 布局的状况下,你想让三个元素自适应屏幕宽度有什么好办法?flex
或者你想把三个元素扩展成四个,这个时候你就须要手动计算每一个元素的宽度。这样好像非常麻烦。spa
那今天就来讲说,如何利用「流」的特性,解决平时在项目中遇到的一些布局问题。code
在刚开始学习 CSS 时咱们都会常常听到这么一个概念叫「文档流」,不少人并无深究文档流是为什么物。cdn
那什么是「文档流」呢?blog
文档流:是引导网页中的元素排列和布局的,它默认的方向是从左向右,从上而下。
而「流」具备最大的一个特色就是自适应性。你能够把它想象成像水流同样,当水流倒入一个容器时,它会自动充满整个容器。而 CSS 中的文档流,其表现是一致的,有殊途同归之妙。
不只如此,你也常常会听到「脱离文档流」,好比浮动,绝对定位等均可以脱离文档流,而脱离文档流不是本文要说的重点,因此就不展开多说,今天主要是聊一聊「流的自适应性」。
文档流中有两个比较重要的概念:块级元素(block)、内联元素(inline),对应到最具表明性的元素就是<div>
、<span>
。
块级元素默认会充满整个屏幕,具备自适应性,而内联元素默认则是水平排列。
你能够想象为块级元素就想是水流同样充满容器,而内联元素就是漂浮在水里按照从左到右排列的物体。
在项目中会常常碰到
display:block
这个属性。但注意,它与块级元素不是同一个东西。display:table
,也属于块级元素。
到这里你应该明确了流的特性,其实不少人都知道「文档流」这个概念,但却没有好好的去利用,从而给本身增长了一些没必要要的麻烦。
好比之前我会写出这样的 CSS:
span {
display: block;
width: 100%;
}
复制代码
若是明白流的特性的话,其实 width: 100%;
这个属性是多余的,由于块级元素在流布局中默认是自动充满容器的。
你是否也中枪写过这种 CSS ?欢迎在评论区说出你的问题。
但若是仅仅只是多了一条属性,其实也就是增长了一行代码显得不那么简洁而已,可事情老是没有那么简单。
一旦你给元素添加了宽度(width)属性,它就会失去流动性,即使是它的值为 100%,也是会失去。
对,你没有看错,只要有了宽度属性,它就会失去了它最牛逼的流动性。这样就变的毫无价值。
好比开头中导航案例,若是给导航加入一些边距。就会出现很差的效果。
.nav {
display: block;
padding: 10px; //添加的边距
width: 100%;
border-bottom: 1px solid #000;
color: #fff;
}
复制代码
而若是咱们把宽度属性去掉,就会获得完美的展现效果。
.nav {
display: block;
padding: 10px;
border-bottom: 1px solid #000;
color: #fff;
}
复制代码
可能你以前并无意识到,加入宽度属性带来的危害。
但当你看到这篇文章以后,你应该警戒宽度给流动性带来的危害,尽可能少用宽度,甚至是「无宽度」。
在此以前我相信不少伙伴在项目汇总遇到过超出宽度的状况,但不多有人去探究,因此不少人都会发挥他特有的计算能力,而后写出以下代码。
.nav {
display: block;
padding: 10px;
width: 180px; // 200px - 10px*2
border-bottom: 1px solid #000;
color: #fff;
}
复制代码
貌似也实现了该有的功能,不过这种缺点咱们显而易见,就是太过固定,任何一点的改动都须要你从新计算。
可能有人会说,兄die,个人计算能力很惊人,你管的着吗,好吧这,波算我输。
那为何加了宽度属性会超出,而不加宽度属性就能够了呢?
原来是由于,当元素不设置宽度属性时或者是 width:auto
,元素的margin、border、padding 能够自动分配空间。
一旦,咱们设置了固定的宽度属性,就算是100%,它就会根据 CSS 的盒模型进行计算。从而失去了自动分配空间的流动性。
至于如何计算的细节,由于盒模型的不一样,因此宽度的做用就不一样,它包含的东西也就不同。具体不在多说。
兄die,这时候知道「无宽度」有多牛逼了吧。
由于这里我提到了盒模型,你会想到把上面的案例,改变下盒模型不就好了吗?好比咱们这么作:
.nav {
display: block;
padding: 10px;
width: 100%;
border-bottom: 1px solid #000;
box-sizing: border-box; //改变盒模型
color: #fff;
}
复制代码
确实在这个案例中是能够这么用的,可是若是想实现案例一的水平有间距排列问题,就有点力不从心了。
因为 CSS 盒模型,是不计算 margin 的,水平排列能够很容易实现,可是想要有相同间距,就比较难以实现。
这个时候你就能够尝试利用流的特性,来很好的实现这个方案。
这时候咱们能够利用流的特性,进行宽度分离。
<div class="demo">
<div class="item">
<div class="child">内容</div>
</div>
<div class="item">
<div class="child">内容</div>
</div>
<div class="item">
<div class="child">内容</div>
</div>
<div class="item">
<div class="child">内容</div>
</div>
</div>
.demo {
padding: 1em;
background-color: #e9e9e9;
overflow: hidden;
}
.item {
float: left;
width: 25%;
}
.child {
margin: 0 10px;
padding: 10px;
border: 1px solid #ccc;
}
复制代码
你会发现,不管你如何改变它的 margin、padding、border 它都会自动填充分配空间,不再会出现布局错乱,超出等等一系列的状况。
以上就是利用流的特性,让布局变得简单、灵活。固然,流的特性不只仅限于这两种布局。
还好比表单的布局,一般表单的布局都是比较难处理的一点,这时候你不妨试试利用「无宽度」、「宽度分离」原则尝试一下,也许会有新的发现。小伙伴们赶忙放飞下本身的想象力吧。
最后,若是以为文章不错,对你有所启发,点赞是一种态度也是一种承认。
微信公众号:六小登登,更多干货文章,这里有个人不少故事,欢迎一块儿交流。
本文参考:《CSS世界》