目录
一、概述
二、布局类型
1. 普通流布局
2. 浮动布局
3. 定位布局
(1) 相对定位relative
(2) 绝对定位absolute
(3) 固定定位fixed
(4) 定位补充
4. flex布局
5. grid布局
三、布局的应用
1. 双栏目布局实现
2. 三栏目布局实现
(1) position + margin 实现
(2) 圣杯布局
(3) 双飞翼布局
(4) flex布局实现
3. 响应式布局
(1) 媒体查询-CSS3-Media Query
(2) grid实现响应式布局
(3) Columns栅格系统
四、写在最后
五、参考资料
无论是前端还是客户端开发都离不开页面的展示,而页面是由布局和各种组件构成的。布局好比是建筑里的框架,而组件则相当于建筑里的砖瓦。组件按照布局的要求依次排列,就组成了用户所看见的界面。
比如Android开发者常用的布局方式有:线性布局(LinearLayout)、相对布局(RelativeLayout)、绝对布局(AbsoluteLayout)、网格布局(GridLayout)等。
IOS开发者常用的布局方式:手写Frame、自动布局(AutoLayout)、xib、storyboard等方式,我们这里主要介绍前端的布局方式。虽然目前大多数网站的构建都是通过成熟的框架搭建的,但是作为前端开发的基础,学习了解一下布局还是很有必要的。
页面布局(Layout):就是对页面的文字、图形或表格进行排布、设计。
研究布局的目的是让我们的页面尽可能的还原UI设计给我们的设计图,适配各种尺寸的屏幕,使其在各种尺寸屏幕上能很好地显示出我们的视图。
我们来看下我们Web开发中常用的几种布局类型:
这是页面默认布局的方式 ,每个元素都有默认空间,每个元素都是在父元素的左上角出现的,页面中的块元素都是按照从上到下的方式出现,每个块元素独占一行,页面中行内元素都是从左到右的方式排列。
每个元素都有一个默认的 display
值,这与元素的类型有关。对于大多数元素它们的默认值通常是 block
或 inline
。一个 block
元素通常被叫做块级元素。一个 inline
元素通常被叫做行内元素。比如 div
是一个标准的块级元素,页面在进行渲染时候,遇到块级元素会另起一行,而行内元素会在当前行进行展示。举个简单的例子:
html
标题
这是一个div块元素
这是一个行内元素
这是另一个行内元素
这是行内块元素
这是还是一个div块元素
div
元素是单独占一行的,而行内元素span
不会换行。其他常用的块级元素包括 p
、 h1——h6
、form
以及Html5中的新元素: header
、 footer
、 section
等等。常用的行内元素a
、input
、img
、label
等。display
的取值除了为block
跟inline
外还可以取值inline-block
,它表示行内块元素,如果一个块元素的display属性取值为inline-block,那么他就不在换行,比如我们这里的第二个div元素。如果一个行内元素display取值为inline-block那么它就具有了块元素的一些特性,例如我们可以改变它的尺寸。display
值是 none
。一些特殊元素的默认display
值是它,例如 script
。 display:none
通常被 JavaScript 用来在不删除元素的情况下隐藏或显示元素。它和 visibility
属性不一样。把 display
设置成 none
元素不会占据它本来应该显示的空间,但是设置成 visibility: hidden;
还会占据空间。display
还有一些其他取值,可以看这里属性:float
取值:none
: 默认,无浮动left
: 左浮动,让元素在父元素的左边,或者挨着已有的浮动元素right
: 右浮动,让元素在父元素的右边,或者挨着已有的浮动元素
我们看下它如何使用,正常情况下的布局:
正常布局
左侧
右侧
后面
现在我们分别给.left
跟.right
添加浮动属性,添加下面代码
.left {
float: left;
width: 100px;
height: 200px;
background-color: rosybrown;
}
.right {
float: right;
width: 100px;
height: 200px;
background-color: saddlebrown;
}
结果:
看下页面效果,左右两个模块倒是符合我们的预期,但是container
元素的背景没有了,我们检查下元素,可以看到container
的高度变成了0,last
只展示了文字,背景没有了。这就说到float属性的特点了:
特点:
解决浮动带来的影响
(1)可以直接设置父元素的高度,比如直接添加height:300px;
(2)为父元素设置overflow
取值 hidden
或者auto
(3)使用clear
属性,取值both
可以解决左右浮动带来的影响。这里注意:这里要给contariner
容器添加子元素
(4)在容器内添加一个CSS伪元素,并将其clear属性设置为both。
左侧
右侧
或者是
.container::after {
content: "";
display: table;
clear: both;
}
看下效果,符合我们的预期了
实际上浮动最主要的作用:是可以使块级元素在一行内显示。并且可以使文字可以环绕浮动元素进行排列。
position
,默认值:static
,根据其取值的的不同分为:position:relative
;position:absolute
;position:fixed
;position
属性取值不为static
,那么这个元素就被称为已定位元素。这里需要注意,后面在介绍这几种定位时,已定位元素会对他本身的位置有所影响。top
、left
、right
、bottom
,取值是以px为单位的数值,取值可以是正数也可以是负数,分别对应不同方向的偏移top
:取值为正,向下移动,取值为负数,向上移动bottom
:取值为正,向上移动,负值 向下移动。left
:取值为正,右移动,负值 左移动right
:取值为正 左移动,负值 右移动如何记忆:可以参考下面的图例,取值为正数时,都是向元素的内部进行靠拢,取值为负数时候都是向远离元素的位置移动。
relative
元素相对于他原来的位置进行距离偏移
用法:position:relative;
配合 top、left、right、bottom进行位置的微调
我们还是以上面的正常文档流布局为例,现在我们想让右侧块跟左侧块在一行显示,并且在左侧块的右边显示,实现下图的效果:
那么我们可以设置.right
的布局如下
.right {
position: relative;
top: -100px;
left: 50px;
width: 50px;
height: 100px;
background-color: saddlebrown;
}
absolute
元素会相对于离他最近的已定位的(三种定位方式的一中)祖先元素去实现位置的初始化跟偏移,祖先元素就是本元素的父级元素。如果没有已定位的祖先元素,那就相对于body去实现位置的初始化跟偏移。绝对定位元素会变成块级元素。
用法:position:absolute;
配合 top、left、right、bottom进行位置的微调
现在我们想让右侧块块叠加在左侧块之上显示,实现下图的效果:
那么我们可以设置.right
的布局如下
.right {
position: absolute;
top: 50px;
left: 0;
width: 50px;
height: 100px;
background-color: saddlebrown;
}
absolute
后 原先父元素的高度变化了,说明.right
脱离了文档流,不再占据页面空间。注意这里top: 50px;
的改变是相对于body改变的,其初始化位置为文档流的左上角,因为其父元素container
并不是已定位的元素。fixed
固定定位(position:fixed)元素会相对于视窗来定位,这意味着即便页面滚动,它还是会停留在相同的位置。和 relative 一样, top 、 right 、 bottom 和 left 属性都可用。
我们还是拿上面的例子,我们将last
固定在页面的右下角,设置last
的CSS如下
.last {
position: fixed;
right: 0;
bottom: 0;
width: 70px;
height: 75px;
background-color: red;
}
position:fixed
的元素也会脱离文档流。一旦将元素设置 已定位元素(position的取值不为static),元素可能会出现堆叠效果,堆叠效果的属性:
z-index
,取值:无单位的数子,数子越大越靠上
我们以上面绝对定位的例子来说明,设置了right
为绝对定位后,right
在left
的上面,此时如果想让left
在上,right
在下,实现下面效果:
设置left
的CSS代码
.left {
position: relative;
z-index: 10;
width: 50px;
height: 100px;
background-color: rosybrown;
}
position: relative;
是没有效果的,父子元素之间无法调整堆叠效果,子元素压在父上。flex布局又叫弹性布局,是一种为一维布局而设计的布局方法。一维的意思是你希望内容是按行或者列来布局。你可以使用display:flex
来将元素变为弹性布局。
我们直接看例子:实现7个item横向排列
flex布局2
item0
item1
item2
item3
item4
item5
item6
item7
上面的代码基本基本涵盖了我们常用的flex的属性
display:flex
: 设置container
容器为弹性布局
flex-direction
:决定主轴的方向,项目横向或是纵向排列
取值:row | row-reverse | column | column-reverse;row
(默认值):主轴为水平方向,起点在左端。row-reverse
:主轴为水平方向,起点在右端。column
:主轴为垂直方向,起点在上沿。column-reverse
:主轴为垂直方向,起点在下沿。
justify-content
: 定义Item在主轴上如何对齐。
取值:flex-start | flex-end | center | space-between | space-around;flex-start
(默认值):左对齐flex-end
:右对齐center
: 居中space-between
:两端对齐,项目之间的间隔都相等。space-around
:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
align-items
:定义Item在交叉轴上如何对齐。
取值:align-items: flex-start | flex-end | center;flex-start
:交叉轴的起点对齐。flex-end
:交叉轴的终点对齐。center
:交叉轴的中间点对齐。
flex-wrap
:一条轴线上放不下,决定其是否换行
取值: nowrap(不换行) | wrap(换行)
flex 属性:flex属性是flex-grow
, flex-shrink
和 flex-basis
的简写,默认值为0 1 auto。flex-grow
: 属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。 取值越大,占用剩余空间越大。flex-shrink
: 属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。flex-basis
:属性指定了flex元素在主轴方向上的初始大小
这里设置item6
与 item7
的flex为1和2,表示当前轴剩余的空间item6占1/3,item7占2/3.
我们访问caniuse查看浏览器对它支持情况,可以看到目前绝大多数浏览器是支持这个属性的。
更多的关于flex的属性可以查看这里:flex布局
grid布局又叫网格布局,讲到布局,我们就会想到 flex
布局,甚至有人认为既然有flex
布局了,似乎没有必要去了解Grid
布局。但flex
布局和Grid
布局有实质的区别,那就是flex
布局是一维布局,Grid
布局是二维布局。flex
布局一次只能处理一个维度上的元素布局,一行或者一列。Grid
布局是将容器划分成了“行”和“列”,产生了一个个的网格,我们可以将网格元素放在与这些行和列相关的位置上,从而达到我们布局的目的。看下面的例子
grid2布局
item0
item1
item2
item3
item4
item5
item6
item7
上面的代码基本基本涵盖了我们常用的grid的属性
display: grid
: 设置container
容器为网格布局grid-template-columns
与grid-template-rows
:分别设置网格的列宽与行高,取值有多中形式例如: /* 声明了三列,宽度分别为 200px 100px 200px */
grid-template-columns: 200px 100px 200px;
/* 声明了两行,行高分别为 50px 50px */
grid-template-rows: 50px 50px;
或者是这样像我们的例子中使用repeat()
函数进行赋值,该函数接受两个参数,第一个参数是重复的次数,第二个参数是所要重复的值。我们的例子中grid-template-columns: repeat(4,1fr);
出现了一个新的单位fr
,fr
代表网格容器中可用空间的一等份,类似于flex的flex-grow
。如果这样取值grid-template-columns: 200px 1fr 2fr
表示第一个列宽设置为 200px,后面剩余的宽度分为两部分,宽度分别为剩余宽度的 1/3 和 2/3。
grid-auto-rows
与 grid-auto-columns
: 表示超出我们没有定义网络的宽度跟高度取值。例如上面的例子grid-template-columns: repeat(4,1fr);
我们只是显示的指定了列的个数,以及宽度,并没有指定行高,那么grid会取grid-auto-rows: minmax(100px,auto);
的值来作为行高。minmax()
函数产生一个长度范围,表示长度就在这个范围之中都可以应用到网格项目中,它接受两个参数,分别为最小值和最大值。grid-gap
: 表示网格间的间隙大小,也可以单独这行跟列的间隙:grid-row-gap
属性、grid-column-gap
.grid-row
和 grid-column
: 表示单个项目的四个边框的起始网格线跟结束网格线,从而确定单个网格的大小跟位置。我们将项目化分为四行四列的网格,那么横向网格线为从1-5,纵向网格线也为从1-5,这里item0的取值grid-row: 1/2;grid-column: 1/5;
表示:行高从第一根网格线到第二跟网格线,列宽度:从第一根网格线到第五根网格线。看下它的浏览器支持情况,总体兼容性还不错,但在IE10以下不支持.
更多的关于grid的属性可以查看这里:grid布局
通过上面的学习我们了解了Web开发常用的几种布局方式,下面我们将这些布局方式来应用到我们的实际开发中,我们就以最常见的几种布局方式来说明
双栏布局在我么的Web开发中间经常用到,例如下面的CSDN的内容详情页。主要特点:一侧栏固定,另一侧栏宽度自适应。
我们使用float+margin
的方式去实现,左侧栏浮动,右侧设置左外边距。
双栏目布局
左侧
右侧
后面内容
实现效果
注意要给container
添加为内容空的子元素,清除浮动带来的影响。
三栏布局也是我们经常遇到的布局方式,它的特点主要是:两边定宽,中间自适应。有多种方式实现三栏布局,我们这里介绍其中四种方式
实现思路:
.box {
/*父元素设置相对定位,否则左右栏会相对Body元素进行位置的偏移*/
position: relative;
background-color:wheat;
}
.middle {
height: 100px;
margin-left: 110px;
margin-right: 110px;
background-color:royalblue;
}
.left {
position: absolute;
top: 0px;
left: 0px;
width: 100px;
height: 100px;
background-color:salmon;
}
.right {
position: absolute;
top: 0;
right: 0;
width: 100px;
height: 100px;
background-color:sandybrown;
}
左边
中间
右边
尾部内容
看下实现效果
实现思路:
中间
左边
右边
后面
CSS
body {
/* 设置body的最小宽度 */
min-width: 800px;
}
.box {
padding: 0 210px;
width: 100%;
background-color:red;
}
.middle {
float: left;
width: 100%;
height: 200px;
background-color:royalblue;
}
.left {
float: left;
width: 200px;
height: 200px;
background-color:salmon;
/*左边距为-100%以使得左元素上升一行并且处于最左位置*/
margin-left: -100%;
/*相对定位*/
position: relative;
left: -210px;
}
.right {
float: left;
width: 200px;
height: 200px;
background-color:sandybrown;
/*元素设置左边距为自身宽度的负值使得右元素上升一行处于最右位置*/
margin-left: -200px;
/*相对定位*/
position: relative;
right: -210px;
}
.last {
background-color:thistle;
height: 40px;
}
效果
实现思路:
中间
左侧
右侧
尾部
CSS
body {
min-width: 800px;
}
.container{
float: left;
/* 整个容器大小 */
width: 100%;
height: 200px;
background: #ddd;
}
.container .middle{
height: 200px;
/* 设置左右边距 */
margin: 0 160px;
background-color:slateblue;
}
.left{
float: left;
width: 150px;
height: 200px;
background-color: rosybrown;
margin-left: -100%;
}
.right{
float: left;
width: 150px;
height: 200px;
background-color:saddlebrown;
margin-left: -150px;
}
.last {
background-color: tomato;
}
效果
圣杯布局跟双飞翼布局的实现上,在前部分是一样的。同样都是左右栏定宽,中间栏自适应。采用浮动和负边距使左右栏与中间栏并排。不同之处大部分在于中间元素的的展示方式上。圣杯布局采用父元素设置内边距的方法,左右元素设置相对定位辅助。而双飞翼布局在中间采用嵌套子元素方法,通过设置子元素外边距来展示。
对比前面两中实现直接实用flex布局能够比较容易的实现三栏布局
左侧
中间
右侧
CCS
.container {
display: flex;
flex-direction: row;
justify-content: center;
align-items: flex-start;
background-color: wheat;
/* height: 100vh; */
}
.left {
width: 150px;
height: 200px;
background-color: rosybrown;
}
.right {
width: 150px;
height: 200px;
background-color: saddlebrown;
}
.middle {
/* 宽度沾满剩下的整个区域 */
flex: 1;
height: 200px;
background-color: seagreen;
}
响应式布局是Ethan Marcotte在2010年5月份提出的一个概念,简而言之,就是一个网站能够兼容多个终端——而不是为每个终端做一个特定的版本。这个概念是为解决移动互联网浏览而诞生的。
例如三星网站的设计,当我们改变浏览器大小时,页面的布局会发生相应的改变,那么这些变化是如何实现的呢?我们介绍三种实现方式
CSS3-Media Query
使用 @media
查询,可以针对不同的媒体类型定义不同的样式。当你重置浏览器大小的过程中,页面也会根据浏览器的宽度和高度重新渲染页面。
语法
@media mediatype and|not|only (media feature) {
CSS-Code;
}
mediatype
: 媒体类型, 例如:screen
:计算机屏幕(默认值),tv
:电视类型设备 等and|not|only
:逻辑操作符and
:用来把多个媒体属性组合起来,合并到同一条媒体查询中not
:用来对一条媒体查询的结果进行取反only
:表示仅在媒体查询匹配成功时应用指定样式media feature
: 多数媒体属性,带有“min-”和“max-”前缀,用于表达“大于等于”和“小于等于”。例如width | min-width | max-width
,height | min-height | max-height
,aspect-ratio | min-aspect-ratio | max-aspect-ratio
等适配进行响应式开发时往往需要针对不同的屏幕添加多个断点,看个例子
item0
item1
item2
item3
item4
item5
item6
item7
CSS
这句代码的作用是禁止用户进行手动的放大缩小页面@media
不支持IE9及以下的浏览器,如果要支持需要添加额外的代码
第二种方式主要是利用grid
的特性来实现响应布局。假如有这样的需求:我们不希望Item过小,需要有最小宽度限制,并且当视口宽度增加时我们不希望看到右侧有空白区域的出现。实现下面效果
响应式布局2
item0
item1
item2
item3
item4
item5
item6
item7
grid
的属性我们再上面已经介绍过了这里不再赘述。唯一没有介绍的是auto-fit
关键字,repeat()
函数的作用是重复创建多个Item,第一个参数数个数,第二个是大小,这里取值auto-fit
的意思是数量是自适应的,只要容纳得下,就会往上排列。Columns栅格系统
往往需要依赖某个UI库,如Bootstrip
或者是Element UI
等。
Bootstrap
来自Twitter,是一个用于快速开发 Web 应用程序和网站的前端框架。它提供了一套响应式、移动设备优先的流式网格系统,随着屏幕或视口(viewport)尺寸的改变,系统会自动将视口分为最多12列。它根据当前视口的大小添加多个媒体查询断点,可以让开发者方便的根据视口大小调整每个网格所占整体视口的宽度。Bootstrap(5.0)
有六种默认响应尺寸:xs
、sm
、md
、lg
、xl
、xxl
,对应关系如下它的基本的网格结构
...
使用规则
.container
class 内,以便获得适当的对齐(alignment)和内边距(padding)例子:
Bootstrap
item0
item0
item0
item0
其他官方示例,Element UI的响应式布局与Bootstrap是相似的工作原理,这里不再赘述。
想了解更多关于Bootstrap和Element UI相关内容,点击他们
你可能会有这样一种感觉,初识前端,感觉,在它新鲜又很简单,在学习完Html+CSS+JavaScript等前端必备基础后,你会发现前端体系涉及的知识点,是方方面面的,零碎又杂乱,所以,真正开始写Web页面你会一头雾水。其实,不必过于担心,因为这是每个前端小白在进阶路上必经的一个心路历程,你只要多写多练,巩固知识点,慢慢的就会有自己的技术心得。
毋容置疑,刚学习写客户端时肯定要从基础的页面布局来入手,因此这篇文章主要面向的是前端初学者,限于技术水平,文中若有技术纰漏,还请不吝赐教,以便共同进步!
| CSS布局全解析_知心宝贝 |
| 一文了解,前端网页布局常用的几种方式 | 实现响应式布局有几种方法 |
| HTML+CSS十分钟实现响应式布局页面,响应式布局实战教程 |
Bootstrap_构建快速响应的网站 Element UI_面向设计师和开发者的组件库
CSS布局—可能是最全的 | Grid 布局完全指南_CSS 栅格布局