目录

传统布局的不足之处:导航栏实现案例说明问题

关于单个、一行多个浮动元素的水平居中实现

弹性布局

弹性容器的主轴和侧轴概念

弹性容器的主轴对齐&侧轴对齐(一维布局特性说明)

主轴flexitem元素弹性宽高,以及换行/换列

多行对齐

flex-flow复合样式属性

flexbox样式总结

flexitem专有样式说明

flex-grow及按比扩容

flex-shrink及按权重比压缩

flex-basis

flex复合写法

order

align-self


传统布局的不足之处:导航栏实现案例说明问题

CSS - 定位布局_伏城之外的博客-CSDN博客

上一个章节定位布局的粘性定位小节中,实现工商银行导航栏时,我使用了ul li,并且由于li是块容器,所以不支持在同一行上排列。此时有两个传统方案可以让li在一行排列:

  • 将li转为行内块元素
  • 将li转为浮动元素

但是这两个方案都有缺点:

  • 行内块元素之间会产生因为代码空格或换行导致的间隙,我们可以通过去除代码中行内块之间的空格、换行,来消除行内块元素之间的空隙,但是此时代码可读性就变差了
  • 浮动元素间虽然紧密贴合,但是会脱标,导致父元素ul的宽高塌陷,虽然给父元素加overflow:hidden,将父元素ul变为BFC容器可以解决宽高塌陷,但是此时父元素的内容区宽度是占满一行的,这将导致无法让父元素紧密包裹子浮动元素,导致无法带子浮动元素水平居中

关于单个、一行多个浮动元素的水平居中实现

首先浮动元素脱标后,浮动元素在浮动流中是不会占满一行的(即不会通过margin来占满剩余宽度),所以此时margin:0 auto无法让浮动元素实现水平居中。

此时我们可以给浮动元素包裹一个标准流父元素,并设置宽高为子浮动元素宽高,之后margin:0 auto父元素。

这种方法也适用于一行多个浮动元素的水平居中

但是当浮动元素未设置宽高(即浮动元素宽高由其内容撑开)时,其标准流父元素的宽高设置将很难给定,而父元素宽高无法确定,则无法实现准确的父元素携带子浮动元素水平居中。

那么此时我们需要怎么办呢?

弹性布局

Flexible Box 模型,通常被称为 flexbox,是一种一维的布局模型。它给 flexbox 的子元素之间提供了强大的空间分布和对齐能力。

这里一维布局的意思指的是:flexbox的子元素只会按照行方向或者列方向,一个方向上进行布局。

当我们为一个元素添加display:flex样式后,该元素就变为了flexbox,即弹性容器。flexbox的子元素就变为了flexitem,即弹性项目。

弹性布局的弹性布局分别体现在:

  • 弹性:flexitem元素可以膨胀以填充额外的空间,收缩以适应更小的空间。
  • 布局:flexbox给予了flexitem强大的空间分布和对齐能力

弹性容器上支持如下样式属性:

  • flex-flow:flex-direction flex-wrap
  • justify-content
  • align-items
  • align-content

弹性项目上支持如下样式属性:

  • order
  • flex:flex-grow flex-shrink flex-basis
  • aligin-self

弹性容器的主轴和侧轴概念

我们知道弹性布局是一维布局,flexItem只会在flexbox的一个方向上进行布局,即flexbox的主轴方向。而flexbox的主轴的垂直方向就是flexbox的侧轴方向。

flexbox的主轴并非固定是水平方向或垂直方向,而是取决于flexbox元素的flex-direction样式,flex-direction属性值如下:

  • row(默认)
  • row-reverse
  • colum
  • colum-reverse

我们通过下图来理解这四个值得含义

弹性容器的主轴对齐&侧轴对齐(一维布局特性说明)

其实理论上来说,弹性布局是一维布局,弹性容器中的弹性项目flexitem只能在主轴上进行各种对齐。而flexitem元素在主轴上的各种对齐就是主轴对齐。侧轴对齐并不是针对每个flexitem元素的,而是针对整个主轴的。所以flexitem元素只在主轴上布局,弹性布局是一维布局。

主轴对齐指的是:flexitem在flexbox主轴上的对齐方式

侧轴对齐指的是:整个主轴在侧轴上的位置

