前端页面布局
静态布局(Static Layout)
- 最传统、原始的Web布局设计。网页最外层容器(outer)有固定的大小,所有的内容以该容器为标准,超出宽高的部分用滚动条(overflow:scroll)来实现滚动查阅。
- 宽度固定,不需要考虑用户浏览器的宽度,布局简单。
- 移动端和pc端页面不通用,需要设计移动端与pc两套页面,并分别设置单独的域名访问。
- PC端限制了最小的宽度, 低于了则以最小宽度出现滚动条。
- 移动端限制了最大的宽度, 超过了则以最大宽度居中显示。
body{
min-width:1200px;
}
.inner{
height:200px;
overflow:hidden;
}
文档高度不定,页面可滚动(常用布局)
上部
详情
.layout { &-wrap { min-width: 1200px; } &-head { height: 100px; background: #666; } &-body { width: 1200px; min-height: 500px; margin: 10px auto; background: #eee; } }
百分比宽度布局(Percentage Widths Layout)
- 固定页面布局,当屏幕大小改变时,页面的大体格局保持不变。
- 宽度使用百分比,文字使用em,rem。
- 随着浏览器宽度的改变,页面的格局会逐渐发生变化。.layout {&-wrap { width:100%;}&-left {
width: 20%;}&-right { width:80%;}}
流式布局(Liquid Layout)
- 页面元素的宽度按照屏幕进行适配调整,随着屏幕的改变,页面的布局没有发生大的变化,可以进行适配调整,实质是静态页面的拼接
- 左侧固定+右侧自适应,两边固定+中间自适应,双栏布局(上边固定,左边固定,右边自适应)
- 元素的宽高用百分比做单位,元素宽高按屏幕分辨率调整,布局不发生变化
- 屏幕尺度跨度过大的情况下,页面不能正常显示。
双栏布局
方案1:撑满window,随浏览器大小变化而变化
<div >
<div >
上部
</div>
<div class="layout-left">
左侧
</div>
<div class="layout-right">
右侧
</div>
</div>
.layout {
&-wrap {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
&-head {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 100px;
background: #666;
overflow: auto;
}
&-left {
position: absolute;
top: 100px;
left: 0;
bottom: 0;
width: 200px;
background: #eee;
overflow: auto;
}
&-right {
position: absolute;
top: 100px;
left: 200px;
right: 0;
bottom: 0;
background: #999;
overflow: auto;
}
}
- abs布局,简单快速的达到我们想要的效果,兼容性好,但是整个页面脱离了文档流
方案2 采用行内块元素布局
<div >
<div >
上部
</div>
<div >
<div class="layout-left">
左部
</div>
<div class="layout-right">
右部
</div>
</div>
</div>
.layout {
&-wrap {
height: 100%;
}
&-head {
height: 100px;
background: #666;
font-size: 30px;
}
&-body {
height: calc(100% - 100px);
background: #eee;
font-size: 0;
}
&-left {
display: inline-block;
width: 40%;
height: 100%;
background: #eee;
font-size: 30px;
overflow: auto;
}
&-right {
display: inline-block;
width: 60%;
height: 100%;
background: #999;
font-size: 30px;
overflow: auto;
}
}
- 由于用到了calc 影响性能,还需要在较高版本的浏览器运行
- 需要清除行内块的空隙带来的影响
方案3:float布局
.layout {
&-wrap {
height: 100%;
}
&-head {
height: 100px;
background: #666;
font-size: 30px;
}
&-body {
height: calc(100% - 100px);
background: #eee;
font-size: 0;
}
&-left {
float: left;
width: 40%;
height: 100%;
background: #eee;
font-size: 30px;
overflow: auto;
}
&-right {
width: 60%;
height: 100%;
margin-left: 40%;
background: #999;
font-size: 30px;
overflow: auto;
}
}
- 在方案二的基础上调整一下左右两个div的样式即可,需要清除浮动带来的影响
弹性布局(Flex Layout)
- 采用Flex布局的元素,称为Flex容器(flex
container),简称”容器”。它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称”项目”。 - flex模块定义了弹性元素的水平方向与垂直方向的对齐显示方式
- 容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis),项目默认沿主轴排列。
- CSS3引入的布局方式,简单方便快捷
- CSS3新特性,浏览器兼容性不好,特别是一些android手机浏览器对flex的支持也不是很好。
flex 容器
.box{
display: flex;
}
flex-direction属性决定主轴的方向(即项目的排列方向)。
.box {
flex-direction: row | row-reverse | column | column-reverse;
}
- row(默认值):主轴为水平方向,起点在左端。
- row-reverse:主轴为水平方向,起点在右端。
- column:主轴为垂直方向,起点在上沿。
- column-reverse:主轴为垂直方向,起点在下沿。
flex-wrap属性
- 默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,如果一条轴线排不下,如何换行。.box{flex-wrap:
nowrap | wrap | wrap-reverse;} - nowrap(默认):不换行。
- wrap:换行,第一行在上方。
- wrap-reverse:换行,第一行在下方。
flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap
.box {
flex-flow: <flex-direction> <flex-wrap>;
}
justify-content属性定义了项目在主轴上的对齐方式。
.box {
justify-content: flex-start | flex-end | center | space-between | space-around;
}
- flex-start(默认值):左对齐
- flex-end:右对齐
- center: 居中
- space-between:两端对齐,项目之间的间隔都相等。
- space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
align-items属性定义项目在交叉轴上如何对齐。
.box {
align-items: flex-start | flex-end | center | baseline | stretch;
}
- flex-start:交叉轴的起点对齐。
- flex-end:交叉轴的终点对齐。
- center:交叉轴的中点对齐。
- baseline: 项目的第一行文字的基线对齐。
- stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
.box {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
- flex-start:与交叉轴的起点对齐。
- flex-end:与交叉轴的终点对齐。
- center:与交叉轴的中点对齐。
- space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
- space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
- stretch(默认值):轴线占满整个交叉轴。
响应式布局(Liquid Layout)
- 采用自适应布局和流式布局的综合方式,为不同屏幕分辨率范围创建流式布局
- 利用媒体查询可以检测到屏幕的尺寸(主要检测宽度),并设置不同的CSS样式,当屏幕大小改变时,会出现不同的布局。
- 栅格布局;将当前屏幕划分为n个,普遍划分为12,24个,根据不同的屏幕显示不同的大小,随着屏幕或视口(viewport)尺寸的增加,系统会自动分为最多12列。
- 随着用户浏览器宽度的变化,到达特定尺寸样式会突变,比如左右模块突变为上下模块。@media (min-width:
1200px).container { width: 1170px;}@media (min-width:
992px).container { width: 970px;}@media (min-width: 768px).container
{ width: 750px;}
##########
移动端
视口(viewport)与像素
布局视口
不再与移动端浏览器相关联,完全是独立的。实际上布局视口的宽度要比屏幕宽出很多。
视觉视口
用户看到的网站展示区域,一般视觉视口和设备宽度一致。并且它的CSS像素的数量会随着用户缩放而改变。
理想视口
为了使网站在移动端有最理想的浏览和阅读宽度而设定。需要手动添写meta视口标签通知浏览器操作。使用它配合css媒体查询制定移动端展示方案。
像素
- 一个像素就是计算机屏幕能显示一特定颜色的最小区域。
- 设备像素(物理像素):设备屏幕的物理像素,任何设备的物理像素的数量都是固定的。
- CSS像素(逻辑像素):为Web开发者创造的,在CSS(和JavaScript)中使用的一个抽象的层,iOS的尺寸单位为pt,Android的尺寸单位为dp。
- 倍率:物理像素 \ 倍率 = 逻辑像素。
- CSS像素相当于多少个设备像素取决于屏幕的特性(是否高密度)和用户进行的缩放。当用户放大的越大,一个CSS像素覆盖的设备像素就越多,因此这个元素不一定会跨越css设置等值的设备像素。在旧的屏幕上,当缩放程度为100%时,一个CSS像素等于一个设备像素。在高密度屏幕上,例如苹果的视网膜屏幕,一个CSS像素跨越了多个设备像素。
- 单位之间的换算关系随倍率变化:
- 1倍:1pt=1dp=1px(mdpi、iPhone 3gs)
- 1.5倍:1pt=1dp=1.5px(hdpi)
- 2倍:1pt=1dp=2px(xhdpi、iPhone 4s/5/6)
- 3倍:1pt=1dp=3px(xxhdpi、iPhone 6 plus)
- 4倍:1pt=1dp=4px(xxxhdpi)
屏幕宽即为设备宽
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" charset="UTF-8">
- 以iPhone
5s为例,屏幕的分辨率是640x1136,倍率是2。浏览器会认为屏幕的分辨率是320x568,仍然是基准倍率的尺寸。所以在制作页面时,只需要按照基准倍率来就行了。无论什么样的屏幕,倍率是多少,都按逻辑像素尺寸来设计和开发页面。只不过在准备资源图的时候,需要准备2倍大小的图,通过代码把它缩成1倍大小显示,才能保证清晰。 - 1px像素的问题,一些canvas画布上圆角矩形会有锯齿
- 使用rem自适应布局,利用rem单位相对根元素的font-size来做计算,根据不同的屏幕算出html的font-size,页面内的大小单位都根据rem来写。
<div >
<div >
这是顶部
</div>
<div >
主体内容
</div>
<div class="layout-foot">
底部
</div>
</div>
.layout {
&-head {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4rem;
background: #fa0;
}
&-body {
position: absolute;
top: 4rem;
left: 0;
right: 0;
bottom: 4rem;
background: #eee;
}
&-foot {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 4rem;
background: #ffa319;
}
}
设定固定的视口宽度
- 先设定好固定的视口宽度,再根据屏幕宽度与设备宽度的比例设定缩放比,一般meta
viewport宽度为设计稿宽度。 - 目前在wap项目中存在两种layout,view/layout/h5.ejs
采用的是屏幕宽即为设备宽,view/layout/h5.fixwidth.ejs,是以1242作为固定宽度。 $h5-fixwidth:
1242px; px) {
@return h5-fixwidth-base-ratio; } .common-btn { display:
inline-block; width: realPx(160px); height: realPx(44px);
background: #F2CEAE; box-shadow: 0 realPx(6px) realPx(20px) 0
rgba(0, 0, 0, 0.30); border-radius: realPx(5px); font-size:
realPx(16px); line-height: realPx(44px); color: #03418B;
letter-spacing: 0; text-align: center; font-family:
PingFang-SC-Medium, Arial, Helvetica, sans-serif; } - 所有的像素都需要重新计算长度1px
- 像素的原因
由于视口显示宽度与设备宽度一样,实际像素与逻辑像素,而设备宽度为逻辑像素,逻辑像素=像素密度✖倍率,比如android大部分屏幕的倍率为2,ios的为3,比如ios手机一逻辑像素实际对应9个像素点。方案1:透明度.border-1px{border:1px
solid rgba(255,255,255,0.5)}
方案2:切一张三像素高,宽度较长的图片,设置其高度为1px
<div style='overflow: hidden;height: 1px'><img src="https://cdn.tianyancha.com/wap/images/feed-line2.png" class="vertical-top" alt=""></div>
方案3:巧用渐变(由于采用相对定位的方式,需要考虑绝对定位时的位置)
.app-border-bottom {
position: relative;
}
.app-border-bottom::after {
content: '';
position: absolute;
width: 100%;
height: 1px;
left: 0px;
bottom: 0px;
background: -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(66.66%, transparent), color-stop(66.66%, #e0e0e0), to(#e0e0e0));
background: linear-gradient(transparent 0%, transparent 66.66%, #e0e0e0 66.66%, #e0e0e0 100%);
}
一些小技巧
标签语义化
- 直观从html结构中就能看出大致结构,方便后续人员的开发与查找元素
<header></header>
<footer></footer>
<section></section>
<a></a>
<i></a>
伪类元素的使用 :before :after
- 使用场景–一些使用共用的文字且不适用于同一模板,方便随时更新
- 结构尽量精简,减少层级,降低html解析的DOM树复杂度
.company-history-count:before {
content: '查看更多 ';
}
.company-history-count:after {
content: ' ';
}
- 一些特定的样式,不需要多余元素包裹,比如异型元素小三角,
.tab-main .active.tab .top::after {
position: absolute;
left: 35%;
top: 100%;
content: '';
width: 0;
height: 0;
margin-top: 2px;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-top: 8px solid #fff;
}
充分利用 + 选择器
- 组件与组件间的间隔,无须增加新的css
<ul class="list-warp">
<li class="list"></li>
<li class="list"></li>
<li class="list"></li>
<li class="list"></li>
</ul>
.list {
width: 100px;
height: 30px;
& + & {
border-top: 1px solid #000;
}
}
- 元素空隙的处理
- 由于当前本地开发的html未压缩,而发到测试与线上的html是压缩过后的,导致本地与测试所看到的页面会稍显不同。
- 行内元素间的空格回车等会造成行内元素的空隙,特别是inline-block元素,解决方法:
- 1.设置空隙的字体大小,font-size:0;.list-warp{ font-size:0; .list{ display:inline-block; font-size:14px; }}
- 2.设置元素浮动,但需要清除浮动的影响,而且图文并排时由于脱离了文档流,导致外部环绕文字显示会有问题.list-warp{ clear:both; .list{ float:left; }}