|
一.概述无论是前端还是客户端开发都离不开页面的展示,而页面是由布局和各种组件构成的。布局好比是建筑里的框架,而组件则相当于建筑里的砖瓦。组件按照布局的要求依次排列,就组成了用户所看见的界面。比如Android开发者常用的布局方式有:线性布局(LinearLayout)、相对布局(RelativeLayout)、绝对布局(AbsoluteLayout)、网格布局(GridLayout)等,IOS开发者常用的布局方式:手写Frame、自动布局(AutoLayout)、xib、storyboard等方式,我们这里主要介绍前端的布局方式。虽然目前大多数网站的构建都是通过成熟的框架搭建的,但是作为前端开发的基础,学习了解一下布局还是很有必要的。页面布局(Layout):就是对页面的文字、图形或表格进行排布、设计. --- 知乎研究布局的目的是让我们的页面尽可能的还原UI设计给我们的设计图,适配各种尺寸的屏幕,使其在各种尺寸屏幕上能很好地显示出我们的视图。我们来看下我们Web开发中常用的几种布局类型:二.布局类型1. 普通流布局这是页面默认布局的方式 ,每个元素都有默认空间,每个元素都是在父元素的左上角出现的,页面中的块元素都是按照从上到下的方式出现,每个块元素独占一行,页面中行内元素都是从左到右的方式排列.
每个元素都有一个默认的 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 还有一些其他取值,可以看这里2. 浮动布局属性: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;}看下效果,符合我们的预期了实际上浮动最主要的作用:是可以使块级元素在一行内显示。并且可以使文字可以环绕浮动元素进行排列。3. 定位布局属性:position,默认值:static,根据其取值的的不同分为:
相对定位:position:relative;
绝对定位:position:absolute;
固定定位:position:fixed;
只要是元素的position 属性取值不为static,那么这个元素就被称为已定位元素。这里需要注意,后面在介绍这几种定位时,已定位元素会对他本身的位置有所影响。偏移属性:top、left、right、bottom,取值是以px为单位的数值,取值可以是正数也可以是负数,分别对应不同方向的偏移top:取值为正,向下移动,取值为负数,向上移动bottom:取值为正,向上移动,负值 向下移动。left:取值为正,右移动,负值 左移动right:取值为正 左移动,负值 右移动如何记忆:可以参考下面的图例,取值为正数时,都是向元素的内部进行靠拢,取值为负数时候都是向远离元素的位置移动。(1)相对定位relative元素相对于他原来的位置进行距离偏移用法:position:relative;配合 top、left、right、bottom进行位置的微调
我们还是以上面的正常文档流布局为例,现在我们想让右侧块跟左侧块在一行显示,并且在左侧块的右边显示,实现下图的效果那么我们可以设置.right的布局如下.right{position:relative;top:-100px;left:50px;width:50px;height:100px;background-color:saddlebrown;}(2)绝对定位absolute元素会相对于离他最近的已定位的(三种定位方式的一种)祖先元素去实现位置的初始化跟偏移,祖先元素就是本元素的父级元素。如果没有已定位的祖先元素,那就相对于body去实现位置的初始化跟偏移。绝对定位元素会变成块级元素。用法:position:absolute;配合 top、left、right、bottom进行位置的微调
现在我们想让右侧块块叠加在左侧块之上显示,实现下图的效果;那么我们可以设置.right的布局如下.right{position:absolute;top:50px;left:0;width:50px;height:100px;background-color:saddlebrown;}可以看到当子元素元素的postion属性设置为absolute后 原先父元素的高度变化了,说明.right脱离了文档流,不再占据页面空间。注意这里top: 50px;的改变是相对于body改变的,其初始化位置为文档流的左上角,因为其父元素container并不是已定位的元素。(3)固定定位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的元素也会脱离文档流。(4)定位补充一旦将元素设置 已定位元素(position的取值不为static),元素可能会出现堆叠效果,堆叠效果的属性:z-index,取值:无单位的数子,数子越大越靠上我们以上面绝对定位的例子来说明,设置了right为绝对定位后,right在left的上面,此时如果想让left在上,right在下,实现下面效果设置left的CSS代码.left{position:relative;z-index:10;width:50px;height:100px;background-color:rosybrown;}注意:只有已经定位的元素可以使用z-index,如果不设置position: relative;是没有效果的,父子元素之间无法调整堆叠效果,子元素压在父上。4. flex布局flex布局又叫弹性布局,是一种为一维布局而设计的布局方法。一维的意思是你希望内容是按行或者列来布局。你可以使用display:flex来将元素变为弹性布局。我们直接看例子:实现7个item横向排列item0item1item2item3item4item5item6item7上面的代码基本基本涵盖了我们常用的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布局5. grid布局grid布局又叫网格布局,讲到布局,我们就会想到 flex布局,甚至有人认为既然有flex布局了,似乎没有必要去了解Grid布局。但flex布局和Grid布局有实质的区别,那就是flex 布局是一维布局,Grid布局是二维布局。flex布局一次只能处理一个维度上的元素布局,一行或者一列。Grid布局是将容器划分成了“行”和“列”,产生了一个个的网格,我们可以将网格元素放在与这些行和列相关的位置上,从而达到我们布局的目的。看下面的例子item0item1item2item3item4item5item6item7上面的代码基本基本涵盖了我们常用的grid的属性display: grid: 设置container容器为网格布局grid-template-columns与grid-template-rows:分别设置网格的列宽与行高,取值有多种形式例如:/*声明了三列,宽度分别为200px100px200px*/grid-template-columns:200px100px200px;/*声明了两行,行高分别为50px50px*/grid-template-rows:50px50px;或者是这样像我们的例子中使用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开发常用的几种布局方式,下面我们将这些布局方式来应用到我们的实际开发中,我们就以最常见的几种布局方式来说明1.双栏目布局实现双栏布局在我么的Web开发中间经常用到,例如下面的CSDN的内容详情页。主要特点:一侧栏固定,另一侧栏宽度自适应。我们使用float+margin的方式去实现,左侧栏浮动,右侧设置左外边距。左侧右侧后面内容实现效果注意要给container添加为内容空的子元素,清除浮动带来的影响。2.三栏目布局实现三栏布局也是我们经常遇到的布局方式,它的特点主要是:两边定宽,中间自适应。有多种方式实现三栏布局,我们这里介绍其中四种方式(1)position + margin 实现实现思路:设置父元素为相对定位,左右两栏采用绝对定位,分别固定于页面的左右两侧中间的主体栏用左右margin值撑开距离.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;}左边中间右边尾部内容看下实现效果(2)圣杯布局实现思路:中间元素占据第一位置优先渲染,设置该元素 width 为 100%左中右三个元素分别左浮动,并且进行清除浮动带来的影响左元素设置左边距为-100%以使得左元素上升一行并且处于最左位置,右元素设置左边距为自身宽度的负值使得右元素上升一行处于最右位置。设置父元素的左右 padding 为左右两个元素留出空间,以展示中间元素内容。设置左右元素为相对定位,左元素的 left 和右元素的 right 为内边距的宽度的负值。代码实现中间左边右边后面CSSbody{/*设置body的最小宽度*/min-width:800px;}.box{padding:0210px;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;}效果(3)双飞翼布局实现思路:中间采用嵌套子元素方法,宽度自适应左中右三个元素分别左浮动,并且进行清除浮动带来的影响左元素设置左边距为-100%以使得左元素上升一行并且处于最左位置,右元素设置左边距为自身宽度的负值使得右元素上升一行处于最右位置。设置中间元素的子元素左右边距为左右元素留空位,以展示中间元素内容。代码实现中间左侧右侧尾部CSSbody{min-width:800px;}.container{float:left;/*整个容器大小*/width:100%;height:200px;background:#ddd;}.container.middle{height:200px;/*设置左右边距*/margin:0160px;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;}效果圣杯布局跟双飞翼布局的实现上,在前部分是一样的。同样都是左右栏定宽,中间栏自适应。采用浮动和负边距使左右栏与中间栏并排。不同之处大部分在于中间元素的的展示方式上。圣杯布局采用父元素设置内边距的方法,左右元素设置相对定位辅助。而双飞翼布局在中间采用嵌套子元素方法,通过设置子元素外边距来展示。(4)flex布局实现对比前面两种实现直接使用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;}pic3.响应式布局响应式布局是Ethan Marcotte在2010年5月份提出的一个概念,简而言之,就是一个网站能够兼容多个终端——而不是为每个终端做一个特定的版本。这个概念是为解决移动互联网浏览而诞生的。例如三星网站的设计,当我们改变浏览器大小时,页面的布局会发生相应的改变,那么这些变化是如何实现的呢我们介绍三种实现方式(1)媒体查询CSS3-Media Query使用 @media查询,可以针对不同的媒体类型定义不同的样式。当你重置浏览器大小的过程中,页面也会根据浏览器的宽度和高度重新渲染页面。语法@mediamediatypeand|not|only(mediafeature){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等适配进行响应式开发时往往需要针对不同的屏幕添加多个断点,看个例子item0item1item2item3item4item5item6item7CSS这句代码的作用是禁止用户进行手动的放大缩小页面设置了三个断点,根据不同的屏幕宽度展示不同的样式。还需要注意@media 不支持IE9及以下的浏览器,如果要支持需要添加额外的代码(2)grid实现响应式布局第二种方式主要是利用grid的特性来实现响应布局。假如有这样的需求:我们不希望Item过小,需要有最小宽度限制,并且当视口宽度增加时我们不希望看到右侧有空白区域的出现。实现下面效果item0item1item2item3item4item5item6item7关于grid的属性我们在上面已经介绍过了这里不再赘述。唯一没有介绍的是auto-fit关键字,repeat()函数的作用是重复创建多个Item,第一个参数数个数,第二个是大小,这里取值auto-fit的意思是数量是自适应的,只要容纳得下,就会往上排列。(3)Columns栅格系统Columns栅格系统往往需要依赖某个UI库,如Bootstrip或者是Element UI等。Bootstrap来自Twitter,是一个用于快速开发 Web 应用程序和网站的前端框架。它提供了一套响应式、移动设备优先的流式网格系统,随着屏幕或视口(viewport)尺寸的改变,系统会自动将视口分为最多12列。它根据当前视口的大小添加多个媒体查询断点,可以让开发者方便的根据视口大小调整每个网格所占整体视口的宽度。Bootstrap(5.0)有六种默认响应尺寸:xs、sm、md、lg、xl、xxl,对应关系如下它的基本的网格结构...使用规则行必须放置在 .containerclass 内,以便获得适当的对齐(alignment)和内边距(padding)使用行来创建列的水平组,内容应该放置在列内,且唯有列可以是行的直接子元素预定义的网格类,比如 .row 和 .col-xs-4,可用于快速创建网格布局。网格系统是通过指定您想要横跨的十二个可用的列来创建的。例如,要创建三个相等的列,则使用三个 .col-xs-4。例子:item0item0item0item0效果其他官方示例,Element UI的响应式布局与Bootstrap是相似的工作原理,这里不再赘述。想了解更多关于Bootstrap和Element UI相关内容点击他们四、总结作为前端小白,学习完Html、CSS、JavaScript等一堆东西,等到真正开始写Web页面还是一头雾水,回忆刚学习写客户端时肯定要从基础的页面布局来入手,于是有了这篇文章。因此这篇文章主要面向的是前端初学者,还请大神勿喷。当然由于作者水平有限,难免出现纰漏,如有问题还请不吝赐教。文章涉及源码参考资料:BootstrapElement UICSS布局Grid 布局完全指南
|
|