您的位置:首页 > Web前端 > CSS

基于CSS3的自适应布局技术

2015-09-29 15:18 661 查看
最近在做uOS APP的布局,研究了一下CSS3自适应布局技术在IE10+中的应用,其他标准浏览器由于具有自动更新功能,只需兼容最近的几个版本就行了——因此我们可以用CSS3来提高工作效率。

前端HTML(结构)+CSS(表现)这部分,无非是两大问题,装饰与布局。装饰某个widget就算再难,我们也可以用图片搞定。布局就不是这回事了,别的不说,display:inline-block有3px BUG,定位布局与浮动布局相关的BUG也不在10以下,关键是用起来非常麻烦,需要许多额外的元素 。早些年够为著名的是圣杯布局,双飞翼布局,近一点的是960grids提倡的栏栅布局,但这些布局都很难与@media配合使用。而@media是面向移动设备响应式布局的利器。
@media无非是在CSS引入条件判定,让相同的几个元素在分支不同时,呈现不同的布局。另,已经的浮动布局,定位布局是无法解决多列等高问题,而浮动时要求出现浮动条的需要,这也是过去不能解决的。 这正是我提倡大胆试用CSS3属性的原因。

CSS3引入了新三种布局,grid布局,伸缩盒布局,多列布局。其中grid布局的文档繁文缛节,可用性不强,目前只有IE10实现了,未来是否完蛋或重来不可知,放弃。 多列布局是针对文本与行内元素的,是为了实现报纸那种布局,与我们这种多widget的富应用不符合,暂不起用。剩下就是伸缩盒布局,是我见过的最操蛋的规范,从2009发布到去年最终定下来,更弦换辙了三次。

Flexbox 规范时间表:

2009年7月 工作草案 (display: box;)
2011年3月 工作草案 (display: flexbox;)
2011年11月 工作草案 (display: flexbox;)
2012年3月 工作草案 (display: flexbox;)
2012年6月 工作草案 (display: flex;)
2012年9月 候选推荐 (display: flex;)

浏览器商为了自救,搞了个私有前缀,因此定义一个伸缩盒特别麻烦:
div{
display: -webkit-box;
display: -moz-box;
display: -o-box;
display: -ms-flexbox;
display: -webkit-flex;
display: -moz-flex;
display: -ms-flex;
display: -o-flex;
display: flex;
}


因此我在定下第2个规范,CSS统一用less来写。less是一种动态的样式表语言,它为CSS增加变量,组合,函数,运算等语法,让CSS更便于编写,复用与维护。 有了less,上面那一坨东西可以封装成一个函数,用不着每次都写这么多让你狂抓的候选值。
.flexbox() {//定义
// 2009 spec
display: -webkit-box;
display: -moz-box;
display: -o-box;
// tweener
display: -ms-flexbox;
// new spec
display: -webkit-flex;
display: -moz-flex;
display: -ms-flex;
display: -o-flex;
display: flex;
}
div{
.flexbox();//使用
}


我已经把与伸缩盒相关的东西都封装为一个less库,大家可以到这里

当然想实现自适应布局,光是伸缩盒是不够的(伸缩盒本来就是一打东西,本文不是入门教程,想学可以看看这篇),还有box-sizing:border-box(防止设置padding 时撑开父元素),
visibility(用它实现显示隐藏,因为CSS3的动画对display:none的元素不起作用)。不过本文也介绍一下如何使用table-cell实现垂直居中。本文涉及到伸缩盒的例子都用less,请自行编译。


布局1:多列布局

<!DOCTYPE html>
<html>
<head>
<title>by 司徒正美</title>
<link href="hopeui.css" media="screen,projection" rel="stylesheet" title="www" type="text/css"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body id="apphopeui">
<div>
menu
</div>
<div>
main
</div>
</body>
</html>

@import "flexbox.less";
html,body{
height:100%;
margin:0;
padding:0;
}
#apphopeui{
@color: pink;
background-color: @color;
height:100%;
.flexbox();
.menu{
max-width:150px;
min-width:150px;
background:#c50000;
.flex(1);
}
.main{
background:#75cc00;
.flex(1)
}
}





布局2: 多栏布局

<!DOCTYPE html>
<html>
<head>
<title>by 司徒正美</title>
<link href="index2.css" media="screen,projection" rel="stylesheet" title="www" type="text/css"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body id="apphopeui">
<header>

</header>
<main>
这是三栏布局,上下两栏固定大小,中间的自适应,占满剩余空间<br/>
safari 5.1.7(window平台支持的最高版本safari)不认main标签,需要你将它的display设置为block或一个伸缩容器

</main>
<footer>

</footer>
</body>
</html>

@import "flexbox.less";
html,body{
height:100%;
margin:0;
padding:0;
}
#apphopeui{
@value: 1 1 auto;
.flexbox();
.flex-direction(column);
background:black;
height:100%;
header{
min-height:100px;
max-height: 100px;
background:#e4247e;
.flex(1);
}
main{
background:#00C6E4;
display:block;//fix safari 5.1.7
.flex(1);//safari5.1.7 use .flex(1); other browser can use .flex(@value)
}
footer{
min-height:100px;
max-height: 100px;
background:#a9ea00;
.flex(1);
}
}





布局3: 三栏三列布局

