flex属性从了解到使用

1. 前言

flex 弹性布局是常见的一种自适应布局方式, 父容器的属性控制整体布局,子项属性控制子项布局。这里主要了解和总结子项中常用的 flex 属性。

2. flex语法

2.1 与 flex 相关的三个属性

弹性布局的 flex 属性定义了如何分配 flex容器的剩余空间。

剩余空间: flex 容器大小减去所有 flex 项的大小总和。

flex 是 <flex-grow> <flex-shrink> <flex-basis> 三者的简写,默认值为 0 1 auto。

flex-grow 表弹性扩展,指定容器剩余空间多余时的分配规则,默认为0,多余空间不分配。
flex-shrink 表弹性收缩,指定容器剩余空间不足时的分配规则,默认值为 1,空间不足要分配;如果为 0,表示不分配。
flex-basis 表基础尺寸,指定 flex 元素在分配空间前的大小,默认值为 auto,即项目本身大小。

如果剩余空间为正数, 即容器有多余空间, 则按照子项的 flex-grow 定义的比例进行扩展;
若为负数, 则剩余空间不足, 按照 flex-shrink 定义的比例进行收缩。

2.1.1 各种值及含义

flex: none | auto | [< 'flex-grow' > < 'flex-shrink' >? || < 'flex-basis' > ];

根据以上 MDN 官方给出的语法,存在以下几种情况:
1.单值语法
如关键字(none 或 auto)、纯数值表示 < ‘flex-grow’ > 或 带单位表示 < ‘flex-basis’ >;

单值语法等同于备注
flex: initialflex: 0 1 auto初始值
flex: noneflex: 0 0 auto- -
flex: autoflex: 1 1 auto- -
flex: 1flex: 1 1 0%只要 flex-grow设置值了, flex-basis 的值必为 0%,而不是默认值auto。
flex: 0flex: 0 1 0%当希望元素充分利用剩余空间,但是各自的尺寸按照各自内容进行分配时适用
flex: 100pxflex: 1 1 100px只要 flex-basis 设置值了, flex-grow 的值必为1 ,而不是默认值0。

2.双值语法
第一个值表 < ‘flex-grow’ > ;
若第二个值为纯数值,则为 < ‘flex-shrink’ > ;
若第二个值带单位表示长度,则表示 < ‘flex-basis’ > ;

双值语法等同于备注
flex: 1 2flex: 1 2 0%只要 flex-grow设置值了, flex-basis 的值必为 0%,而不是默认值auto。
flex: 1 100pxflex: 1 1 100px只要 flex-basis 设置值了, flex-grow 的值必为1 ,而不是默认值0。

3.三值语法
对应 < ‘flex-grow’ > < ‘flex-shrink’ > < ‘flex-basis’ > 的值;

2.2 默认值 flex: initial

2.2.1 含义

它等同于 flex:0 1 auto。
0 表示 flex-grow: 0 , 当子项总长度<容器宽度时,不会撑满,按照实际宽高存在;
1 表示 flex-shrink:1,当子项总长度>容器宽度时,子项会收缩相对应的比例;
auto 表示 flex-basis:auto,尺寸自适应于内容,即子项宽度由内容决定。

2.2.2 适用场景

适用于子项总长度小于总容器的场景,例如按钮、标题、小图标等小部件的排版布局。

2.2.3 区分于 flex: auto

flex: initial === flex:0 1 auto
flex: auto === flex:1 1 auto

区别在于前者 flex-grow 值为0,后者为1。
当有多余空间时,flex: auto 子项的宽度会撑满容器,其他情况两者相同。

2.3 flex:1 的含义及应用

2.3.1 含义

flex:1 等同于 flex: 1 1 0%。
子项的宽度不由内容决定,根据剩下的空间进行相应比例的伸缩。

2.3.2 适用场景

场景一:各子项宽度等分
思路:子项都设置 flex:1
子项都设置 flex:1

场景二:希望元素充分利用剩余空间,如:多列布局中,希望某一列或某几列撑满剩下空间
思路:固定列宽度固定,自适应列设置 flex:1
在这里插入图片描述

2.3.3 应用中出现的问题

溢出不省略

在这里插入图片描述
代码:

<div class="flex-container">
  <div class="flex-item-left"></div>
  <div class="flex-item-right">
    <div class="text">这是一段长长长长长长长长的文字</div>
  </div>
</div>

.flex-container{
  display: flex;
  align-item: center;
  padding: 10px;
  background-color: #e9eff9;
  width: 200px;
  height: 50px;
}

.flex-item-left{
  width: 50px;
  min-width: 50px;
  height: 100%;
  background-color: #638cd0;
  margin-right: 10px;
}

.flex-item-right{
  flex: 1;
}

.text{
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

分析:
在分配剩余空间之前,决定当前子元素的实际空间大小的优先级为: flex-basis > width > 内容宽度。

同时, 这个实际空间大小会受到元素的 min-widthmax-width 的限制 。

浏览器默认为flex容器的子元素设置了 min-width: auto; min-height: auto,这意味着子元素的最小宽度和高度不能小于其内容的宽度和高度。

当 flex 子项内容足够多时, 最小宽度为内容宽度, 内容溢出。

参考:
flex布局中 text-overflow:ellipsis 失效
flex弹性布局 子元素内容超出盒子容器宽度问题

解决思路:
直接把 min-width: auto; 这个默认属性覆盖,设置为 min-width: 0,即使其内容为空或者宽度很小,也可以使得flex子元素在flex容器中正确地布局

元素不对齐

在这里插入图片描述

代码及示例链接如下

demo: flex元素无法对齐

<div class="numbers">
  <div class="row">
    <div class="button">1</div>
    <div class="button">2</div>
    <div class="button">3</div>
  </div>
  <div class="row">
    <div class="button">4</div>
    <div class="button">5</div>
    <div class="button">6</div>
  </div>
  <div class="row">
    <div class="button" id="number0">0</div>
    <div class="button" id="colon">:</div>
  </div>
</div>

.row {
  display: flex;
}

.button {
  flex: 1;
  margin: 5px;
  border: 1px solid gray;
}

.button#number0 {
 flex: 2; 
}

.button#colon {
 flex: 1;
}

问题: 如图,flex值为2 的子项无法与其他行 flex值为1 子项的边缘对齐

分析: flex容器的剩余空间会先减去flex子项之间的 margin, 然后再去按照伸缩比例进行分配各子项空间。而flex值为2的子项所在的行比其他行少了10px的margin,剩余空间也会比其他行多了10px,故比例1的对应空间也会多于其他行。

参考:
how-to-get-flexbox-to-include-padding-in-calculations
flex-grow-not-sizing-flex-items-as-expected
用户体验思考与flex三坑:元素不均分、溢出不省略和垂直不滚动

解决思路:
使用可明确长度的 flex-basis 属性而不用flex: 1

.button    { flex-basis: 33.33%; }
#number0   { flex-basis: calc(66.67% + 10px); }
 *          { box-sizing: border-box; } 

注: 让所有元素 box-sizing: border-box; 目的是让元素整体宽度包含边框, 避免在分配空间时因边框产生计算误差

2.4 其他应用场景

需求场景:多个子元素下, 元素保持等比例宽度, 空间剩余时, 子元素不撑满, 空间不足时, 仍保持等比例宽度, 不会被压缩, 而是出现滚动条

解决思路:各子项设置 flex: 0 0 25%;
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值