设置主轴上元素的对齐方式使用样式justify-content,它具有如下属性值:

  • flex-start(默认值)
  • center
  • flex-end
  • space-between
  • space-around

下面通过代码看看以上对齐效果:

justify-content:flex-start

flexitem元素从flexbox容器的主轴起始线排列

justify-content:center

flexitem元素从flexbox容器的主轴中间排列

justify-content:flex-end

flexitem元素从flexbox容器的主轴终止线排列

justify-content:space-around

每个flexitem元素的左右空间相等

justify-content:space-between

flexitem元素之间间隔相等

设置整个主轴在侧轴上的位置用样式align-items,它具有如下属性值:

  • stretch(默认值)
  • flex-start
  • center
  • flex-end
  • baseline

下面通过代码看看以上属性值效果:

align-items的默认值是stretch,含义是自动拉伸自适应高度的flexitem元素的高度为flexbox的高度

对于设置高度height的flexitem元素而言,align-items不会拉伸其高度

如果flexbox也没有高度,则flexbox会被高度最高的flexitem元素撑开,即flexbox的高度为最高的flexitem元素的高度。

所以实际上,此时无高度的flexitem会默认被拉伸到最高的兄弟flexitem元素的高度

主轴放置于侧轴起始位置

主轴放置于侧轴中间位置

主轴放置于侧轴结束位置

主轴上flexitem元素按照内容文字的基线baseline对齐

主轴flexitem元素弹性宽高,以及换行/换列

当我们主轴上flexitem过多,以至于超出flexbox宽/高时,默认情况下,主轴上的flexitem元素是不会换行的,而是表现出flexitem元素的弹性宽/高特点,即flexitem元素的会被尽可能地压缩宽/高以适应flexbox的宽/高,但是一个flexitem元素的宽度最多被压缩到内容宽高,如果flexitem压缩到内容宽高还是超过flexbox宽高的话,则默认会超出flexbox范围,而不是换行。

我们可以通过flexbox容器样式属性 flex-wrap 来控制主轴上flexitem是否换行,flex-wrap属性值如下:

  • nowrap(默认值)
  • wrap
  • wrap-reverse

当给flexbox设置flex-wrap:wrap后,此时主轴上flexitem元素的宽高不会再被压缩,当flexbox一行/一列放不下多余flexitem时,则对应flexitem换行或换列显示。

换行/换列时,如果flexbox在对应换行/换列方向上有剩余空间,默认情况下剩余空间会被均分,保证每个flex-item的在对应方向的边距相同。

但是如果我们设置了侧轴对齐方式,则

当flexbox设置了flex-wrap:wrap,即使主轴换行/换列也放不下多余的flexitem,flexitem也不会被被压缩宽高,而是超出flexbox范围。

flex-wrap:wrap-reverse是反向换行

需要注意的是 flex-direction:xxx;flex-wrap:wrap-reverse 不等价于 flex-direction:xxx-reverse; flex-wrap:wrap;

原因是:flex-wrap控制的是换行/换列的方向,而不是主轴的方向

多行对齐

上例中,我们可以通过align-items来设置多行的在侧轴上的对齐方式

但是可以发现,align-items设置的多行对齐,行与行之间总是留有空隙。

如果我们想让多行之间没有空隙的实现在侧轴上对齐,则需要借助flexbox的align-content样式。

首先,需要点明的是,align-content只能用于多行侧轴对齐设置,即只能用于flex-wrap:wrap的flexbox。

align-content从名字上看,其实就是将每一行或每一列当成一个整体元素,在flexbox侧轴上排列(让他们像主轴上的flexitem一样实现对齐),align-content具有如下常用属性值:

  • normal(默认值)
  • flex-start
  • center
  • flex-end
  • baseline
  • space-around
  • space-between

当align-content为normal时,则多行根据align-items值在侧轴上对齐;

当align-content不是normal时,则多行根据lign-content值在侧轴上对齐;

flex-flow复合样式属性

flex-direction和flex-wrap可以复合写成flex-flow样式;

flex-flow:flex-direction flex-wrap

由于flex-direction的默认值是row,flex-wrap的默认值是nowrap,所以flex的默认值是:

flex-flow:row nowrap;

flexbox样式总结

我们通过给flexbox设置flex-direction来控制其主轴方向,设置flex-wrap来设置其是否换行,二者可以复合写为flex-flow。

