深掘 CSS3 Flex 布局的奥秘:打造无界限的灵活页面布局

简介: 深掘 CSS3 Flex 布局的奥秘:打造无界限的灵活页面布局


个人主页:学习前端的小z


个人专栏:HTML5和CSS3悦读


本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结,欢迎大家在评论区交流讨论!




✍CSS flex布局

Flex是Flexible Box的缩写,意为”弹性(放大、缩小)布局”,用来为盒状模型提供最大的灵活性。

flex布局是目前主流的布局方式,结合盒子模型+定位,可以快速实现页面各种复杂布局。

大部分场景下可以代替浮动布局,特殊场景下,比如:文字环绕效果,还得使用浮动布局更方便。

学习Flex布局搞清楚几个重要的概念:

  • flex container:flex 容器
  • flex item:flex 项目,针对容器的子级
  • main axis:主轴,默认是水平方向
  • cross axis:交叉轴,默认是垂直方向
  • main start:主轴和 flex 容器左边的交叉点
  • main end:主轴和 flex 容器右边的交叉点
  • cross start:交叉轴和 flex 容器上边的交叉点
  • cross end:交叉轴和 flex 容器下边的交叉点
  • main size:flex 项目占据的主轴宽度,可伸缩
  • cross size:flex 项目占据的交叉轴高度,可伸缩

flex 项目默认沿主轴排列

💎1 Flex容器和Flex项目

指定一个 Flex 容器:

<style>
.box {
    display: flex;
    /*display: inline-flex;*/
}
</style>
<div class="box">
    <div></div>
    <span></span>
    文字
    <input type="text">
</div>

Flex 容器的子级全部变成 Flex 项目,不管你原来是 block,inline-block,inline 都会设置为 flex 项目(display: block)一样对待。

flex项目变成block,这个block和之前学习position:absolute、fixed以及float:left|right的块级类似,虽然计算属性display:block,但是表现形式和行内块类似,默认都是内容的宽度,但是可以设置宽度、高度、外边距、内边距、边框等等

💎2 Flex 容器属性

🌹2.1 主轴的方向

flex-direction属性决定主轴的方向(即项目的排列方向)。

flex-direction: row | row-reverse | column | column-reverse;
  • row(默认值):主轴为水平方向,起点在左端。
  • row-reverse:主轴为水平方向,起点在右端。很少使用
  • column:主轴为垂直方向,起点在上沿。交叉轴就变成水平
  • column-reverse:主轴为垂直方向,起点在下沿。交叉轴就变成水平。很少使用

🌹2.2 主轴对齐方式

justify-content属性定义了项目在主轴上的对齐方式。

justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;

它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右。

  • flex-start(默认值):左对齐
  • flex-end:右对齐
  • center: 居中
  • space-between:两端对齐,项目之间的间隔都相等。
  • space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
  • space-evenly:每个间隙距离相等. (兼容处理:用 space-between配合before+after使用)

🌹2.3 Flex 项目换行

默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,如果一条轴线排不下,如何换行。

  1. Flex容器指定了具体宽度
  2. 所有的Flex项目总宽度 > Flex容器宽度
flex-wrap: nowrap | wrap | wrap-reverse;

它可能取三个值。

1、nowrap(默认):不换行。Flex宽度700px,每个Flex项目宽度为100px, 1000px > 700px,只能收缩至70px

2、wrap:换行,第一行在上方。

3、wrap-reverse:换行,第一行在下方。很少使用

flex-flow

flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。很少使用

flex-flow: <flex-direction> <flex-wrap>;

🌹2.4 交叉轴对齐方式

🍡2.4.1 align-items属性

align-items属性设置 flex项目在每个 flex 行的交叉轴上的默认对齐方式。

align-items: flex-start | flex-end | center | baseline | stretch;

它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。

  • flex-start:交叉轴的起点对齐。
  • flex-end:交叉轴的终点对齐。
  • center:交叉轴的中点对齐。
  • baseline: 项目的第一行文字的基线对齐。很少使用
  • stretch(默认值):没有交换主轴和交叉轴方向的情况下,如果Flex项目未设置高度或设为auto,将占满整个容器的高度。如果flex项目有高度,则不会被拉伸占满,高度也可以会超过flex容器

【实践】利用justify-content和align-items快速实现水平垂直居中

  • 与之前的 position:absolute + margin 水平垂直居中更好,不脱标,不会遮盖等问题
🍡2.4.2 align-content属性

align-content属性只适用多行的flex容器(flex 项目不止一行时该属性才有效果),它的作用是当flex容器在交叉轴上有多余的空间时,将flex 项目作为一个整体(属性值为:flex-start、flex-end、center时)进行对齐。

align-content: flex-start | flex-end | center | space-between | space-around | stretch;

