本文主要以解析网页中最常见的左右固定宽度、中间随屏幕自适应的三栏布局来学习CSS中的BFC和Flex。

在日常的浏览网页中,我们经常会见到一种布局,左右固定或左右其一固定,中间主要展示内容且宽度自适应,这一布局难点在于中间如何自适应,接下来我们开始实现它。

首先我们可将布局整体作为一个父容器,那么该父容器的子元素则为左div、中div、右div,此处我们代入一个实际的例子:关注页/粉丝页中的用户列表。 那么则左边是头像,中间是名字和个人简介,名字右边等级标签,右边是关注按钮。

左中右布局.png 乍看这个布局很简单,但在用户名字非常长的时候就容易出现问题了,可能会出现以下几种情况:

1.名字无法尽量长 2.等级与名字不在一行 3.关注按钮被挤出父容器

在解释出现的这些问题之前,我们先搭建好整体布局,

<div id="first" class="main">
  <div class="avatar">
    <img src="http://via.placeholder.com/50" alt="">
  </div>
  <div class="content">
    <a class="name" href="#">name</a>
    <span>tag</span>
  </div>
  <div class="text">there is my introduction.</div> 
  <div class="follow">
    <span>+follow</span>
  </div> 
</div>

并创建样式。

/*单行文本*/
.oneline {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/*父容器*/
.main{
    display:block;
    background: #f2f2f2;
    padding: 5px;
    height: 50px;
}
/*头像*/
.avatar{
    float: left;
    margin-right: 10px;
}
.avatar img{
    border-radius: 50px;
}
/*内容*/
.content{
    margin-left: 5px;
}
.content a{
    text-decoration: none;
    color:black;
}
/*等级*/
.content span{
    background: #66ccff;
    color: #fff;
    border-radius: 5px;
    font-size:0.8em;
    padding: 0 5px;
}
/*个人简介*/
.text{
    margin-top: 10px;
}
/*关注*/
.follow{
    float: right;
    line-height: 30px;
    height:30px;
    color: #66ccff;
    border:1px solid #66ccff;
    background: #fff;
    margin:10px 0;
    border-radius: 5px;
}

因为头像的左浮动,和关注的右浮动,还有内容部分因自适应无法确定宽度,关注按钮被内容部分阻挡无法右浮,此时关注按钮被挤出父容器。

关注按钮被挤出父容器.png

解决方法很简单,我们将关注按钮与内容的div调换位置。

调换位置后.png

没有了内容部分的阻挡,关注按钮回到了正常的位置。但当我们将用户名改的长一点,标签和用户名就不在一行显示了。

标签和用户名不在一行显示.png

接下来派上用场的就是flex布局了。

我们知道,flex布局有一个css属性叫flex-shrink,它的默认值是1,如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。

所以我们要将内容部分的第一行布局改为flex,再给里面标签的样式添加上flex-shrink: 0;

将原content部分样式替换为如下代码:

.content .nickname-wrap{
    display: flex;
    flex-direction:row;
    justify-content:flex-start;
    align-items:flex-start;
}
.nickname-wrap span{
    flex-shrink: 0;
    background: #66ccff;
    color: #fff;
    border-radius: 5px;
    font-size:0.8em;
    padding: 0 5px;
}

更改内容部分为如下HTML代码:

<div class="content">
    <div class="nickname-wrap">
        <a class="name oneline" href="#">达拉崩吧斑得贝迪卜多比鲁翁</a><span>标签</span>
    </div>
    <div class="text oneline">达拉崩吧斑得贝迪卜多比鲁翁昆图库塔卡提考特苏瓦西拉松</div>
</div>

最后我们刷新浏览器,查看效果。

最终效果.png

参考资料:

http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html -flex语法(阮一峰的网络日志)

https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context -块格式化上下文(MDN Web 文档)