主轴上flexitem元素的对齐使用justify-content,主轴行在侧轴上的位置用align-items,对于主轴多行情况,还可以将每一行当成整体元素使用align-content使其在侧轴上实现对齐。

flexitem专有样式说明

flexitem即flexbox在主轴上的弹性项目元素,当我们设置flexbox不换行时,flexitem元素的宽/高会具有弹性,下面以主轴row方向来说明:

  • 当flexbox一行放不下所有flexitem元素,则所有flexitem的宽度会被自动压缩到可以适配一行宽度位置,但是最小只能压缩到flexitem的内容宽度。
  • 当align-items为stretch时,对于未设置高度的flexitem来说,其高度会被拉伸到flexbox的高度。

这里我们发现通过flexbox样式来控制flexitem元素的弹性是普渡众生型的,所有flexitem元素都会被影响,如果我们想让部分flexitem的宽度不被压缩,则需要针对特定的flexitem元素进行设置,此时我们需要使用flexitem专有样式flex-grow,flex-shrink,flex-basis

另外,flexbox只会按照代码顺序来排列flexitem,这是不自由的,所以我们需要使用flexitem专有样式order来针对每个flexitem元素设置排列顺序。

还有,flexbox是通过align-items来控制所有flexitem在侧轴上的对齐,也是普渡众生型的,为了能实现特定flexitem的侧轴对齐,我们可以使用align-self,该样式的值和align-items一致,但是只作用于特定flexitem,而不是所有flexitem。

flex-grow及按比扩容

MDN官方对于flex-grow的解释是:设置flexitem主尺寸的弹性增长系数。

flexitem的主尺寸指的是flexitem在主轴方向上的尺寸,

  • 比如主轴为row或row-reverse时,flexitem的主尺寸就是宽度width;
  • 比如主轴为colum或colum-reverse时,flexitem的主尺寸就是高度height;

弹性增长系数,其实就是当flexbox主轴方向存在剩余空间时,设置了flex-grow的flexitem主尺寸可以分配到的剩余空间的比例。

flex-grow可是任何非负数值,默认值为0。

flex-grow按比扩容计算规则:

假设:flexbox主轴方向是row,则

剩余宽度 = flexbox宽度 -  所有flexitem原始宽度之和

flexitem占比 = flexitem的flex-grow  ÷  所有flexitem的flex-grow之和

flexitem所分得的剩余宽度 = flexitem占比 × 剩余宽度

flexitem弹性宽度 = flexitem原始宽度 + flexitem所分得的剩余宽度

剩余宽度 = 500 - (100 + 150 + 50) = 200px

blue占比 = 0 / (0 + 1 + 1) = 0

red占比 = 1 / (0 + 1 + 1) = 1/2

orange占比 = 1 / (0 + 1 + 1) = 1/2

blue所分得剩余宽度 = 0 * 200 = 0

red所分得剩余宽度 = 1/2 * 200 = 100

orange所分得剩余宽度 = 1/2 * 200 = 100

blue未扩容

red扩容后弹性宽度为 150 + 100 = 250px

orange扩容后弹性看到为 50 + 100 = 150px

flex-shrink及按权重比压缩

MDN官网对于flex-shrink的定义是: 该属性指定了flexitem的收缩规则。flexitem仅在默认宽度之和大于flexbox容器的时候才会发生收缩,其收缩的大小是依据 flex-shrink 的值。

flexitem元素的flex-shrink值可以为任何非负数,默认值为1。

flex-shrink按权重比压缩计算规则:

假设:flexbox主轴方向是row,则

flexitem权重 = flexitem宽度 × flexitem的flex-shrink系数

总权重 = 所有flexitem的权重之和

flexitem权重比 = flexitem权重 ÷ 总权重

总压缩宽度 = 所有flexitem原始宽度之和 - flexbox宽度

flexitem压缩宽度 = flexitem权重比 × 总压缩宽度

flexitem弹性宽度 = flexitem原始宽度 - flexitem压缩宽度

flexitem的flex-shrink默认为1。

总权重 = (100 * 0 + 150 * 1 + 50 * 1) * 2 = 400

blue权重比 = 100 * 0 / 400 = 0

red权重比 = 150 * 1 / 400 = 3/8

orange权重比 = 50 * 1 / 400 = 1/8