未指定 flex-wrap: wrap; ,那么 align-content 属性是无效的:

翻译:flex wrappe:nowrap属性防止align-content产生效果。

尝试将flex-wrap设置为nowrap以外的其他内容。

说白了nowrap无效,设置 wrap-reverse 或者 wrap 是可以的,只要换行才可以对align-content产生效果

只要设置了flex-wrap: wrap,表示存在多行,那么就用align-content,否则单行总是用align-items即可

该属性可能取6个值。

  • flex-start:与交叉轴的起点对齐。
  • flex-end:与交叉轴的终点对齐。
  • center:与交叉轴的中点对齐。
  • space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
  • space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
  • stretch(默认值):轴线占满整个交叉轴。如果flex项目有高度,则不会被拉伸占满,高度也可以会超过flex容器

💎3 Flex 项目属性

🌹3.1 Flex项目排序

order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。很少使用

order: <integer>;

🌹3.2 Flex 项目交叉轴对齐方式

align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

该属性可能取6个值,除了auto,其他都与align-items属性完全一致。

该属性可能取6个值,除了auto,其他都与align-items属性完全一致。

auto 表示继承 Flex 容器的 align-items 属性的值。

🌹3.2 放大比例

该属性用来设置当父元素的宽度大于所有子元素的宽度的和时(即父元素会有剩余空间),子元素如何分配父元素的剩余空间。 flex-grow 的默认值为 0,意思是该元素不索取父元素的剩余空间,如果值大于0,表示索取。值越大,索取的越厉害。

flex-grow: <number>; /* default 0 */

如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。

假如设置父元素 400px,子元素 A 为100px,子元素 B 为 200px.则剩余空间为 100px

例子一:

A的 flex-grow 为 0,B的 flex-grow 为 0(即A、B不设置该属性)

则A、B的实际宽度为他们本身的宽度,即A的实际宽度为100px ; B的实际宽度为200px

例子二:

A的 flex-grow 为1,B的 flex-grow为0(即不设置该属性)

则A的实际宽度为 100px + 100px =200px ; B的实际宽度为 200px + 0 = 200px

例子三:

A的 flex-grow 为 1,B的 flex-grow 为 2

则 A 的实际宽度为 100px + 100px * 1/3 = 400/3 px , B的实际宽度为 200px + 100px * 2/3 = 800/3 px

上面的 总系数为 1 + 2 = 3 ,然后按照 各元素的 flex-grow 的属性值进行分配 A 1/3 B 2/3

结论: d = 剩余空间,g1 = flex-grow1,g2 = flex-grow2,A = A宽度,B = B宽度,设 At = A最终分配的宽度,Bt = B最终分配的宽度,当 d > 0,At = A + d * (g1 / g1 + g2),Bt = B + d * (g1 / g1 + g2)

最终结果 At + Bt = A + B + d = 父盒子的宽度,达到扩展

🌹3.3 收缩比例

该属性用来设置子元素的 缩小比例,当父元素的宽度小于所有子元素的宽度的和时(即子元素会超出父元素),子元素如何缩小自己的宽度的。 **flex-shrink **的默认值为 1,当父元素的宽度小于所有子元素的宽度的和时,子元素的宽度会减小。值越大,减小的越厉害。如果值为 0,表示不减小。

假如设置父元素 400px,子元素A为 200px,子元素B为 300px.则超出空间为 100px

例子一:

设置A的 flex-shrink 为 0,B的 flex-shrink 为 0

则A,B都不减小宽度,A、B的实际宽度为他们本身的宽度,即A的实际宽度为 200px ; B的实际宽度为 300px

例子二:

A的 flex-shrink 为 0,B的 flex-shrink 为 1,则A不减小宽度,B减小

则A的实际宽度为他本身的宽度= 200px , B的实际宽度为 300px - 100px(超出的宽度)= 200px

例子三:

如果A,B都减小宽度,A设置 flex-shirk 为 3,B设置 flex-shirk 为 2。则最终 A 的大小为 自身宽度 (200px) - A减小的宽度(100px * (200px * 3 / (200px * 3 + 300px * 2))) = 150px

最终 B 的大小为 自身宽度 (300px)- B减小的宽度 (100px * (300px * 2/(200px* 3 + 300px* 2))) = 250px

结论: d = 超出空间,g1 = flex-shrink1,g2 = flex-shrink2,A = A宽度,B = B宽度,设 At = A最终分配的宽度,Bt = B最终分配的宽度,当 d > 0,At = A - d * ( A * g1 / (A * g1 + B * g2) ),Bt = B - d * ( B * g2 / (A * g1 + B * g2) )

最终结果 At + Bt = A + B - d = 父盒子的宽度,达到收缩

🌹3.4 Flex项目基准宽度

