对Flex布局的总结与思考
阅读本文之前最好对flex布局有基本了解,可以通过“参考资料”中列举的资源来学习。
flex布局规范的设计目标
一维布局模型(one-dimensional layout model),元素项沿着水平或垂直方向来排列,就像一条沿着一个方向的“流”。
与之对应的,CSS Grid Layout是一个二维布局模型。两者互为补充。
- 空间分配(space distribution),(假设主轴是水平方向)元素项的最终宽度受到当前行剩余空间(或不足空间)的影响,就像是有弹性一样会膨胀和收缩。
- 强大的对齐支持(align and justify),align和justify本质上来说,是定义多余(空白)的空间要放在哪里。align(align-items, align-content)定义了交叉轴方向上的多余(空白)空间分布,而justify(justify-content)定义了主轴方向的多余(空白)空间要分布。
为了方便讨论,我们假设主轴是水平方向,当主轴是垂直方向的时候是同理的。
对align和justify的思考
主轴方向的多余空间
justify-content
定义的是主轴方向的多余空间要如何分布。
主轴方向的多余空间的出现是因为容器宽度 > 元素项宽度之和。如图:
这个可交互实例来自MDN。
等一下,不是说 【主轴方向的多余空间会分配给元素项->使元素项膨胀->元素项占满主轴的空间】 的吗?为什么这里又有多余的空间来给justify-content
分发呢?这是因为元素项不一定会膨胀(flex-frow
的默认值为0,默认不膨胀),即使膨胀,膨胀后的宽度也会受到max-width
的约束。因此有很多时候,主轴在元素项膨胀以后还是有多余空间的。
一个行内,交叉轴方向的多余空间
align-items
定义的是一个行内,交叉轴方向的多余空间要如何分布。
一个行内,交叉轴方向的多余空间的出现是因为行的高度大于项的高度。由于各个项的高度不一致,比较高的项会将整行的高度撑开,对于那些比较矮的项,在它的垂直方向上就会出现多余空间。如下图:
这个可交互实例来自MDN。
关于高度撑开的讨论,见用css控制元素高度:自底向上和自顶向下的方法。
行与行之间,交叉轴方向的多余空间
align-content
定义的是行与行之间,交叉轴方向的多余空间要如何分布。
在这里说的“行”,指的是一个flex容器内,由于flex-wrap: wrap造成的换行(下面会讨论到换行),而不是指【第一个flex容器是一行,第二个flex容器是第二行】!
行与行之间,交叉轴方向的多余空间的出现是因为容器高度 > 容器内各行的高度之和。
前面说过,一个行的高度是由这一行中最高的项撑开的。一个flex容器,默认的时候(height:auto),其高度也是被其内部的所有行的高度撑开的,在这个时候容器的高度恰好等于所有行的高度之和,不存在“行与行之间,交叉轴方向的多余空间”。
但是如果容器本身定义了height: 10000px呢?它的高度就固定了,不会受到其内部的行的影响。这时候,如果所有行的高度之和不足以填满容器高度,交叉轴方向就会出现多余空间。如图:
这个可交互实例来自MDN。
对空间分配的思考
flex是如何计算项的宽度的?
所有项先按照原始宽度在容器中排列。
原始宽度由flex-basis决定,由于flex-basis默认值是auto(意思是取content-box的宽度作为flex-basis),因此一般width就是原始宽度。如果没有定义width,则width由项的子元素撑开。
如果容器有多余的宽度,则将这些多余宽度分配给每个项(分配比例由flex-grow控制),使得项的宽度增加,得到每个项的flex宽度。最终宽度基于flex宽度,但还会受到min-width、max-width的限制。
如果所有项的原始宽度已经超过了容器元素的宽度,那么会先检查flex-wrap
是否允许换行,如果允许换行,则换行以后再计算flex宽度;如果不允许换行,则将超出的宽度分配给每个项(分配比例由flex-shrink控制),使得项的宽度减小,得到每个子元素的flex宽度。最终宽度基于flex宽度,但还会受到min-width、max-width的限制。
总结来说就是,width决定原始宽度,flex-grow/flex-shrink决定分配比例,min-width、max-width限制最终宽度。
flex宽度计算的例子(可在浏览器中打开):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div class="container">
<div class="flex">
<div class="content1">
<div class="inner1"></div>
</div>
<div class="content2">
<div class="inner2"></div>
</div>
</div>
</div>
</body>
<style>
.flex {
display: flex;
width: 1000px;
/* 容器元素的剩余剩余宽度将被分配 */
}
.content1 {
flex-grow: 1;
height: 100px;
background-color: chocolate;
/* 没有定义width,则由它的子元素撑开 */
}
.content2 {
flex-grow: 1;
height: 100px;
background-color: aqua;
/* 没有定义width,则由它的子元素撑开 */
}
.inner1 {
height: 50px;
background-color: cornflowerblue;
/* 将父元素的宽度撑开为100px */
width: 100px;
}
.inner2 {
height: 50px;
background-color: greenyellow;
/* width设置为百分比时,无法撑开父元素,因此父元素的原始宽度为0 */
width: 100%;
}
</style>
</html>
计算过程:
content1原始宽度100px,content2原始宽度0px。剩余宽度为1000px-100px=900px。
由于content的flex-grow都相等,因此剩余宽度被平均分配,每个content分到450px。
content1最终宽度100px+450px=550px,content2最终宽度0px+450px=450px。
开发时布局的一般流程
根据UI设计,确定需要多少“行”来显示所有内容,然后确定每一“行”有哪些“项”。一个“项”本身也可以成为容器,包含一行或多行。
这里的“行”指的就是一个
flex-direction:row
的容器了(与之前的讨论不同)。它可以设置flex-wrap:wrap
,使得一个“行”容器在宽度不够容纳子元素的时候,在容器内部产生换行。- 对每一“行”,定义其样式。行是一个flex容器(display:flex)。并使用justify-content、align-items来定义元素在容器中的分布方式。通过margin-top来定义行之间的纵向距离。
- 对每一“项”,定义其样式。使用margin、padding来对元素位置进行微调。合理使用flex-grow、flex-shrink、width、min-width、max-width来调整元素的宽度。通过margin-left来定义元素之间的横向距离。如果这“项”本身也是一个容器(包含一行或多行),返回第2步。
参考资料
本文转载于猿2048:对Flex布局的总结与思考
对Flex布局的总结与思考的更多相关文章
- flex布局帮助你快速实现布局
flex布局可以帮我们快速布局一些区块,实现你想要的效果,不用再去float,position之类的.我们在布局网页的时候很多时候都是一些特殊布局,flex就能帮我快速去布局,不需要去定位. 任何一个 ...
- flex布局大全 2019
有句话叫做:存在即是合理. 最近很喜欢flex布局模式,不过还在摸索中,这里正一边在项目中使用和总结,也在学习一些大牛们总结的东西和布局思考. 鉴于自己很苦恼,到处去ha资料,真的,就没有一个系统的, ...
- flex布局大全
有句话叫做:存在即是合理. 最近很喜欢flex布局模式,不过还在摸索中,这里正一边在项目中使用和总结,也在学习一些大牛们总结的东西和布局思考. 鉴于自己很苦恼,到处去ha资料,真的,就没有一个系统的, ...
- Flex 布局教程:语法篇
作者: 阮一峰 网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便 ...
- Flex 布局教程:实例篇
该教程整理自 阮一峰Flexible教程 今天介绍常见布局的Flex写法.你会看到,不管是什么布局,Flex往往都可以几行命令搞定. 我的主要参考资料是Landon Schropp的文章和Solved ...
- 在移动端中的flex布局
flex布局介绍: flex布局很灵活, 这种布局我们也可以称之为弹性布局, 弹性布局的主要优势就是元素的宽或者高会自动补全; flex布局实例: 比如有两个div,一个div的宽度为100px, ...
- css flex布局
关于flex布局的一些简单用法 效果(下图) 实现代码: <!--html--> <div class="wrap"> <div class=&quo ...
- FLEX布局的一些问题和解决方法
前言 露珠最近研究了一下flex的布局方式,发现项w3c推出的这套布局解决方案对于日益复杂的前端开发布局来说是确实是一利器,并且在不同的屏幕上实现了真正的响应式布局:不再单纯地依赖百分比和float的 ...
- CSS之flex布局
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
随机推荐
- Hive表数据同步到es
1.首先服务器节点,进入到对应的数据库.2. 然后找到要同步的表,show create table + 表名查看一下或者自己可以新建一个表,用来测试原表,如下 CREATE TABLE `wb_tm ...
- Qt:QReadWriteLock
0.说明 QReadWriteLock类提供了读写锁. 读写锁是一种保护那些可以读写的资源的同步工具,如果有多个线程同时要进行读操作,但是有一个线程想要写入,那么所有其他线程都会等待直到这个写线程完成 ...
- WPS:从某一页开始编号,并且奇数页偶数页页眉页脚的页码位置不同
1.开始页的页眉页脚同时取消勾选"同前页" 此后,这一页就是以后所有页的第一页了 2.删去开始页之前所有的页眉页脚 3.页眉页脚选项中,设置奇偶页不同,其它都不用设置
- (第二章第一部分)TensorFlow框架之文件读取流程
本章概述:在第一章的系列文章中介绍了tf框架的基本用法,从本章开始,介绍与tf框架相关的数据读取和写入的方法,并会在最后,用基础的神经网络,实现经典的Mnist手写数字识别. 有四种获取数据到Tens ...
- SpringSecurity原理解析以及CSRF跨站请求伪造攻击
SpringSecurity SpringSecurity是一个基于Spring开发的非常强大的权限验证框架,其核心功能包括: 认证 (用户登录) 授权 (此用户能够做哪些事情) 攻击防护 (防止伪造 ...
- pd.cut和pd.qcut()之间的区别
- Windows10 1809版本Windows自动更新服务无法禁用问题解决方案
症状 Windows Update服务已经在服务管理器中禁用,但是莫名奇妙的会被自动设置为手动,并会自动下载补丁.原因 微软加强了系统更新服务的保护措施,导致按照原有的禁用服务方法,能够随时被恢复.解 ...
- 使用.Net6中的System.Text.Json遇到几个常见问题及解决方案
前言 以前.NetCore是不内置JSON库的,所以大家都用Newtonsoft的JSON库,而且也确实挺好用的,不过既然官方出了标准库,那更方便更值得我们多用用,至少不用每次都nuget安装Newt ...
- rest-framework之视图和源码解析
视图和源码解析 通过使用mixin类编写视图: from rest_framework import mixins from rest_framework import generics class ...
- request的自动urlencode问题解决
今天写盲注脚本的时候,由于题目对空格进行了过滤,所以必须要用%09进行代替,然而当我在脚本中,将payload的空格替换成%09的时候,抓包发现进行了两次编码,导致脚本一直跑不通. 自己在网上也没有找 ...