有这样一个问题。javascript
通常来讲,有如下这些布局方法:css
float:left|right
display:inline-block
display:flex
display:grid
position:absolute|relative
<table>
或display:table
bootstrap
、Pure.css
等有小伙伴就要说,这也太多了吧,我应该怎么选择?html
别急,下面咱们就开始逐一分析各类方法在web自适应布局下的使用姿式,最后作个总结。java
本文的全部例子使用了同一种三栏布局。源代码点我git
float:left|right
最经常使用的布局方式之一,设置了float
的元素脱离了文档流。须要注意在使用过浮动后,须要清除浮动,从而避免影响后面的非浮动元素。github
HTMLweb
<div class="rwd-header">Header</div>
<div class="rwd-content">
<div class="rwd-content-left">Left</div>
<div class="rwd-content-body">
<div class="rwd-content-bodyTop">Top Content</div>
<div class="rwd-content-bodyBottom">Bottom Content</div>
</div>
<div class="rwd-content-right">Right</div>
</div>
<div class="rwd-footer">Footer</div>
复制代码
普通的html布局,一个header,一个footer,中间是三栏式布局。chrome
关键cssbootstrap
.rwd-content-left,
.rwd-content-body,
.rwd-content-right {
float: left;
}
复制代码
给中间的三栏都设上浮动。浏览器
.rwd-content::after {
content: "";
clear: both;
display: block;
}
复制代码
清除浮动
.rwd-content-left {
width: 20%;
height: 200px;
}
.rwd-content-body {
width: 60%;
}
.rwd-content-right {
height: 300px;
width: 20%;
}
复制代码
元素的宽度都是百分比。由于没有内容高度给死了,平常应用时多用auto,让里面的内容撑开高度。
当@media的查询条件知足时,应用{}
中的样式。
screen就是指电脑屏幕,还有print指打印页面。 MDN @media
@media作的事彻底能够用javascript代替,用js添加一个class或者直接用js修改css属性。优势是浏览器全兼容,缺点就是用了js。
@media only screen and (max-width: 1024px) {
.rwd-content-left {
width: 30%;
}
.rwd-content-body {
width: 70%;
}
.rwd-content-right {
width: 100%;
}
}
@media only screen and (max-width: 768px) {
[class*="rwd-content-"] {
width: 100%;
}
}
复制代码
中尺寸屏幕要把right
挤下去,只要让left
和content
加起来等于100%,后面的东西就自动换行了。
小尺寸用了css选择器,把全部rwd-content-
开头的class宽度都设成100%。
display:inline-block
HTML
<div class="rwd-header">Header</div>
<div class="rwd-content" ><div class="rwd-content-left">Left</div ><div class="rwd-content-body" ><div class="rwd-content-bodyTop">Top Content</div ><div class="rwd-content-bodyBottom">Bottom Content</div ></div ><div class="rwd-content-right">Right</div>
</div>
<div class="rwd-footer">Footer</div>
复制代码
html和浮动布局的同样,为了不空白字符压缩(white space collapse)的问题,写法略有变化。
关键css
.rwd-content-left,
.rwd-content-body,
.rwd-content-right {
display: inline-block;
vertical-align: top;
}
复制代码
对咱们这个布局,只是把float:left
改为这两句。
自适应的代码也和float同样,不重复贴了。
二者都是很经常使用的布局方式。
若是须要垂直居中,使用inline-block。
inline-block有空白字符压缩的问题。
使用float,注意要清除浮动。
没有特别推荐用哪一种,看我的习惯。
好比我在小尺寸的时候,想把content放最上面,left和right都挤下去,怎么作呢?
float和inline-block布局没有纯css的方法,要用js把dom扣出来,日后面放,flexbox和grid布局均可以很好地解决这个问题。
display:flex
HTML
<div class="rwd-header">Header</div>
<div class="rwd-content">
<div class="rwd-content-left">Left</div>
<div class="rwd-content-body">
<div class="rwd-content-bodyTop">Top Content</div>
<div class="rwd-content-bodyBottom">Bottom Content</div>
</div>
<div class="rwd-content-right">Right</div>
</div>
<div class="rwd-footer">Footer</div>
复制代码
html仍是同样。
看css前先说说flex基础。
flexbox布局说白了就是点菜。先想好要吃什么,而后点必选菜,最后点可选菜,爱点不点。
先想要吃什么,仍是用以前的例子。header和footer不用管,须要布局一个这样的东西:
而后点必选菜,有下面几个必选菜要点:
1). flex-direction, 选水平方向从左到右,选flex-direction: row
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
复制代码
2). flex-wrap,咱们是单行布局,不要换行,选flex-wrap: nowrap
.container{
flex-wrap: nowrap | wrap | wrap-reverse;
}
复制代码
3). justify-content,若是水平方向有空间,怎么分配,选space-between
.container {
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
}
复制代码
4). 垂直方向怎么布局,选align-items: flex-start
.container {
align-items: flex-start | flex-end | center | baseline | stretch;
}
复制代码
5). align-content,多行布局怎么分配空间,咱们是单行布局,不存在的
.container {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
复制代码
选好这5个以后,再加上display: flex;
,往flex容器上一写,就完事了。
能够偷懒的地方: 上面5种属性,第一个值是默认值,若是选了第一个,这个属性能够不用写。
最后的可选菜比较经常使用的是能够调整flex子项(flex item)的顺序(order),单独改变某个子项的布局等。
详细教程点这里: flexbox中文教程[1] A Guide to Flexbox[2]
关键css
.rwd-content {
display: flex;
justify-content: space-between;
align-items: flex-start;
}
复制代码
flex容器(container)属性如前文所说。
@media only screen and (max-width: 1024px) {
.rwd-content {
flex-wrap: wrap;
}
.rwd-content-left {
width: 30%;
}
.rwd-content-body {
width: 70%;
}
.rwd-content-right {
width: 100%;
}
}
@media only screen and (max-width: 768px) {
[class*="rwd-content-"] {
width: 100%;
}
}
复制代码
自适应布局时,设flex-wrap: wrap;
,其余同样。
display:grid
HTML
<div class="rwd-grid">
<div class="rwd-header">Header</div>
<div class="rwd-content-left">Left</div>
<div class="rwd-content-bodyTop">Top Content</div>
<div class="rwd-content-bodyBottom">Bottom Content</div>
<div class="rwd-content-right">Right</div>
<div class="rwd-footer">Footer</div>
</div>
复制代码
grid的特色就是随心所欲,dom的顺序无所谓,只要放在grid容器下就能够。
看css以前仍是先说说grid基础。
2个两分钟由于通常grid有两种使用方式:
1). 网格项(grid item)起个名字,在网格容器(grid container)上定义好网格布局而且经过名字指定好全部网格项的位置。
2). 网格容器只定义布局,每一个网格项在使用的时候,自行选择放到哪一个(或哪几个)网格中。
无论哪一种方式,只要会划线,你就掌握了grid布局。把想要的布局画出来,而后用线分割开。
横向1 ~ 7的黑线和纵向1) ~ 4)的红线都叫网格线。
网格线包围的一个或多块矩形区域叫网格区块。
第一种grid布局方式:
.rwd-grid {
display: grid;
grid-gap: 5px;
width: 100%;
grid-template-areas: "header header header"
"left top right"
"left bottom right"
". bottom right"
". bottom ."
"footer footer footer";
grid-template-rows: 80px 150px 50px 100px 100px 100px;
grid-template-columns: 20% 60% 20%;
}
.rwd-header {
grid-area: header;
}
.rwd-content-left {
grid-area: left;
}
.rwd-content-bodyTop {
grid-area: top;
}
.rwd-content-bodyBottom {
grid-area: bottom;
}
.rwd-content-right {
grid-area: right;
}
.rwd-footer {
grid-area: footer;
}
复制代码
网格项(grid item)用grid-area
属性起个名字。
网格容器(grid container)上三个主要属性要设置:
grid-template-areas
: 就是一张地图,和咱们划线分割的图布局同样,.
表示空白。
grid-template-rows
: 设置行上的高度,不设置的话为auto。除了固定数字,百分比还有fr。 grid-template-rows: repeat(3, 1fr)
就是三等分的意思。
grid-template-columns
: 设置列的宽度。
自适应布局就是重画地图。
@media only screen and (max-width: 1024px) {
.rwd-grid {
grid-template-areas: "header header"
"left top"
"left bottom"
". bottom"
"right right"
"footer footer";
grid-template-rows: 80px 150px 50px 200px 100px 100px;
grid-template-columns: 30% 70%;
}
}
@media only screen and (max-width: 768px) {
.rwd-grid {
grid-template-areas: "header"
"left"
"top"
"bottom"
"right"
"footer";
grid-template-rows: 80px 200px 150px 250px 100px 100px;
grid-template-columns: 100%;
}
}
复制代码
第二种grid布局方式:
.rwd-grid {
display: grid;
grid-gap: 5px;
margin: 5px 0;
width: 100%;
grid-template-rows: 80px 150px 50px repeat(3, 100px);
grid-template-columns: 20% 60% 20%;
}
复制代码
网格容器上只要设置grid-template-rows
和grid-template-columns
。网格项在用的时候,自行设置须要放的地方。有不少种设置方式。
.rwd-header {
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 2;
}
复制代码
四个属性,分别是行、列的开始和结束。这边的序号指的是网格线,参照以前图中横向的黑色网格线和纵向的红色网格线。
参照图,应该好理解。
至关于:
.rwd-header {
grid-column: 1 / 4;
grid-row: 1 / 2;
}
复制代码
简写成两个属性,<开始> / <结束>。
至关于:
.rwd-header {
grid-column: 1 / span 3;
grid-row: 1;
}
复制代码
span 3指的是通过了3个网格;若是网格项只跨越了1格,能够省略设置结束位置的网格线。
至关于:
.rwd-header {
grid-area: 1 / 1 / 2 / 4;
}
复制代码
网格线上左下右的顺序,不一样于margin和padding的上右下左。
固然你能够别管这么多乱七八糟的,看我自适应布局:
@media only screen and (max-width: 1024px) {
.rwd-grid {
grid-template-rows: 80px 150px 50px 200px 100px 100px;
grid-template-columns: 30% 70%;
}
.rwd-header {
grid-area: 1 / 1 / 2 / 3;
}
.rwd-content-left {
grid-area: 2 / 1 / 4 / 2;
}
.rwd-content-bodyTop {
grid-area: 2 / 2 / 3 / 3;
}
.rwd-content-bodyBottom {
grid-area: 3 / 2 / 5 / 3;
}
.rwd-content-right {
grid-area: 5 / 1 / 6 / 3;
}
.rwd-footer {
grid-area: 6 / 1 / 7 / 3;
}
}
复制代码
详细教程点这里: 网格中基于线的定位[3] 和这里 网格模板区域[4]
position:absolute|relative
至关经常使用,特别是各类特效里都会用到。
对于自适应布局,就本身算top
和left
吧。
<table>
或display:table
我的认为表格布局比较适用于表格(看上去是废话,但并非)。
若是是通常的页面布局,就不要用table了。Why not use tables for layout in HTML?[5]
关于表格的自适应,看这里:Responsive table layout[6]
bootstrap
、Pure.css
等所谓万变不离其宗,用框架布局也是使用了上面所说的原理,这边就再也不细说各类框架。
推荐给全部元素加上border-box;
。
* {
box-sizing: border-box;
}
复制代码
IE盒模型的宽度和高度包括了padding和border,这样对于百分比的布局比较好控制,不会出现加起来超过100%而换行的状况。
在自适应的布局中少用或者不用固定的高度、宽度,使用百分比, auto或calc()。
<meta name="viewport" content="width=500, initial-scale=1">
复制代码
viewport主要用于手机自适应布局,由于如今手机分辨率愈来愈高,web上的1px到手机上未必就是1px,用这个meta让手机的px和web的px保持一致。
具体解释在这里: viewport meta[7]
说到这里,看完的同窗应该都明白了web自适应布局常见的套路。
当碰到某个酷炫的自适应页面的时候至少不会说: 这个怎么实现的?还有这种操做?
那么有同窗就要问,是否是只要学flex和grid就好了?对不起,全部都要学(就是这么可怕)。各类布局都有他们的使用场景。而且你也拦不住别人用,都须要看懂是吧。只能说要与时俱进,路漫漫其修远兮,吾将上下而求索。
参考资料
[1] Flex布局教程 - http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
[2] A Complete Guide to Flexbox - https://css-tricks.com/snippets/css/a-guide-to-flexbox/
[3] CSS网格中基于线的定位 - https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Grid_Layout/Line-based_Placement_with_CSS_Grid
[4] 网格模板区域 - https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Grid_Layout/Grid_Template_Areas
[5] Why not use tables for layout in HTML? - https://stackoverflow.com/questions/83073/why-not-use-tables-for-layout-in-html
[6] Responsive table layout - http://allthingssmitty.com/2016/10/03/responsive-table-layout/
[7] Using the viewport meta tag to control layout on mobile browsers - https://developer.mozilla.org/en-US/docs/Mozilla/Mobile/Viewport_meta_tag
[8] Responsive Web Design - https://www.w3schools.com/css/css_rwd_intro.asp
[9] Can I use - https://caniuse.com/