basis 的中文意思就是 基础、基准 ,该属性用来设置元素的宽度,通常情况下大家使用 width 设置宽度。但是如果元素上同时设置了 widthflex-basis ,那么 width 的值就会被 flex-basis 覆盖掉。其实就是flex 项目占据的主轴宽度(main size),可伸缩

flex-basis: <length> | auto; /* default auto */

放大比例(flex-grow)和收缩比例(flex-shrink)都是更加基准宽度(flex-basis)来进行计算的,如果没有基准宽度(flex-basis),那么就去使用width,如果width也没有,就会自动计算。

<style>
    .father {
        display: flex;
        width: 400px;
        height: 200px;
    }
    .box {
        width: 200px;
        height: 100px;
        flex-basis: 300px;
        background: blue;
    }
</style>
<div class="father">
    <div class="box"></div>
</div>

可以看到给父元素添加 display:flex 属性后让其变成 flex 布局 ,子元素的 width 设置成 200 pxflex-basis 设置成 300 px,最终显示为 300pxwidth 的值就被 flex-basis 覆盖掉,这个属性比较好理解

flex 属性

flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。

.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。

建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。


相关文章
|
3天前
|
Web App开发 前端开发 JavaScript
技术心得记录:瀑布流的布局原理分析(纯CSS瀑布流与JS瀑布流)
技术心得记录:瀑布流的布局原理分析(纯CSS瀑布流与JS瀑布流)
|
2天前
|
前端开发
CSS中的display属性:布局控制的关键
CSS中的display属性:布局控制的关键
105 42
|
5天前
|
移动开发 前端开发 HTML5
2024.4.5-CSS 布局模型(层模型)
2024.4.5-CSS 布局模型(层模型)
|
14天前
|
前端开发 开发者 容器
CSS进阶-Grid布局高级应用
【6月更文挑战第16天】**CSS Grid布局是CSS3的强大力量,用于复杂二维布局。然而,隐式网格、未命名Grid线和缺少响应式设计是常见问题。解决方法包括显式定义网格结构、命名Grid线和结合媒体查询实现响应式。高级技巧涉及自适应列宽、复杂区域布局和元素层叠对齐。代码示例展示了响应式Grid的用法。掌握这些能提升布局效率和设计灵活性。**
|
14天前
|
前端开发 开发者 容器
CSS进阶-Flexbox高级布局技巧
【6月更文挑战第16天】Flexbox是CSS3的布局模块,简化响应式设计和复杂多列布局。文章探讨了Flex容器与项目属性的区分、垂直居中、防止元素溢出等常见问题及解决方案。此外,还分享了等宽不同高列、圣杯布局和自适应间距等高级技巧。通过示例展示了如何创建垂直居中布局,强调实践和理解核心概念是掌握Flexbox的关键。
|
11天前
|
前端开发 容器
如何用css实现两列布局?
如何用css实现两列布局?
14 1
|
16天前
|
前端开发 开发者
CSS进阶-CSS3多列布局
【6月更文挑战第14天】CSS3的多列布局简化了复杂布局,提供杂志样式排版。通过`column-*`属性如`column-count`和`column-gap`实现内容分割和列间距控制。常见问题包括内容溢出、列间距不当和兼容性问题。解决方法包括使用`word-break`和`hyphens`处理长单词,灵活设置列宽和列数,以及为旧浏览器提供回退方案。代码示例展示了一个自动平衡列高的两列布局。理解并解决这些问题将帮助开发者更好地利用CSS3多列布局。尽管有兼容性挑战,但它是现代网页设计的重要工具。
|
19天前
|
前端开发 开发者 容器
CSS基础-Flexbox布局基础
【6月更文挑战第11天】Flexbox是CSS3的全新布局模式,简化了网页动态布局问题。通过`display: flex`设置容器,调整`flex-direction`、`justify-content`、`align-items`等属性控制项目排列和对齐。适用于响应式布局、均匀分布空间和元素对齐。注意浏览器兼容性、选择合适布局模式及区分对齐与排序属性。通过实例代码学习和实践,掌握Flexbox能有效提升网页布局效率。
|
19天前
|
前端开发 开发者 容器
CSS基础-Grid布局基础
【6月更文挑战第11天】CSS Grid布局简化了网页设计,提供前所未有的灵活性。本文探讨Grid基础、常见问题及解决方案。学习重点包括理解容器和项目、正确使用网格线、避免固定单位、有效对齐元素以及选择合适布局模型。通过深入学习、实践调试和参考资源,设计师能避免陷阱,掌握这一现代布局技术。实践是关键,不断尝试将使你在Grid布局中游刃有余。
|
25天前
|
前端开发 容器
7. CSS 网格布局
7. CSS 网格布局
17 4