<!DOCTYPE html>
<html>
<head>
<title>by 司徒正美</title>
<link href="index3.css" media="screen,projection" rel="stylesheet" title="www" type="text/css"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body id="apphopeui">
<header>

</header>
<main>
<div></div>
<div>  这是三栏三列布局,上下两栏固定大小,中间的自适应,占满剩余空间;
safari 5.1.7(window平台支持的最高版本safari)不认main标签,需要你将它的display设置为block或一个伸缩容器
<br/>
白色部分,如果不设置overflow属性,以当我们收窄浏览器时,里面的文本会溢出;设置为overflow:hidden时,所有浏览器都能达到预期效果;
设置overflow:auto 时,只有safari5.1.7失败
</div>
<div>

</div>

</main>
<footer>

</footer>
</body>
</html>

@import "flexbox.less";
html,body{
height:100%;
margin:0;
padding:0;
}
#apphopeui{
.flexbox();
.flex-direction(column);
background: pink;
height:100%;
header{
.flex(1);
.fixed-height(100px);
background:#e4247e;
}
main{
.flexbox();
height:99%;// fix safari 5.1.7
background:blue;
.flex(1);
>:nth-child(1){
.flex(1);
.fixed-width(200px);
background:#b9b9b9;
}
>:nth-child(2){
.flex(1);
background:#4D99E0;
overflow-y: auto;
}
>:nth-child(3){
.flex(1);
.fixed-width(200px);
background:#b9b9b9;
}
}
footer{
.flex(1);
.fixed-height(100px);
background:#a9ea00;
}
}





布局4: 基于table-cell的多个元素垂直居中

<!DOCTYPE html>
<html>
<head>
<title>by 司徒正美</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style>
.aaa, .bbb{
width:300px;
height:300px;
background: red;
display:table-cell;
text-align: center;
vertical-align: middle;
}
.aaa div, .bbb div{
margin: 0 auto;
width:60px;
height:60px;
background: greenyellow;
}
.aaa div{
float: left;
}
.aaa div{
float: left;
}
</style>
</head>
<body>
<h3>多元素垂直居中</h3>
<div>
<div>11111</div>
<div>22222</div>
<div>33333</div>
</div>
<div>
<div>aaaaa</div>
<div>bbbbb</div>
<div>ccccc</div>
</div>
<p>第一个用于做放多个按钮的容器</p>

</body>
</html>





布局5: 基于伸缩盒的多个元素垂直居中

table-cell有个缺点是,它的overflow样式不起作用,因此子元素会一直撑大父元素。想出现滚动条,就要用到伸缩盒。
<!DOCTYPE html>
<html>
<head>
<title>by 司徒正美</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="index5.css" media="screen,projection" rel="stylesheet" title="www" type="text/css"/>
</head>
<body>
<h3>多元素垂直居中</h3>
<div>
<div>11111</div>
<div>22222</div>
<div>33333</div>
</div>

<p>第一个用于做放多个按钮的容器</p>
</body>
</html>

@import "flexbox.less";
html,body{
height:100%;
margin:0;
padding:0;
}
.aaa{
width:400px;
height:400px;
.flexbox();
.align-items(center);
.justify-content(space-around);
background:#e4247e;
div{
.flex(1);
// margin: 0 auto; //don't set it ,otherwise safari5.1.7 crash
width:100px;
max-width:100px;
height:40px;
border:1px solid black;
background: #00C6E4;
}
}






布局6: 多列等高并出现水平滚动条

<!DOCTYPE html>
<html>
<head>
<title>by 司徒正美</title>
<link href="index6.css" media="screen,projection" rel="stylesheet" title="www" type="text/css"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

</head>
<body>
<div id="apphopeui">
<header>xxx</header>
<main>yyy</main>
<footer>zzz</footer>
</div>

</body>
</html>

@import "flexbox.less";
html,body{
height:100%;
margin:0;
padding:0;
}
#apphopeui{
width:50%;
height:100%;
.flexbox();
.box-sizing(border-box);
border:10px solid #b7b7b7;
overflow-x:auto;
overflow-y: hidden;
@value: 1 1 auto;//IE get the height of v-scrollbar into the total height;
header{
.flex(@value);
.fixed-width(150px);
background:#4D99E0;
}
main{
.flex(@value);
.fixed-width(150px);
background:#75CC00;
display:block;//fix safari 5.1.7
}
footer{
.flex(@value);
.fixed-width(450px);
background:#E49800;
}
}





布局7,伸缩盒里出现垂直滚动条

<!DOCTYPE html>
<html>
<head>
<title>by 司徒正美</title>
<link href="index7.css" media="screen,projection" rel="stylesheet" title="www" type="text/css"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<style>

</style>
</head>
<body>
<header>Header</header>
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
<footer>Footer</footer>
</body>
</html>

@import "flexbox.less";
html { height: 100%; }
body {
.flexbox();
.flex-direction(column);
.box-sizing(border-box);
padding: 20px;
height: 100%;
background: #ccc;
}
header, footer {
.flex(@flexvalue);
.fixed-height(80px);
background: #b3b3b3;
}
ul {
.flex(1);
list-style: none;
margin: 0;
padding: 0;
background: hsl(200,100%,90%);
height:0;//fix opera 12.16
overflow: auto;

}
li { padding: 20px; }
li:nth-child(odd) { background: hsl(200,100%,85%); }




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: