CSS 文档流技巧,让布局更简单

作者: 560b7bb7b879 | 来源:发表于2019-04-24 16:02 被阅读9次

    看文章之前,先来看两个例子。这是我们在项目中最常见的项目布局方式。

    案例一:多个容器按照相同间距水平排列。

    案例二:常见的菜单导航

    看到这两个案例时,你可以先短暂的想想平时都是如何实现的,很多同学的答案应该是这样的。

    // 案例一
    <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 布局的情况下,你想让三个元素自适应屏幕宽度有什么好办法?

    或者你想把三个元素扩展成四个,这个时候你就需要手动计算每个元素的宽度。这样好像很是麻烦。

    那今天就来说说,如何利用「流」的特性,解决平时在项目中遇到的一些布局问题。

    在刚开始学习 CSS 时我们都会经常听到这么一个概念叫「文档流」,很多人并没有深究文档流是为何物。

    那什么是「文档流」呢?

    文档流

    文档流:是引导网页中的元素排列和布局的,它默认的方向是从左向右,从上而下。

    而「流」具有最大的一个特点就是自适应性。你可以把它想象成像水流一样,当水流倒入一个容器时,它会自动充满整个容器。而 CSS 中的文档流,其表现是一致的,有异曲同工之妙。

    不仅如此,你也经常会听到「脱离文档流」,比如浮动,绝对定位等都可以脱离文档流,而脱离文档流不是本文要说的重点,所以就不展开多说,今天主要是聊一聊「流的自适应性」。

    文档流中有两个比较重要的概念:块级元素(block)、内联元素(inline),对应到最具代表性的元素就是<div><span>

    块级元素默认会充满整个屏幕,具有自适应性,而内联元素默认则是水平排列。

    你可以想象为块级元素就想是水流一样充满容器,而内联元素就是漂浮在水里按照从左到右排列的物体。

    在项目中会经常碰到 display:block 这个属性。但注意,它与块级元素不是同一个东西。display:table,也属于块级元素。

    失去流动性

    到这里你应该明确了流的特性,其实很多人都知道「文档流」这个概念,但却没有好好的去利用,从而给自己增加了一些不必要的麻烦。

    比如以前我会写出这样的 CSS:

    span {
        display: block;
        width: 100%;
    }
    
    

    如果明白流的特性的话,其实 width: 100%; 这个属性是多余的,因为块级元素在流布局中默认是自动充满容器的。

    你是否也中枪写过这种 CSS ?欢迎在评论区说出你的问题。

    但如果仅仅只是多了一条属性,其实也就是增加了一行代码显得不那么简洁而已,可事情总是没有那么简单。

    一旦你给元素添加了宽度(width)属性,它就会失去流动性,即便是它的值为 100%,也是会失去。

    对,你没有看错,只要有了宽度属性,它就会失去了它最牛逼的流动性。这样就变的毫无价值。

    比如开头中导航案例,如果给导航加入一些边距。就会出现不好的效果。

    image
    .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 它都会自动填充分配空间,再也不会出现布局错乱,超出等等一系列的情况。

    以上就是利用流的特性,让布局变得简单、灵活。当然,流的特性不仅仅限于这两种布局。

    还比如表单的布局,通常表单的布局都是比较难处理的一点,这时候你不妨试试利用「无宽度」、「宽度分离」原则尝试一下,也许会有新的发现。小伙伴们赶紧放飞下自己的想象力吧。

    这里推荐一下我的前端学习交流群:731771211 ,里面都是学习前端的,如果你想制作酷炫的网页,想学习编程。自己整理了一份2019最全面前端学习资料,从最基础的HTML+CSS+JS【炫酷特效,游戏,插件封装,设计模式】到移动端HTML5的项目实战的学习资料都有整理,送给每一位前端小伙伴,有想学习web前端的,或是转行,或是大学生,还有工作中想提升自己能力的,正在学习的小伙伴欢迎加入学习。

    点击:加入

    相关文章

      网友评论

        本文标题:CSS 文档流技巧,让布局更简单

        本文链接:https://www.haomeiwen.com/subject/wmyggqtx.html