1. Flex布局与响应式布局
1.1 为什么需要响应式布局?
在电脑PC端,使用浮动,定位同时使用像素px单位就可以完成大部分布局,而且布局完之后不会有大问题,但是到了移动端,移动设备的屏幕尺寸多种多样,从小屏幕的智能手机到大屏幕的平板电脑,甚至是可穿戴设备,简单地运用和PC端一样的方式就会出现一些布局和排列的问题。
这里用PC端的缩放浏览器来举个例子,当浏览器缩小的时候,百度就只显示了一部分,无法在缩小的屏幕(浏览器窗口)中完全显示。
移动前端中常说的 viewport (视口)就是浏览器中用于呈现网页的区域。视口通常并不等于屏幕大小,特别是可以缩放浏览器窗口的情况下,为了确保在不同设备上都能够提供良好的用户体验,需要使用响应式布局来适应不同的屏幕尺寸。
1.2 响应式布局的解决方案
响应式布局有多种方案,比如:
媒体查询:它允许根据设备的特性(如屏幕宽度、设备类型等)应用不同的样式规则。通过使用媒体查询,可以针对不同的屏幕尺寸和设备类型应用不同的样式,从而实现响应式布局。
流式布局(百分比布局):它是一种基于相对单位(如百分比)进行设计的布局方式。在流式布局中,元素的宽度和高度相对于父元素或视口进行计算,使得它们可以根据可用空间的大小进行自适应调整。流式布局可以使页面在不同屏幕尺寸下保持比例和流动性。
Flex布局:Flexbox是CSS3中的一种弹性盒子布局模型,它提供了强大的排列和对齐功能,可以实现灵活的响应式布局。通过使用Flexbox属性和值,可以轻松地控制元素在容器中的位置、顺序和大小。
栅格系统:栅格系统是一种将页面划分为多个网格列的布局方式,通过定义网格列数和间距来布局页面内容。栅格系统通常与媒体查询和流式布局结合使用,以实现在不同屏幕尺寸下的响应式布局。流行的栅格系统包括Bootstrap的栅格系统和Foundation的栅格系统。
本文主要介绍Flex布局
1.3 Flex布局的优越性
排列灵活,样式简单:Flex布局在响应式解决方案中具有灵活的排列和对齐、自适应的弹性性质、自动换行和调整顺序以及容器和项目的灵活性等优点,可以通过简单的CSS属性设置来控制元素在容器中的位置和布局。通过设置容器的flex-direction、justify-content和align-items等属性,可以轻松实现水平或垂直方向上的排列和对齐需求。这种灵活性使得在不同设备上适应不同布局要求变得容易。相比起针对不同屏幕来设置的媒体查询,相同的样式设置就可以适配多种屏幕尺寸,Flex布局非常的方便。
自动换行,调整顺序:在移动设备上,屏幕空间有限,需要在有限的空间中合理布局元素。Flex布局可以通过设置flex-wrap属性实现自动换行,使得项目可以在一行排列不下时自动换行到下一行。此外,还可以使用order属性调整项目的显示顺序,以便在移动设备上优先显示重要内容。这种自动换行和调整顺序的特性使得在小屏幕设备上实现良好的用户体验变得简单。
除了响应式布局外,在PC端也可以利用Flex布局来替代浮动和定位,完成很好的元素排列,让开发者免去使用float,position来布局的不便。最常见的八股文面试题,垂直水平居中就可以用flex布局轻松完成,这也是工作中较为常用的方式。
2. Flex布局定义
Flex布局对于元素的内联(行内)或块级的性质是不关心的。在Flex布局中,元素会根据容器和项目的属性进行排列,无论元素是行内元素还是块级元素。采用Flex布局的元素,称为Flex容器(flex container),简称”容器”。Flex容器的所有子元素自动成为容器成员,称为Flex项目(flex item),简称”项目”。
容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。
项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。
3. Flex容器属性
3.1 开启flex布局display:flex
元素写了这个属性之后,就变成了一个flex的容器,就可以通过flex布局相关的方式去操作排列子元素。
[/span>style
.parent{
display: flex;
Width</span>: 400px;
Height</span>: 200px;
background-color:blueviolet;
}
.child{
Width</span>: 100px;
Height</span>: 50px;
background-color: aqua;
border: 1px solid black;
}
[/span>body
[/span>div class="parent"
[/span>div class="child"
[/span>div class="child"
开启flex布局之后,没有进行其他的设置,可以看到这个排列和没有开启flex布局的时候是不一样的,2个块级元素,并没有上下排列,而是已经排列在左右。开启flex布局后,容器中的项目默认会沿着主轴进行排列,此时没有对容器和项目进行其他的设置,主轴也按照默认的方向水平放置,所以2个子盒子都沿着主轴水平排列了。
3.2 改变主轴的方向flex-direction属性
flex-direction属性决定了主轴的方向,所有容器中的项目都会根据主轴方向来排列。
flex-direction 属性有四个可能的取值:
row(默认值):Flex 项目水平排列,起点在左端,终点在右端。主轴从左到右。
row-reverse:Flex 项目水平排列,起点在右端,终点在左端。主轴从右到左。
column:Flex 项目垂直排列,起点在顶部,终点在底部。主轴从上到下。
column-reverse:Flex 项目垂直排列,起点在底部,终点在顶部。主轴从下到上。
图中显示flex-direction的值为row时元素按顺序从左往右横向排列,子元素贴着父元素的左侧
.parent{
display: flex;
flex-direction: row;
Width</span>: 400px;
Height</span>: 200px;
background-color:blueviolet;
}
图中显示flex-direction的值为row-reverse时元素按顺序从右往左横向排列,子元素贴着父元素的右侧(代码同上)
图中显示flex-direction的值为column时元素按顺序从上往下竖向排列,子元素贴着父元素的顶部,这一点类似于常规的文档流中块级元素的排列(代码同上)
图中显示flex-direction的值为//代码效果参考:http://hnjlyzjd.com/hw/wz_25400.html
column-reverse时元素按顺序从下往上竖向排列,子元素贴着父元素的底部(代码同上)总的来说,flex-direction属性虽然简单,但是有重要的作用,可以
控制主轴方向:flex-direction 属性决定了主轴的方向,即 Flex 项目在水平方向或垂直方向上的排列。通过设置不同的取值,我们可以实现水平排列(左到右或右到左)或垂直排列(从上到下或从下到上)的布局。
确定起点和终点:flex-direction 属性的取值影响了 Flex 项目在主轴上的起点和终点的位置。在 row 值下,起点位于左端,终点位于右端;在 row-reverse 值下,起点位于右端,终点位于左端;在 column 值下,起点位于顶部,终点位于底部;在 column-reverse 值下,起点位于底部,终点位于顶部。这种控制起点和终点的能力对于设计布局非常有用。
影响项目排列顺序:flex-direction 属性还决定了 Flex 项目在主轴上的排列顺序。在默认的 row 值下,Flex 项目按照其在 HTML 结构中的顺序从左到右排列;在 row-reverse 值下,项目按照相反的顺序从右到左排列;在 column 值下,项目按照结构顺序从上到下排列;在 column-reverse 值下,项目按照相反的顺序从下到上排列。通过改变项目的排列顺序,我们可以调整 Flex 布局的外观和行为。
3.3 改变换行方式flex-//代码效果参考:http://hnjlyzjd.com/hw/wz_25398.html
wrap属性flex-wrap属性决定了换行相关的策略。它决定了当弹性容器的宽度不足以容纳所有子元素时,是否允许子元素换行并如何排列。
它有几个常用的属性值:
nowrap(默认值):子元素不换行,尽可能地将它们放在一行内,即使溢出弹性容器的边界。
wrap:如果子元素在一行内放不下,将它们进行换行,从新行开始排列。
wrap-reverse:与 wrap 相同,但换行时的排列顺序与正常顺序相反。
当没有写flex-wrap属性时,所有元素会默认沿着主轴在一行(或一列)排列。这也就和写了flex-wrap: nowrap是等效的
在已经给子项目设置了100px的宽度的情况下,6个项目仍然会排在同一行,而此时父元素的宽度也只有400px,说明此时子项目的宽度已经被压缩了变成了小于100px。
[/span>style
.parent {
display: flex;
Width</span>: 400px;
Height</span>: 200px;
background-color: blueviolet;
}
.child {
Width</span>: 100px;
Height</span>: 50px;
background-color: aqua;
border: 1px solid black;
}
[/span>body
[/span>div class="parent"
[/span>div class="child"
[/span>div class="child"
[/span>div class="child"
[/span>div class="child"
[/span>div class="child"
[/span>div class="child"
当希望子项目完成换行的时候可以设置flex-wrap: wrap
明显可以看到,图片已经完成了换行效果,但是这里上下两行元素出现了空隙,似乎与预期效果不符合,这是由于多行对齐时的align-content的默认值导致的,具体align-content用法会在后文解释。
.parent {
display: flex;
flex-wrap: wrap;
Width</span>: 400px;
Height</span>: 200px;
background-color: blueviolet;
}
.child {
Width</span>: 100px;
Height</span>: 50px;
background-color: aqua;
border: 1px solid black;
}
当换行属性设置为flex-wrap: wrap-reverse,也会完成换行,但是换行的顺序与前面相反,第一行会在最下面,最后一行在上面
3.4 主轴对齐方式justify-content属性
justify-content是flex布局中的重要属性之一,用于定义和调整弹性容器中项目在主轴上的对齐方式。它控制项目沿着主轴的分布方式,包括项目之间的间距、对齐和对齐方式的调整。
这个属性常用的有以下几个值
flex-start(默认值):将项目对齐到弹性容器的起始位置。项目靠主轴起始端对齐。
flex-end:将项目对齐到弹性容器的末尾位置。项目靠主轴末尾端对齐。
center:将项目在主轴上居中对齐。项目在主轴上平均分布,两端留有相同的空白。
space-between:将项目在主轴上平均分布,并使项目之间的间距相等。首个项目对齐到主轴起始端,最后一个项目对齐到主轴末尾端。
space-around:将项目在主轴上平均分布,并使项目之间的间距相等。首尾两端的间距是相邻项目间距的一半。
space-evenly:将项目在主轴上平均分布,并使项目之间的间距相等。首尾两端和相邻项目之间的间距相等。
不写justify-content或者justify-content的值为flex-start时,flex容器内部的项目会按顺序沿着主轴排列,也就是当主轴是水平的时候就横过来排列,主轴是竖直的就竖过来排列。
以较常见的flex-direction取默认值row的时候举例,有类似于float:left的效果,但是不会出现子元素浮动后脱离文档流导致父元素高度塌陷的问题。
.parent {
display: flex;
justify-content: flex-start;
Width</span>: 400px;
Height</span>: 200px;
background-color: blueviolet;
}
justify-content的值为flex-end时,子元素也就是flex容器会靠主轴的终点处对齐,与前面的flex-start呈现相反的对齐排列效果。
以较常见的flex-direction取默认值row的时候举例,类似于float:right的效果,但是与右浮动不同的是右浮动会导致元素倒序排列而flex-end会保持元素的顺序,元素的排列顺序仍然是1,2,3。
1
2
3
对于右浮动会出现倒序的原因,这里进行简单的解释:
浮动的元素直到碰到边缘或另一个浮动元素的边缘为止,而代码又是从上往下执行,对于第一个child会优先进行浮动,碰到父盒子右边缘,结束,第二个child再开始浮动,碰到第一个child的左边缘再结束,第三个child在第二个child浮动结束后再浮动,就贴着第二个child左边缘。
解决右浮动倒序的方法可以有以下几种:
利用flex布局的flex-end,如上图所示
倒序书写元素,这样就可以正序排列了。
对于多个右浮动的child,再在外面加一层div包裹,先让外层的div右浮动(只有一个盒子,不会出现顺序问题的同时又能靠右对齐),然后让每个child左浮动(左浮动不会导致顺序出现问题,又可以实现浮动效果),代码和图片如下
[/span>style
.parent {
Width</span>: 400px;
Height</span>: 200px;
background-color: blueviolet;
}
.wrapper {
float: right;
}
.child {
float: left;
Width</span>: 100px;
Height</span>: 50px;
background-color: aqua;
border: 1px solid black;
}
[/span>body
[/span>div class="parent"
[/span>div class="wrapper"
[/span>div class="child"
[/span>div class="child"<span style="color: rgba(0, 0, 255, 1)"]2<span style="