总压缩宽度 = 600 - 500 = 100

blue压缩宽度 = 0 * 100 = 0

red压缩宽度 = 3/8 * 100 = 37.5

orange压缩宽度 = 1/8 * 100 = 12.5

blue未被压缩

red弹性宽度 = 150 - 37.5 = 112.5

orange弹性宽度 = 50 - 12.5 = 37.5

flex-basis

MDN官方对于flex-basis的解释是:flexitem在主轴方向上的初始大小。如果不使用box-sizing:border-box盒子模型的话,那么flex-basis指定的就是flexitem的内容区主尺寸。

如果一个flexitem元素既设置了flex-basis(非auto值),又设置了内容区主尺寸(即content-box的width、height),则flexitem的内容区尺寸以flex-basis的值为准。

flex-basis的取值如下:

  • auto(默认值)
  • 指定尺寸
  • content

flex-basis:auto的意思是“参照我的width/height属性”,即flexitem的内容区尺寸取决于width\height。

flex-basis:content,意思是参照flexitem元素实际内容的尺寸

flex-basis:指定尺寸,意识是忽略flexitem的主尺寸width/height,以flex-basis指定的尺寸为准

另外由于flex-basis会影响flexitem的主尺寸大小,所以会影响剩余宽度计算,压缩宽度计算,即会影响flex-grow,flex-shrink。

剩余宽度 = 200 - 85 - 50 - 50 = 15px

blue扩容后宽度 = 50 + 15 = 65px

每个flexitem的flex-shrink默认为1

压缩总宽度 = flexitem原始宽度之和 - flexbox宽度 = (85 + 50 + 50) * 2 - 200 = 170

总权重 = (85 * 1 + 50 * 1 + 50 * 1) * 2 = 370

red权重比为 85 * 1 / 370

blue权重比为 50 * 1 / 370

green权重比为 50 * 1 / 370

压缩宽度 = 压缩总宽度 * 权重比

则red弹性宽度为 = 原始宽度 - 压缩宽度 = 45.95px

flex复合写法

flex-grow、flex-shrink、flex-basis可以复合写成flex样式属性。

flex:flex-grow  flex-shrink  flex-basis

但是flex的用法多种多样,其支持一个值,两个值,三个值的情况

对于一个值的情况

如果值为非负数字,且无单位,则该值对应flex-grow,且此时flex-shrink:1,flex-basis为0%

 

如果值为一个有单位的数字,则带单位的数字对应flex-basis的值,且此时flex-grow:1,flex-shrink:1

如果值为auto或content,则也对应flex-basis的值,且此时flex-grow:1,flex-shrink:1

对于两个值的情况

此时第一个值必然对应flex-grow,则只能是非负数。

第二值可以是flex-shrink,比如为非负数时,也可以时flex-basis,比如为带单位的值,auto,content。

对于三个值的情况

则必然对应 flex:flex-grow  flex-shrink  flex-basis

总结

flex

flex-grow

(默认1)

flex-shrink

(默认1)

flex-basis

(默认0%)

0 0 1 0%
1 1 1 0%
auto 1 1 auto
content 1 1 content
30px 1 1 30px
1 1 1 1 0%
1 auto 1 1 auto
1 1 auto 1 1 auto

order

flexitem元素还支持设置order样式来定义自身排列顺序,order值越小越靠前,order值默认为0,所以设置了正数的order的lfexitem总是显示在未设置order的flexitem后面。order还支持负数,order为负数的flexitem总是最先显示,因为它小于默认的order:0。

align-self

align-self用于给特定的flexitem进行侧轴对齐,其值基本与align-items值相同。并且flexitem的align-self会覆盖来自flexbox的align-items。

align-self的值如下:

  • flex-start
  • center
  • flex-end
  • baseline

