CSS3之 flex 各种场景应用

227 阅读5分钟

本文已参与「 新人创作礼 」活动,一起开启掘金创作之路

关于如何进行图片优化 - 适合的才是最好的

最近刚入职一个新公司,全新负责搭建一个项目。CSS3 Layout 的应用那是应接不暇。

不能说CSS3 没有用过,一般都是用到哪里查到哪里。

没有系统的思考过。

今天我还是江几个布局为主吧。

第一种布局 列布局。

例如这是百度首页的热搜记录:

如果用flex改如何做呢?

<!-- 文章图一 -->
<div class="warp">
  <div>物流不通不畅问题总体得到缓解</div>
  <div>上海社会面疫情风险正逐步降低热</div>
  <div>北京56例感染者详情一览</div>
  <div> 人涉婚宴热4上海外滩长草?</div>
  <div> 记者连夜去看了新2她是全国唯</div>
  <div> 记者连夜去看了新</div>
  <div> 她是全国唯一一位女省委书记热</div>
  <div> 记者连夜去看了新</div>
  <div>同济大学回应学生盒饭吃出虫卵异物</div>
  <div>3333</div>
</div>



.warp {
  display: flex;
  width:300px;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: space-between;
  div {
    max-width: 50%;
    line-height: 25px;
    height:25px;
    overflow: hidden;
    white-space:nowrap;
    text-overflow: ellipsis;
  }
}

这里面重点的几句代码要解释下:

flex-direction: row; // 多列布局 , 默认缺省属性就是row

如果设置为colum , 那就只能一列了。这个侧边栏用的比较的多。

flex-wrap: wrap; // 这个属性决定你是否多行布局是否成功,默认flex-wrap 为 no-wrap;

如果没有设置属性就是这个样式了!

全部挤在一起一行了!

但是我的需求是,2列布局,且想两边靠拢。

justify-content: space-between; // 默认属性为flex-start
//justify-content: flex-start | flex-end | center | space-between | space-around

最后的结果为:

至于overflow:hidden, noswap 这个代码中有,不在今天讲解范围。

我们继续应用实战。

举例 Ant Design Pro 界面设计。

Header 100% 撑开

Side为弹性伸缩。

MainContent为剩余内容的补齐。举例:如果Side为 100px, 那么main为 100vw - 100px

我们来构思下,我们的实现。

<div class='wrap-page'>
  <header>header</header>
  <div class="content">
    <div class="side">side</div>
    <div class="content">content</div>
  </div>
  <footer>footer</footer>
</div>

是不是看起来很简单的样子。

wrap-page {
  width:100vw;
  height:100vh;
  background:red;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  header,footer {
    height:48px;
    background:black;
    text-align: center;
    line-height: 48px;
    color: white;
  }
  .content {
    background:yellow;
    flex: auto;
    background-color: green;
    display: flex;
    .side {
      width:88px;
      text-align: center;
      height:100%;
      background: red;
      justify-content: center;
      display: flex;
      align-items: center;
    }
    .content {
      flex:auto;
      background:pink;
      justify-content: center;
      align-items: center;
    }
  }
}

这里重点说几个样式:

  1. flex: auto; // 他会内容优先,沾满左右空格。
  2. 如果需要内容空间上下居中,align-items: center; 是牛逼元素之一。

这些布局如果用DIV其实也是可以实现的, 包括一模一样的功能。只是flex的布局更加简便。

特别是作用任何地方, 他不用脱离文档流。

flex的用处远远不止于此。

flex 属性其实有可以传3个参数。
就好比marign:1px 2px 3px 4px; 每个参数都代表不同含义
还有font:normal 12px/25px arial; //这些都是css的简写

flex也不例外:

flex :flex-grow flex-shrink flex-basis;

一般的布局或许很多人都是用不到的, 但是如果我们要做到牛逼的弹性布局,这些元素那是必不可少的。

例如:

flex-grow 剩余空间索取默认值为0,不索取。

flex-shrink 子元素总宽度大于父元素如何缩小。

flex-basis 该属性用来设置元素的宽度,当然width也可以用来设置元素的宽度,如果设置了width和flex-basis,那么flex-basis会覆盖width值。

下面我来举例如何正确的使用这3个元素。我就通过组合使用的方式,省的去记住这么复杂的属性名称。

<div class="flex-wrap">
  <div class='cloum1'>1</div>
  <div class='cloum2'>2</div>
  <div class='cloum3'>3</div>
</div>

.flex-wrap {
  width:200px;
  height:200px;
  background:cornflowerblue;
  display: flex;
  .cloum1 {
    // flex-grow: 2;
    // flex-shrink: 0;
    // flex-basis: 20px;
    flex:2 0 20px;
    background: red;
  }
  .cloum2 {
    // flex-grow: 3;
    // flex-shrink: 0;
    // flex-basis: 50px;
    flex : 3 0 50px;
    background: green;
  }
  .cloum3 {
    // flex-grow: 5;
    // flex-shrink: 0;
    // flex-basis: 30px;
    flex: 5 0 30px;
    background: blue;
  }
}

得到的公式为 cloum1 、cloum2、cloum3 他们flex-basis 总数为 100px

而flex-wrap宽度为200响度,剩余像素就给flex-grow来瓜分。

100 / ( 2+3+5 ) = 10px , 这个值是flex-grow

最后得到的值为 cloum1 、cloum2、cloum3 40、80 、80

因为这里的flex-shrink都为0 所以不用考虑,就算有值应该也不生效,( 因为basis的总宽小鱼容器宽度 )

关于flex-shrink 的计算DEMO ( 复杂度要高于grow ,官方文档没有放出计算公式 )

<div class="flex-wrap">
  <div class='cloum1'>1</div>
  <div class='cloum2'>2</div>
  <div class='cloum3'>3</div>
</div>

.flex-wrap {
  width:500px;
  height:200px;
  background:cornflowerblue;
  display: flex;
  .cloum1 {
    // flex-grow: 2;
    // flex-shrink: 0;
    // flex-basis: 20px;
    flex:0 5 200px;
    background: red;
  }
  .cloum2 {
    // flex-grow: 3;
    // flex-shrink: 0;
    // flex-basis: 50px;
    flex : 0 3 500px;
    background: green;
  }
  .cloum3 {
    // flex-grow: 5;
    // flex-shrink: 0;
    // flex-basis: 30px;
    flex: 0 2 300px;
    background: blue;
  }
}

总宽度是500px

basis 200 + 500 + 300 = 1000 超过500

flex-shrink 5 + 3 + 2 = 10

Total权重Ratio = 200 * 5 + 500 * 3 + 300*2 = 3100

需要收缩的总宽度为 1000 - 500 = 500

ratio 1 1000 /3100 = 0.3225

ratio 2 1500/3100 = 0.4838

ratio 3 600 /3100 = 0.1935

cloum1= 200 - (500 x 0.3225)=> 38.75

cloum2= 500 - (500 x 0.4838)=> 258.1

cloum3= 300 - (500 x 0.1935)=> 203.25

关于新宽度的计算公式,我查到的资料基本都是错误的,如果你求知的欲望,你也可以研究下:www.samanthaming.com/flexbox30/2… ( 我通过不同的数值多求几次,精度上会有一些差异 )

上面文章DEMO地址为:code.juejin.cn/pen/7091698…