兼容ie8及现代浏览器的多种方案实现自适应布局
一、响应式布局
(一)、介绍
响应式布局是一种兼容pc、移动端等多种终端的样式布局。即根据屏幕的大小自适应布局,或者变化布局样式,(屏幕在拉伸时显示不同的效果比如一行布局变多行布局)。
(二)、响应式布局技术
1. viewport技术
viewport是pc端和移动端公用一套代码的重要神器。常遇到如下代码:
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"">
viewport的属性如下:
width | 设置layout viewport 的宽度,为一个正整数,或字符串"width-device" |
---|---|
initial-scale | 设置页面的初始缩放值 |
minimum-scale | 允许用户的最小缩放值 |
maximum-scale | 允许用户的最大缩放值 |
user-scalable | 是否允许用户进行缩放 |
height | 设置layout viewport 的高度 |
另,利用rem单位可以实现各终端显示大小的问题。可以参考这个文章
2.@media媒体查询
@media 可以针对不同的屏幕尺寸设置不同的样式,当你重置浏览器大小的过程中,页面也会根据浏览器的宽度和高度重新渲染页面。
案例:实现小屏1024px和大屏1600px之间时div用middleClass四列布局
@media screen and (min-width:600px) and (max-width:900px){
.contariner.middleClass {
float:left;
width:25%
}
媒体类型
值 | 描述 |
---|---|
all | 用于所有设备 |
aural | 已废弃。用于语音和声音合成器 |
braille | 已废弃。 应用于盲文触摸式反馈设备 |
embossed | 已废弃。 用于打印的盲人印刷设备 |
handheld | 已废弃。 用于掌上设备或更小的装置,如PDA和小型电话 |
用于打印机和打印预览 | |
projection | 已废弃。 用于投影设备 |
screen | 用于电脑屏幕,平板电脑,智能手机等。 |
speech | 应用于屏幕阅读器等发声设备 |
tty | 已废弃。 用于固定的字符网格,如电报、终端设备和对字符有限制的便携设备 |
tv | 已废弃。 用于电视和网络电视 |
媒体功能
值 | 描述 |
---|---|
aspect-ratio | 定义输出设备中的页面可见区域宽度与高度的比率 |
color | 定义输出设备每一组彩色原件的个数。如果不是彩色设备,则值等于0 |
color-index | 定义在输出设备的彩色查询表中的条目数。如果没有使用彩色查询表,则值等于0 |
device-aspect-ratio | 定义输出设备的屏幕可见宽度与高度的比率。 |
device-height | 定义输出设备的屏幕可见高度。 |
device-width | 定义输出设备的屏幕可见宽度。 |
grid | 用来查询输出设备是否使用栅格或点阵。 |
height | 定义输出设备中的页面可见区域高度。 |
max-aspect-ratio | 定义输出设备的屏幕可见宽度与高度的最大比率。 |
max-color | 定义输出设备每一组彩色原件的最大个数。 |
max-color-index | 定义在输出设备的彩色查询表中的最大条目数。 |
max-device-aspect-ratio | 定义输出设备的屏幕可见宽度与高度的最大比率。 |
max-device-height | 定义输出设备的屏幕可见的最大高度。 |
max-device-width | 定义输出设备的屏幕最大可见宽度。 |
max-height | 定义输出设备中的页面最大可见区域高度。 |
max-monochrome | 定义在一个单色框架缓冲区中每像素包含的最大单色原件个数。 |
max-resolution | 定义设备的最大分辨率。 |
max-width | 定义输出设备中的页面最大可见区域宽度。 |
min-aspect-ratio | 定义输出设备中的页面可见区域宽度与高度的最小比率。 |
min-color | 定义输出设备每一组彩色原件的最小个数。 |
min-color-index | 定义在输出设备的彩色查询表中的最小条目数。 |
min-device-aspect-ratio | 定义输出设备的屏幕可见宽度与高度的最小比率。 |
min-device-width | 定义输出设备的屏幕最小可见宽度。 |
min-device-height | 定义输出设备的屏幕的最小可见高度。 |
min-height | 定义输出设备中的页面最小可见区域高度。 |
min-monochrome | 定义在一个单色框架缓冲区中每像素包含的最小单色原件个数 |
min-resolution | 定义设备的最小分辨率。 |
min-width | 定义输出设备中的页面最小可见区域宽度。 |
monochrome | 定义在一个单色框架缓冲区中每像素包含的单色原件个数。如果不是单色设备,则值等于0 |
orientation | 定义输出设备中的页面可见区域高度是否大于或等于宽度。 |
resolution | 定义设备的分辨率。如:96dpi, 300dpi, 118dpcm |
scan | 定义电视类设备的扫描工序。 |
width | 定义输出设备中的页面可见区域宽度。 |
二、自适应布局
(一)、描述
自适应布局即使用固定分割点来进行布局。元素的宽度可以随着屏幕大小的改变可以自动伸缩或者拉伸,使其效果满足最小屏幕的布局样式和最大屏幕的样式。例如在工作中遇到小屏div压缩宽度文字不折行显示三点,大屏可以显示全部;多行布局时两边元素固定,中间元素可以自适应屏幕的宽度;两行布局,右边随这个文章内容变宽,达最大宽折行,左边全屏铺满…这种可以随着屏幕拉伸压缩的布局可称自适应布局。
(二)实现技术
1.flex布局
flex弹性布局,是自适应布局的一大神器,大多数现代预览器都支持,如下:
ie6-9及opera10-11.5不支持,如要考虑这些版本的预览器兼容性请绕路。
flex容器属性:
父类容器属性
flex-direction | row | row-reverse | column | column-reverse; |
---|---|
flex-direction | row | row-reverse | column | column-reverse; |
flex-wrap | nowrap | wrap | wrap-reverse; |
flex-flow | <flex-direction> <flex-wrap> |
align-items | stretch | center | flex-start | flex-end | baseline; |
子类元素属性
order | <integer>; 用整数值来定义排列顺序,数值小的排在前面。可以为负值,默认为0。 |
---|---|
flex-grow | <integer>; 一个数字,规定项目将相对于其他灵活的项目进行扩展的量。默认值是 0。 |
flex-shrink | <integer>; 一个数字,规定项目将相对于其他灵活的项目进行收缩的量。默认值是 1。 |
flex-basis | <integer> | auto; 个长度单位或者一个百分比,规定元素的初始长度。 |
flex | flex-grow flex-shrink flex-basis 缩写 auto | initial | inherit; |
align-self | auto | stretch | center | flex-start | flex-end | baseline | initial | inherit; |
三列自适应布局代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>css3 flex demo</title>
<style>
.flex-container{
height: 300px;
border: 1px solid black;
display: -webkit-flex;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
}
[class^=item]{
height: 100px;
text-align: center;
vertical-align: middle;
line-height: 100px;
color: #fff;
font-size: 40px;
}
.item1{
background-color: red;
flex-basis: 50%;
}
.item2{
background-color: orange;
flex-basis: 40%;
}
.item3{
background-color: green;
flex-basis: 100px;
}
.align_items,.align_content{ width: 302px; height: 302px;border:1px solid; display: flex; float: left; margin-left: 50px;}
.align_items{ align-items: baseline; }
.align_content{ flex-wrap: wrap; align-content: space-around; justify-content: space-around;}
.item1-1{ background:red;}
.item1-2{ background:orange;}
.item1-3{ background:yellow;}
.item1-4{ background:green;}
.item1-5{ background:cyan;}
.item1-6{ background:blue;}
.item3-1,.item3-2,.item3-3{ width: 100px; height: 80px;}
.item3-3{ font-size: 50px; }
.item3-1{ font-size: 24px;}
.item4-1{ width: 200px; height: 80px;}
.item4-2{ width: 30px; height: 50px;}
.item4-3{ width: 280px; height: 100px;}
.item4-4{ width: 80px; height: 30px;}
.item4-5{ width: 40px; height: 100px;}
.item4-5{ width: 120px; height: 60px;}
</style>
</head>
<body>
<h1>flex 单行自适应布局</h1>
<div class="flex-container">
<div class="item1">1</div>
<div class="item2">2</div>
<div class="item3">3</div>
</div>
</body>
</html>
具体详细可以阅览这个文章
2.正padding+absolute布局实现右边压缩,左边不可压缩,兼容ie8
实现左右元素固定宽度,中间区域可以随着屏幕的改变而改变。或者实现更多的列可以自适应,某些元素固定,可以利用百分比长度,以及padding内边距和绝对定位实现,多列时也用50%和50%等多个百分长度自适应,注意父级元素的长度是固定的,不是脱离文档流的元素。
两个百分的元素并排布局可以模拟两边都压缩的效果。注意铺满div子元素宽的总和为百分之百
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>css3 flex demo</title>
<style>
.float-container{
height: 200px;
border: 1px solid black;
position: relative;
overflow: hidden;
}
[class^=item]{
height: 200px;
text-align: left;
vertical-align: middle;
line-height: 200px;
color: #fff;
font-size: 40px;
}
.item1{
background-color: red;
width: 100px;
position: absolute;
left: 0;
}
.item2{
background-color: orange;
width: 100%;
padding-right: 100px;
padding-left: 0px;
}
.item3{
background-color: green;
width: 100px;
position: absolute;
right: 0;
}
</style>
</head>
<body>
<h1>正padding 单行自适应布局</h1>
<div class="float-container">
<div class="item1">1</div>
<div class="item2">2 可拉伸</div>
<div class="item3">3</div>
</div>
</body>
</html>
3.负margin+absolute实现左右两边都压缩,兼容ie8
对于固定宽度的块级元素实现两边长度自动压缩的场景时可以利用负外边距,和百分比宽达到两边都压缩的效果。该方案可以实现图片随着两边居中剪裁。
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>css3 flex demo</title>
<style>
.float-container{
height: 200px;
border: 1px solid black;
position: relative;
overflow: hidden;
}
[class^=item]{
height: 200px;
text-align: left;
vertical-align: middle;
line-height: 200px;
color: #fff;
font-size: 40px;
}
.item1{
background-color: red;
width: 100px;
position: absolute;
left: 0;
}
.item2{
background-color: orange;
width: 300px;
position:absolute;
left:50;
margin-left:-150px;
}
.item3{
background-color: green;
width: 100px;
position: absolute;
right: 0;
}
</style>
</head>
<body>
<h1>负margin 单行自适应布局</h1>
<div class="fm-container">
<div class="item1">1</div>
<div class="item2">2 可拉伸两边压缩</div>
<div class="item3">3</div>
</div>
</body>
</html>
4.onresize事件
浏览器对resize时间兼容程度如下:
除了chrome大多数都不太支持resize事件,可以用如下方案:
(function(){
function getStyle(el, name) {
if(window.getComputedStyle){
return window.getComputedStyle(el,null)[name];
}else{
return el.currentStyle[name];
}
}
let resizeFn= function() {
//初始加载,兼容大小屏方法
//let totalW = document.documentElement ? document.documentElement.clientWidth : document.body.clientWidth
//自适应方法
let totalW = getStyle(document.getElementByTagName(body)[0],'width').replace(/px/,'');
let leftW = getStyle(document.getElementById('left'),'width').replace(/px/,'');
let rightW = totalW-leftW;
let maxW=500;
let minW=100;
if(rightW <maxW){
document.getElementById('right').style.width=right-minW+'px';
}else{
document.getElementById('right').style.width='100%';
}
}
if(window.addEventListener){
window.addEventListener('resize', function(){ resizeFn(); });
}else if(window.attachEvent){
window.attachEvent('onresize', function(){ resizeFn(); });
}
resizeFn();
//注意销毁绑定的监听事件
if (window.addEventListener) {
window.addEventListener("resize",handler,false);
} else {
// ie8及以下,只支持事件冒泡
window.attachEvent("resize",handler);
}
})();