CSS - 弹性布局(flex)相关推荐

  1. CSS弹性布局 Flex属性

    flex是Flexible Box的缩写,就是弹性盒子布局的意思 通过flex我们可以解决元素居中问题,自动弹性伸缩,适配不同大小的屏幕和移动端. Flex布局简介 序号 简记 术语 1 二成员 容器 ...

  2. CSS 弹性布局/flex布局最后一行左对齐

    设计案例: 左对齐前 左对齐后 html: <h1 class="module-title">核心产品</h1> <ul class="co ...

  3. css 弹性盒子 flex布局

    目录 css弹性盒子flex 布局 什么是flex 常见父项属性 概念与案例 主轴与侧轴 flex-direction设置主轴的方向 justify-content 设置主轴上的子元素排列方式 fle ...

  4. CSS 的弹性布局(flex) ,是什么?

    一.弹性布局 是什么? 元素根据窗口大小变化而自动伸长或缩短,使得整个页面格式保持不变. 二.怎么使用? 1.使用方法 /* 1.父元素中增加 display 属性:*/ display: flex; ...

  5. css弹性布局笔记一(垂直居中、水平居中、居中)(display:flex)

    CSS弹性布局,需要一个容器,容器中至少包含一个以上的元素,以下代码包含子元素垂直居中.水平居中.居中三种情况 <html> <head> <style type=&qu ...

  6. css布局之弹性布局flex

    1. 弹性布局作用 作用:弹性布局flex能按照我们的设置自动计算各子元素之间的间距并将之布局好,而不需要像定位那样手动计算布局. 2.弹性布局的定义和属性 弹性布局是定义在一个父容器中,加上disp ...

  7. 使用css弹性布局,让页面footer底部固定

    在前端开发过的工作中,footer永远固定在底部的需求.也就是说一个Footer元素如何粘住底部,使其无论内容多或者少,Footer元素始终紧靠在浏览器的底部.我们知道,当内容足够多可以撑开底部到达浏 ...

  8. css弹性布局自动换行怎么实现,网页设计常用布局之CSS弹性布局

    #网页设计#在网页设计中内容的排版和布局往往是整个设计工作的重点和难点,如果能熟练掌握CSS弹性布局的话,无论是页面的整体设计还是局部内容的布局,都能起到事半功倍的效果.尤其是对非专业的或刚开始从事前 ...

  9. 一、CSS弹性布局[弹性盒子、弹性元素]

    一.CSS弹性布局 1.弹性盒子 弹性盒子的属性全都是写在父元素上面 1.1基础 解释:在父元素上写上display:flex;或者display:inline-flex;子元素就会出现弹性效果,其中 ...

  10. 前端css弹性布局各种属性

    前端css弹性布局各种属性 一.基本概念 Flexbox 是 flexible box 的简称(注:意思是"灵活的盒子容器")又叫弹性布局,是 CSS3 引入的新的布局模式.它决定 ...

最新文章

  1. Html 教程 (5) “表格”三要素
  2. 强迫症犯了,忍不住赞一下slf4j包Logger.java的优雅代码
  3. HTML 标签简写及全称
  4. 初识ES-安装IK分词器
  5. 英语口语(5月17)
  6. java web 不用框架_MyShop-不用框架的基础javaweb项目
  7. c语言编程车,C语言编程之自动类型转化
  8. 项目管理工具project软件学习(八) - 关键路径查询、资源可用性
  9. WCF中NetTCp配置
  10. 打开含avi格式视频文件的文件夹“死机”问题的解决
  11. 性能优化之雅虎35条军规
  12. t分布 u分布 卡方分布_F分布、t分布、正太分布与卡方分布的联系与区别
  13. 【学习小记】支配树【图论】
  14. 开发者工具的暖心提示语
  15. uni-app【判断手机是否安装微信QQ】
  16. PostgreSQL 11 preview - Surjective indexes - 索引HOT增强(表达式)update评估
  17. 【随手记】Oracle存储过程报错 Compilation errors for PACKAGE BODY
  18. 一种利用强核力和弱核力复制物质原子的仪器
  19. 英特尔NUC迷你电脑套件安装windows10+ubuntu18.04双系统
  20. win10安装CP2102(STM32串口通信)驱动

热门文章

  1. leetcode第29题python版两数相除
  2. 火车购票系统服务器端uml活动图,火车购票完整系统UML类图时序图状态图协作图活动图对象图用例图.doc...
  3. 通俗讲解:PoW共识机制与以太坊的关系、Ghost协议 及 PoS共识机制的变种---Casper...
  4. java循环结构和分支结构
  5. 同一子网下数据传输的基本流程
  6. 同一局域网下访问vue项目
  7. Idea使用SpringLoaded实现热部署
  8. python怎么画参数函数图像_python函数 图
  9. cloud-init中NoCloud配置
  10. CSP2019 游记