CSS初入门:flex布局
flex布局
1、简介
Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。布局的传统解决方案,基于盒模型,依赖 display 属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。而Flex 布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持。任何一个容器都可以指定为 Flex 布局。
2、关于flex弹性盒模型
采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目"。
对于某个元素只要声明了display: flex;
,那么这个元素就成为了弹性容器,具有flex弹性布局的特性。如下:
<div class="father">
<div class="son1">弹性元素1</div>
<div class="son2">弹性元素2</div>
<div class="son3">弹性元素3</div>
</div>
.father{
width: 600px;
height: 400px;
background-color: antiquewhite;
display:flex;
margin-left: 50px;
margin-top: 50px;
}
.son1{
width: 100px;
height: 100px;
background-color: red;
}
.son2{
width: 100px;
height: 100px;
background-color: blue;
}
.son3{
width: 100px;
height: 100px;
background-color: green;
}
flex盒模型特点:
- 每个弹性容器都有两根轴:主轴和交叉轴,两轴之间成90度关系。注意:水平的不一定就是主轴。
- 每根轴都有起点和终点,这对于元素的对齐非常重要。
- 弹性容器中的所有子元素称为<弹性元素>,弹性元素永远沿主轴排列。
- 弹性元素也可以通过
display:flex
设置为另一个弹性容器,形成嵌套关系。因此一个元素既可以是弹性容器也可以是弹性元素。
3、盒模型属性
3.1 容器属性
(1)flex-direction(控制主控方向)
主轴的方向处理
flex布局是一种一维布局模型,一次只能处理一个维度(一行或者一列)上的元素布局。flex布局大部分的属性都是作用于主轴的,在交叉轴上很多时候只能被动地变化。
可以在弹性容器上通过flex-direction
修改主轴的方向。如果主轴方向修改了,那么交叉轴就会相应地旋转90度,弹性元素的排列方式也会发生改变,因为弹性元素永远沿主轴排列。
flex-direction属性的取值(排列方向)
(1)row(默认)(水平方向)
(2)row-reverse(水平相反方向)
(3)column(垂直方向)
(4)column-reverse(垂直相反方向)
例如,默认情况下的flex布局
例如,假设将主轴设置为水平相反方向
补充:再子元素中也使用flex布局会怎么样??如下
<div class="father">
<div class="son1">1
<div class="son1_1">1</div>
<div class="son1_2">2</div>
<div class="son1_3">3</div>
</div>
<div class="son2">2</div>
<div class="son3">3</div>
</div>
.father{
width: 600px;
height: 400px;
background-color: antiquewhite;
display:flex;
flex-direction: row;
margin-left: 50px;
margin-top: 50px;
}
.son1{
width: 100px;
height: 100px;
background-color: red;
display: flex;
}
.son2{
width: 100px;
height: 100px;
background-color: blue;
}
.son3{
width: 100px;
height: 100px;
background-color: green;
}
.son1 *{
background-color: yellow;
width: 20px;
height: 20px;
border: 2px solid black;
}
如果改变子元素中flex布局的主轴方向,
flex-direction: row-reverse;
(2)flex-wrap(换行)
沿主轴方向的排列处理
弹性元素永远沿主轴排列,那么如果主轴排不下,该如何处理?可以通过设置flex-wrap
属性可使得主轴上的元素不换行、换行、反向换行。
flex-wrap属性的取值:
(1)nowrap(默认)(不换行)
(2)wrap(换行)
(3)wrap-reverse(换行并反转)
假设,容器的宽度是600px,容器中有7个100px的子元素,有下面几种情况
(1)当主轴方向不换行时
.father{
width: 600px;
height: 400px;
background-color: antiquewhite;
display:flex;
flex-direction: row;
margin-left: 50px;
margin-top: 50px;
}
.son1{
width: 100px;
height: 100px;
background-color: red;
display: flex;
}
.son2{
width: 100px;
height: 100px;
background-color: blue;
}
.son3{
width: 100px;
height: 100px;
background-color: green;
}
<div class="father">
<div class="son1">1</div>
<div class="son2">2</div>
<div class="son3">3</div>
<div class="son1">4</div>
<div class="son2">5</div>
<div class="son3">6</div>
<div class="son1">7</div>
</div>
结果:
可以发现,原本flex盒子下600px只能存放6个宽度为100px的子元素的,但现在一行却存放了7个元素,并且这七个元素的宽度都改变了。所以这里就有个规律,在不换行的情况下,如果一行中所有子元素的总宽大于flex盒子的宽,那么子元素的宽就会随之改变,子元素的宽度 = 所有子元素的总宽/子元素个数
(2)主轴方向换行的情况下
flex-wrap:wrap;
1、如果子元素都是等宽的
2、如果子元素不等宽
(3)wrap-reverse
同样表示换行,需要注意的是第一排会紧贴容器底部。
(3) flex-flow
flex-flow
属性是flex-direction
与flex-wrap
属性的简写集合,默认属性为row nowrap
,即横向排列,且不换行。
(4)justify-content(主轴上的元素对齐)
取值:
主轴上的对齐方式:
(1)flex-start(默认,向左对齐)
(2)flex-end(向右对齐)
(3)center(居中)
(4)space-between(左右两端对齐,即左右两侧项目都紧贴容器,且项目之间间距相等)
(5)space-around(项目之间间距为左右两侧项目到容器间距的2倍)
(6)space-evenly(项目之间间距与项目与容器间距相等,相当于除去项目宽度,平均分配了剩余宽度作为项目左右margin)
(5)align-items
用于控制项目在交叉轴排列方式,默认stretch即如果项目没设置高度,或高度为auto,则占满整个容器。
取值:
(1)flex-start(让项目在交叉轴紧贴容器顶部)
(2)flex-end(与flex-start相反)
(3)center(在交叉轴中心位置排列)
(4)baseline(让项目以第一行文字的基线为参照进行排列)
(5)stretch(默认)
注意
(1)常理来说justify-content与align-items默认分别处理项目主轴,交叉轴的对齐方式,但如果我们修改了flex-direction为column,它们处理的轴向会交换,也就是justify-content处理交叉轴,align-items处理主轴。
(2)通过给一个父元素设置justify-content:center;
和align-items:center;
可以使得其子元素垂直水平居中。
(6)align-content
作用:用于控制多行项目的对齐方式,如果项目只有一行则不会起作用,所以需设置flex-wrap: wrap;
取值:
(1)flex-start(让项目在交叉轴紧贴容器顶部)
(2)flex-end(让项目在交叉轴紧贴容器底部)
(3)center(让项目在交叉轴中心位置排列)
(4)space-between(上下两侧项目紧贴容器,上下项目之间间距相等)
(5)space-around(上下两侧项目之间间距为上下两侧项目与容器间距两倍。)
(6)space-evenly(上下两侧项目之间间距与上下两侧项目到容器之间间距相等)
(7)stretch(自动拉伸子元素)
3.2 项目属性
容器属性是加在父容器上的,而项目属性,就是写在项目/弹性元素上的,就好比容器属性给ul,项目属性给li差不多一个意思。
(1)order
取值:默认为0
作用:用于决定项目排列顺序,数值越小,项目排列越靠前
(2)flex-grow
取值:默认为0,用于决定项目在有剩余空间的情况下是否放大,默认不放大。补充:即便设置了固定高度同样也会放大。
第一种情况:假设默认三个项目中前两个个项目都是0,最后一个是1,最后的项目会占满剩余所有空间。
第二种情况:假设只有第一个项目默认为0,后面两个项目flex-grow均为1,那么后两个项目平分剩余空间
第三种情况:假设第一个项目默认为0,第二个项目为flex-grow:2,最后一个项目为1,则第二个项目在放大时所占空间是最后项目的两倍。
(3)flex-shrink
取值:默认为1
作用:用于决定项目在空间不足时是否缩小,即空间不足时整体一起等比缩小;注意,即便设置了固定宽度,也会缩小。但如果某个项目的flex-shrink设置为0,那么即便空间不够,自身也不会再缩小。
(4)flex-basis
取值:默认auto
作用:用于设置项目宽度,默认auto时,项目会保持默认宽度,或者以width为自身的宽度,但如果设置了flex-basis,权重会比width属性高,因此会覆盖width属性
上图中既设置了width又设置了flex-basis,但是却是以flex-basis为准。
(5)flex
作用:flex属性是flex-grow,flex-shrink与flex-basis三个属性的简写,用于定义项目放大,缩小与宽度。
取值:0 1 auto(默认)
div {
flex:0.5;
}
表示
flex-grow 值为 1,即在空间分配时等比例扩展;
flex-shrink 值为 1,即在空间不足时等比例收缩;
flex-basis 值为 0.5,即基础大小为 flex 容器的宽度的一半。
div {
flex:1;
}
表示
flex-grow 值为 1,即在空间分配时等比例扩展;
flex-shrink 值为 1,即在空间不足时等比例收缩;
flex-basis 值为 0%,项目的初始尺寸会变为 0,根据 flex-grow 和 flex-shrink 的值来调整
(6)align-self
作用:用于让个别项目拥有与其它项目不同的对齐方式,各值的表现与父容器的align-items属性完全一致
取值:(取值的作用同align-items一致)
(1)auto(默认)
(2)flex-start
(3)flex-end
(4)center
(5)baseline
(6)stretch
习题
习题一:模仿w3school网站的导航栏
代码实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>导航栏</title>
<style>
*{
list-style: none;
margin: 0;
padding: 0;
}
div{
margin:48px auto;
padding: 0;
}
#menu{
width: 1210px;
height: 50px;
background-color:#e8e7e3;
display: flex;
justify-content: space-around;
margin: auto;
padding: 0;
}
li{
/* display: block; */
line-height: 48px;
justify-content: space-around;
flex-grow: 2;
/* line-height: 50px; */
text-align: center;
}
#menu a{
text-decoration: none;
color: #838382;
display: block;
}
li:hover{
background-color: rgb(174, 177, 177);
}
</style>
</head>
<body>
<div>
<ul id="menu">
<li title="HTML/CSS 系列教程"><a href="#">HTML/CSS</a></li>
<li title="浏览器脚本教程"><a href="#">Browser Side</a></li>
<li title="服务器脚本教程"><a href="#">Server Side</a></li>
<li title="编程教程"><a href="#">Programing</a></li>
<li title="XML系列教程"><a href="#">XML</a></li>
<li title="建站手册"><a href="#">WebBuilding</a></li>
<li title="参考手册"><a href="#">Reference</a></li>
</ul>
</div>
</body>
</html>
习题二:模仿手机淘宝的导航栏
说明:图标可以随着网页放大而放大,缩小而缩小
代码实现如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=\, initial-scale=1.0">
<title>淘宝导航栏</title>
<style>
*{
margin: 0px;
padding: 0px;
}
/*让父标签满足flex布局*/
.outer{
display: flex;
/* 使得子标签div之间间距为左右两侧div标签到父标签间距的2倍*/
justify-content: space-around;
margin: 50px auto;
}
.inner{
text-align: center;
font-size: 20px;
}
div a{
text-decoration: none;
color: black;
}
/* 让图片填满整个div标签,使得其页面放大缩小时也能同比例放大缩小 */
.inner img{
width: 100%;
}
</style>
</head>
<body>
<div class="outer">
<div class="inner">
<a href="#">
<img src="../images/1.png" alt="天猫新品">
<p>天猫精品</p>
</a>
</div>
<div class="inner">
<a href="#">
<img src="../images/2.png" alt="今日暴饮">
<p>今日暴饮</p>
</a>
</div>
<div class="inner">
<a href="#">
<img src="../images/3.png" alt="天猫国际">
<p>天猫国际</p>
</a>
</div>
<div class="inner">
<a href="#">
<img src="../images/4.png" alt="天猫市场">
<p>天猫市场</p>
</a>
</div>
<div class="inner">
<a href="#">
<img src="../images/5.png" alt="充值中心">
<p>充值中心</p>
</a>
</div>
</div>
<div class="outer">
<div class="inner">
<a href="#">
<img src="../images/6.png" alt="机票酒店">
<p>机票酒店</p>
</a>
</div>
<div class="inner">
<a href="#">
<img src="../images/7.png" alt="金币庄园">
<p>金币庄园</p>
</a>
</div>
<div class="inner">
<a href="#">
<img src="../images/8.png" alt="阿里拍卖">
<p>阿里拍卖</p>
</a>
</div>
<div class="inner">
<a href="#">
<img src="../images/9.png" alt="淘宝吃货">
<p>淘宝吃货</p>
</a>
</div>
<div class="inner">
<a href="#">
<img src="../images/10.png" alt="分类">
<p>分类</p>
</a>
</div>
</div>
</body>
</html>
更多推荐
所有评论(0)