文章目录
flex布局
flex布局两个属性,容器和项目。
一旦我们开启弹性布局后,项目(也就是设为dispaly:flex元素的子元素)即使为块级元素,它的宽度仍不会是父亲的100%
,因为flex从字面上理解就是弹性布局吗,所以块级元素的宽度为内容所撑起的宽度。
早期CSS三大难题包括:垂直居中、列等宽和和自适应宽
设为 Flex 布局以后,子元素的float
、clear
和vertical-align
属性将失效。
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。
项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。
任何容器都可以设为flex(或者inline-flex)
.container {
display: flex; /* or inline-flex */
容器属性
有:
- flex-direction
- flex-wrap
- justify-content
- align-items
- align-content
项目属性
有:
- order
- flex-grow
- flex-shrink
- flex-basis
- flex
- aligin-self
一、flex容器属性
1、flex-direction
项目的排列方向。默认row,即横向水平向右排列
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
2、flex-wrap
3、flex-flow
flex-direction
属性和flex-wrap
属性的简写形式,默认值为row nowrap
。
.container {
flex-flow: <flex-direction> || <flex-wrap>;
}
.container {
justify-content: flex-start | flex-end | center | space-between | space-around;
}
4、justify-content
项目在main-axis上的对齐方式。默认为flex-start。
-
space-between:
- flex items 之间的距离相等。
- 与main start、main end两端对齐。
-
space envely:
- flex items 之间的距离相等。
- flex items(也叫项目)与main start、main end之间的距
等于
flex items之间距离。
-
space-around
- flex items之间的距离相等。
- flex items(也叫项目)与main start、main end之间的距离是flex items之间距离
一半
。
5、align-items
项目在cross-axis(交叉轴)上的对齐方式。默认flex-start
.container {
align-items: flex-start | flex-end | center | baseline | stretch | normal;
}
-
normal: 在弹性布局中,效果和stretch一样。
-
stretch:当flex items 在cross axis方向的 size 为 auto 时(即我们没有设置他的高度),会自动拉伸至
填充
flex contanier -
baseline: 与基准线对齐。
6、align-content
定义了多行flex itmes 在cross axis 上的对齐方式。如果项目只有一根轴线(即项目只有一行),该属性不起作用。用法与justify-conten类似
。
.container {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
-
flex-start:
-
flex- end
-
align-content: space-between
二、项目属性
1、order
它决定了flex items 的排布顺序,
- 可以设置为任意整数(正整数,负整数,0),值越小排在前面。
- 默认值为0.
.item {
order: <integer>; /* default 0 */
}
2、flex-grow
flex-grow
属性定义项目的放大比例,默认为0
,即如果存在剩余空间,也不放大。
如果所有项目的flex-grow
属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow
属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
.item {
flex-grow: <number>; /* default 0 */
}
3、flex-shrink
flex-shrink
属性定义了项目的缩小比例,默认为1
,即如果空间不足,该项目将缩小
。
如果所有项目的flex-grow
属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow
属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
.item {
flex-shrink: <number>; /* default 1 */
}
4、flex-basis
flex-basis
属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto
,即项目的本来大小。
.item {
flex-basis: 具体的宽度数值(100px) | auto; /* default auto */
}
决定flex items 最终 base size的因素,优先级从高到低
- max-width\max-height\min-width\min-height
- flex-basis
- width\height
- 内容本身的size
所以如果在项目的属性中,我们同时设置了宽度width和felx-basis这两个属性,那么width属性不生效。
5、flex
flex
属性是flex-grow
, flex-shrink
和 flex-basis
的简写,属性可以指定1个,两个,或者3个值。默认值为flex:initial,即三个值分别为 0 1 0%
,也就是说flex-grow
, flex-shrink
各自是各自的默认值,而flex-basis
为0%
,也就是初始不占宽度。
单值语法 :值必须为以下其中之一:
- 一个无单位的数(
number
);他会被当做flex-grow
的值。- 即此时flex-basis的值一直为0%,flex-shrink的值一直为1,flex为数值且改变时候
不会改变 flex-basis和flex-shrink的值。
- 即此时flex-basis的值一直为0%,flex-shrink的值一直为1,flex为数值且改变时候
- 一个有效的宽度(
width
)值,如100px;它会被当做flex-basis
的值。- 即此时 flex-grow为 1, flex-basis为 1, flex-basis为 100px(
注意flex-grow的值不为默认值 0
)
- 即此时 flex-grow为 1, flex-basis为 1, flex-basis为 100px(
- 关键字 0 、none 、auto、1
flex :initial 适合做小控件的分布布局,默认
flex:0 不经常用 ,适合替换元素下的文字内容不超过替换元素(设置在替换元素的父元素上)(0 1 0%)
flex :1 经常用来做等分布局,当希望元素充分利用剩余空间,同时不会侵占元素应有的宽度的时候。(1 1 0%)
flex: auto 用来做宽度根据内容宽度不均分的标题导航栏 (1 1 auto)
flex: none 适合用在内容不能换行的小控件身上。如按钮。(0 0 auto)
-
双值语法:
- 第一个值必须为一个无单位数,并且它会被当做
flex-grow
的值。 - 第二个值必须为以下之一:
- 一个无单位数:它会被当做
flex-shirnk
的值。 - 一个有效的宽度值,它会被当做
flex-basis
的值。
- 一个无单位数:它会被当做
- 第一个值必须为一个无单位数,并且它会被当做
-
三值语法:
- 第一个值必须为一个无单位数,并且它会被当做
flex-grow
的值。 - 第二个值必须为一个无单位数,并且它会被当做
flex-shirnk
的值。 - 第三个值必须为一个有效的宽度值,并且它会被当做
flex-basis
的值。
- 第一个值必须为一个无单位数,并且它会被当做
-
该属性有四个快捷值:
auto
(1 1 auto
)和1
(1 1 0%)
类似,0
(0 1 0%)
和none
(0 0 auto
)类似。
flex :0 元素不会弹性增大,但是会弹性缩小,且考虑到flex-basis的值为0%,因此设置了flex:0 的元素表现为最小内容宽度。
flex: none 元素尺寸和flex: 0一样不会自动增大,但是
也不会
自动缩小。且考虑到此时flex-basis的属性值为 auto,故设置了flex:none 的尺寸的最终尺寸最终表现为最大内容宽度。
替换元素: 视频图片按钮属于替换元素,替换元素的首选最小宽度是元素内容自身的宽度。
最终的首选内容宽度: 一个元素最终首选内容宽度是所有内部子元素中最大的那个首选内容宽度。
flex:initial—— flex:0 1 auto
flex:initial是flex的默认属性,具体表现为,当容器有剩余空间时不增长,当容器空间不足时会缩小,尺寸自适应内容;
效果如下所示:
代码如下所示:(下面例子代码类似,只是flex值改变,就不做展示)
<h4>flex:initial</h4>
<div class="container">
<div class="iten">天高地迥</div>
<div class="iten">觉宇宙之无穷</div>
<div class="iten">兴尽悲来</div>
<div class="iten">识盈虚之有数</div>
</div>
<style>
.container{
display: flex;
border:1px red solid;
width: 400px;
}
.container div{
border: 1px blue solid;
flex:initial;
}
</style>
flex:0——flex: 0 1 % 与 flex: none —— flex: 0 0 auto
flex:0与flex:none 两个对应的flex-grow是0,flex-shrink属性前者为1,后者为0,且flex-basis不同;故,flex:0,会表现为“一柱擎天”效果
,flex:none 具体表现为元素尺寸不会弹性增大,也不会弹性减小
。
- flex:0
- flex-basis:0%表示固定尺寸是0,且元素的flex-basis为 1
- flex: none
- flex-basis: auto表示固定尺寸由内容决定,由于元素不具有弹性(不会增大,不会缩小),因此元素内的内容不会换行
效果图如下所示:
flex:1——flex: 1 1 0% 与 flex:auto——flex:1 1 auto
flex:1与flex:auto 两个对应的flex-grow和flex-shrink属性值都是1,只有flex-basis不同,这两种具体表现形式为,元素尺寸可以弹性增大,也可以弹性减小,在flex:1 时在尺寸不足时会优先最小化尺寸,flex:auto在尺寸不足时优先最大化内容尺寸。
效果如下所示:
上图体现了两者的区别,虽然都是充分分配容器内容,但是flex:1 的尺寸是较长的尺寸优先牺牲自己的尺寸,而flex:auto 中是较长的尺寸优先扩展自己的尺寸。
所以,flex:1 更适合在等比例列表
时使用,flex:auto适用于
元素充分利用剩余空间,比如头部导航文字多少不一致时
使用,如下图:
6、align-self
align-self
属性允许单个项目有与其他项目不一样
的对齐方式,可覆盖align-items
属性。默认值为auto
,表示继承父元素的align-items
属性,如果没有父元素,则等同于stretch
。
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
三、筛子布局
你会看到,不管是什么布局,Flex往往都可以几行命令搞定。
注意哈,Flex布局后,其子元素的float
、clear
、vertical-align
属性将失效。
骰子的一面,最多可以放置9个点。
下面,就来看看Flex如何实现,从1个点到9个点的布局。
单个Flex项
<body>
<div class="container box">
<div class="item"></div>
</div>
</body>
body{
background-color:#333;
}
.container{
background-color:#e7e7e7;
margin:16px;
padding:4px;
width:104px;height: 104px;
border-radius: 10%;
box-shadow:inset 0 5px white,
inset 0 -5px #bbb,
inset 5px 0 #d7d7d7,
inset -5px 0 #d7d7d7;
}
.item{
width:24px;height: 24px;
border-radius: 50%;
margin:4px;
background-color: #333;
box-shadow: inset 0 3px #111,
inset 0 -3px #555;
}
两个Flex项
<body>
<div class="container box">
<div class="item">1</div>
<div class="item">2</div>
</div>
</body>
body{
background-color:#333;
}
.container{
background-color:#e7e7e7;
margin:16px;
padding:4px;
width:104px;height: 104px;
border-radius: 10%;
box-shadow:inset 0 5px white,
inset 0 -5px #bbb,
inset 5px 0 #d7d7d7,
inset -5px 0 #d7d7d7;
}
.item{
width:24px;height: 24px;
border-radius: 50%;
margin:4px;
color:white;
text-align:center;
background-color: #333;
box-shadow: inset 0 3px #111,
inset 0 -3px #555;
}
三个Flex项
<body>
<div class="container box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
</body>
##### 四个Flex项
<body>
<div class="container box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
</body>
<body>
<div class="container box">
<div class="row">
<div class="item">1</div>
<div class="item">2</div>
</div>
<div class="row">
<div class="item">3</div>
<div class="item">4</div>
</div>
</div>
</body>
六个Flex项
<body>
<div class="container box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
</body>
<body>
<div class="container box">
<div class="row">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
<div class="row">
<div class="item">4</div>
</div>
<div class="row">
<div class="item">5</div>
<div class="item">6</div>
</div>
</div>
</body>
九个Flex项
<body>
<div class="container box">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
</body>
其余前端布局用flex实现
1. 网格布局
1.1 基本网格布局
最简单的网格布局,就是平均分布。在容器里面平均分配空间,跟上面的骰子布局很像,但是需要设置项目的自动缩放。
HTML代码如下。
<div class="Grid">
<div class="Grid-cell">...</div>
<div class="Grid-cell">...</div>
<div class="Grid-cell">...</div>
</div>
CSS代码如下。
.Grid {
display: flex;
}
.Grid-cell {
flex: 1;
}
1.2 百分比布局
某个网格的宽度为固定的百分比,其余网格平均分配剩余的空间。
HTML代码如下。
<div class="Grid">
<div class="Grid-cell u-1of4">...</div>
<div class="Grid-cell">...</div>
<div class="Grid-cell u-1of3">...</div>
</div>
.Grid {
display: flex;
}
.Grid-cell {
flex: 1;
}
.Grid-cell.u-full {
flex: 0 0 100%;
}
.Grid-cell.u-1of2 {
flex: 0 0 50%;
}
.Grid-cell.u-1of3 {
flex: 0 0 33.3333%;
}
.Grid-cell.u-1of4 {
flex: 0 0 25%;
}
2.圣杯布局
圣杯布局(Holy Grail Layout)指的是一种最常见的网站布局。页面从上到下,分成三个部分:头部(header),躯干(body),尾部(footer)。其中躯干又水平分成三栏,从左到右为:导航、主栏、副栏。
HTML代码如下。
<body class="HolyGrail">
<header>...</header>
<div class="HolyGrail-body">
<main class="HolyGrail-content">...</main>
<nav class="HolyGrail-nav">...</nav>
<aside class="HolyGrail-ads">...</aside>
</div>
<footer>...</footer>
</body>
CSS代码如下。
.HolyGrail {
display: flex;
min-height: 100vh;
flex-direction: column;
}
header,
footer {
flex: 1;
}
.HolyGrail-body {
display: flex;
flex: 1;
}
.HolyGrail-content {
flex: 1;
}
.HolyGrail-nav, .HolyGrail-ads {
/* 两个边栏的宽度设为12em */
flex: 0 0 12em;
}
.HolyGrail-nav {
/* 导航放到最左边 */
order: -1;
}
如果是小屏幕,躯干的三栏自动变为垂直叠加。
@media (max-width: 768px) {
.HolyGrail-body {
flex-direction: column;
flex: 1;
}
.HolyGrail-nav,
.HolyGrail-ads,
.HolyGrail-content {
flex: auto;
}
}
3.输入框的布局
我们常常需要在输入框的前方添加提示,后方添加按钮
HTML代码如下。
<div class="InputAddOn">
<span class="InputAddOn-item">...</span>
<input class="InputAddOn-field">
<button class="InputAddOn-item">...</button>
</div>
.InputAddOn {
display: flex;
}
.InputAddOn-field {
flex: 1;
}
4.悬挂式布局
有时,主栏的左侧或右侧,需要添加一个图片栏。
HTML代码如下。
<div class="Media">
<img class="Media-figure" src="" alt="">
<p class="Media-body">...</p>
</div>
CSS代码如下。
.Media {
display: flex;
align-items: flex-start;
}
.Media-figure {
margin-right: 1em;
}
.Media-body {
flex: 1;
}
5.固定的底栏
有时,页面内容太少,无法占满一屏的高度,底栏就会抬高到页面的中间。这时可以采用Flex布局,让底栏总是出现在页面的底部。
HTML代码如下。
<body class="Site">
<header>...</header>
<main class="Site-content">...</main>
<footer>...</footer>
</body>
CSS代码如下。
.Site {
display: flex;
min-height: 100vh;
flex-direction: column;
}
.Site-content {
flex: 1;
}
6.流式布局
每行的项目数固定,会自动分行。
CSS的写法。
.parent {
width: 200px;
height: 150px;
background-color: black;
display: flex;
flex-flow: row wrap;
align-content: flex-start;
}
.child {
box-sizing: border-box;
background-color: white;
flex: 0 0 25%;
height: 50px;
border: 1px solid red;
}