8

前言

先扯一段废话来引入好了。又很久没有写文章了(间接性踌躇满志,持续性混吃等死),几个月了登上来看到有人收藏和点赞,感到很惭愧,最近主要精力花费在react和redux,在写项目的过程中发现当前学习重心偏向js和框架学习,css的知识不够扎实,正好碰到公司的技术大牛分享css心得,借此机会恰好梳理一下自己的知识。

本篇的内容主要是pc端的常规布局,说到这里,虽然目前flex布局和grid布局比较火,用起来也确实很方便,但是这两个方案有个比较致命的地方--需要高版本浏览器的支持(IE10以上),而很多项目需要考虑到IE8以下的兼容,所以目前在pc端项目中仍然使用一些常规的布局方案。

正文

为了更容易理解,还是采用举例的方式进行知识点说明

水平布局类

一侧元素固定宽度,另一侧元素自动填充满父容器

案例1:比如需要写这样一个评论区域,左侧是固定宽度的区域放置评论者的头像,右侧是评论的内容和信息等
评论

这时候可以这样写
案例1

 .left{
    position:absolute;
    width:200px;
  }
  .right{
    padding-left:200px;
  }

一侧不定宽,另一侧元素自动填充满父容器

案例2:如果把上个案例左边的头像换成评论者昵称,由于昵称长度不一定,所以左侧的宽度不能写死,此时采用如下写法:
图片描述

  .left{
    float: left;
  }
  .right{
   overflow: auto;  }

这种写法的原理是触发右边元素的BFC特性(关于bfc的详细介绍不在本篇提出,网上有比较多的文章介绍),可以先简单的说一下,BFC的简单来说,主要是使元素成为一个独立的容器,不受外界因素的影响。这种写法也可以用在有侧边栏的页面布局上,以及常见的带有标题和时间戳的文章列表项上,看下面的例子:
图片描述

类似于上图这种,需要显示文章标题和发布时间情况,可能有些人会采取左侧标题左浮动,右侧时间戳右浮动的写法来写,这样的写法其实是不够稳健的:如果标题的长度太长,或者说整个容器的宽度变小的时候,效果会变成这样:右侧的元素会被挤到下一行去
图片描述

,而采用上面的写法时是这样的:
图片描述

如果再配合上css的文字超出部分省略号,就可以变成这种效果:当容器宽度小的时候,标题根据长度自适应显示。
图片描述

(关于white-space这个属性,在后续的文章会再提到,占个坑)
关键代码:

.left{
    float: left;
    background-color: lightpink;
    text-overflow: ellipsis;
    max-width: 171px;
    overflow: hidden;
    white-space: nowrap;
  }
  .right{
    overflow: auto;
    background-color: lightblue;
  }

水平居中类

对于定宽元素,直接使用margin:0 auto;(其实只有左右是auto即可 上下的可以设置其它值):

.inner{
      width: 300px;
      height:400px;
      margin: 0 auto;
    }

对于非定宽的元素,在父容器上使用text-align:center即可

.box{
      text-align:center;
    }

以上两种都比较简单和常见,不再赘述。

垂直居中类

文字(内联)内容的垂直居中

案例3:还是刚刚上面的文章列表项,如果需要让标题和时间戳都垂直居中, 那么可以让子元素的line-height值等于li的高度,即可实现内部的文字居中。
效果图(为了让效果更明显,特意设置了两边字体大小不同):
图片描述

关键代码:

    //父容器
   .box{
        height:40px;
    }
    //子容器
    .inner{
        line-height:40px;
    }
       

这里要提一下的是,line-hight只对于内联元素或者内联内容有效,比如说为块级元素p标签设置行高,实际上是为p标签中的内联文字设置了行高。(行高的详细计算也不在本文赘述,后续看情况是否另写)

块盒的垂直居中

案例4:假设现在我们需要写一个工具条,工具条的高度不确定,工具条内的图标高度有可能不一样,但是都要垂直居中。 目标效果图:
图片描述
像上面这种效果,可能会有人提出对不同的图标使用不同margin:top的值来使它们强制垂直居中,但是这样的写法是很不方便的,如果工具栏的高度有所变化,需要进行相应调整。比较合适的写法是像下面这样:

//父容器
.toolbar{
    font-size:0
    height:300px;
}
  .toolbar:after{
    content:"";
    display: inline-block;
    vertical-align: middle;
    width: 0;
    height: 100%;
  }
//子容器
  .inner{
    display: inline-block;
    vertical-align: middle;
  }

这个例子可能需要详细解释下。首先先问一个问题吧:vertical-align: middle;这个属性是怎么生效的?字面上翻译过来是“垂直方向居中”,那请问这里的垂直方向居中是以什么为参照物的呢?,
css2.1里面提到:

for inline non-replaced elements, the box used for alignment is the box whose height is the 'line-height' (containing the box's glyphs and the half-leading on each side, see above). For all other elements, the box used for alignment is the margin box.
在w3c上是这样描述的:
该属性定义行内元素的基线相对于该元素所在行的基线的垂直对齐。允许指定负长度值和百分比值。这会使元素降低而不是升高。在表单元格中,这个属性会设置单元格框中的单元格内容的对齐方式。

简单的来说,可以认为这些设置了inline-block内部块盒,它们vertical-align的是相对于父容器的行高来设置的。好了,第二个关键点是,在上面的案例中 我们并不确定父元素box的行高,那这时候父元素box的行高就等于子行内元素中高度最高的一个,对于上面伪类属性的作用大家肯定都知道,相当于给box添加一个子元素,由于我们给这个伪类设置了inline-block,使之具有内联元素的特征,又设置了高度为100%,那么当父容器具有固定高度时,这个伪类元素能保证,父容器的行高等于高度,从而保证了其他元素的vertical-align: middle;能够真正相对于父容器的高度居中

还有一点就是,使用inline-block的元素会导块级元素出现间隙(具体的原因关系到inline-block的属性特性,本文暂时不提),通用的解决方案是给父容器加上font-size:0

绝对定位元素的居中

对于已知宽高的绝对定位元素,可以简单的这样写:

.inner {
   position: absolute;
    left:50%;
    top:50%;
    width: 100px;
    height: 100px;
    margin-left: -50px;
    marigin-right: -50px;
}

关键思路就是设置负边距为自身宽高的一半
如果在ie9以上,可以使用transform属性简化代码,此时可以不需要知道元素自身的宽高

.inner {
   position: absolute;
    left:50%;
    top:50%;
    width: 100px;
    height: 100px;
    transform: translate(-50%,-50%);
}

小结

本文主要是对pc端常用的一些布局写法做了整理,总体上还是偏向于在某种情况下怎么做的思路来写的, 其实其中很多的东西值得深入研究,比如BFC,line-heightdisplay:inline-block的一些内容,但是由于篇(lan)幅(duo)的关系无法在文中详细说明,后续再一一补上吧(如果懒癌没有发作的话,毕竟每次写文章之前写结构、画图、写代码、组织语言都要花费一番功夫,写完一次都会恐惧一段时间。。。)还有就是,很感谢那些支持和关注的人,你们给了我前进的动力。
然后是惯例:如果这篇文章对你有帮助,请大方的点收藏和推荐吧,以上内容属于个人见解,如果有不同意见,欢迎指出和探讨。请尊重作者的版权,转载请注明出处,如作商用,请与作者联系,感谢!


安歌
7k 声望5.5k 粉丝

目前就职于Ringcentral厦门,随缘答题, 佛系写文章,欢迎私信探讨.