欢迎访问移动开发之家(rcyd.net),关注移动开发教程。移动开发之家  移动开发问答|  每日更新
页面位置 : > > > 内容正文

打造自己的栅格系统

来源: 开发者 投稿于  被查看 40191 次 评论:64

打造自己的栅格系统


说起bootstrap,比较出名的还是它的栅格系统,今天来研究研究这个东西。
关于bootstrap的栅格系统的介绍请参考,官方中文版介绍。

本文不会涉及响应式,只是关心怎么用百分比构建它的。因此相对来说比较简单。
本文行文的思路,是通过一个个例子,来说明这个东西。

使用过bootstrap的同学都知道(正如官方介绍的那样),
栅格、栅格,自然就有行和列之说。col-*放row内,row放在一个容器container内。
我们假设container的width为800px。我们先创建一个一行两列的栅格布局:
html 代码

<style>
.container{
    width: 800px;
    margin: 0 auto;
}
.col{
    width: 50%;
    float: left;
}
</style>
<style>
[class^=col] {
    padding-top: 10px;
    padding-bottom: 10px;
    background: #ccc;
}
</style>
<div class="container">
    <div class="row">
        <div class="col">test</div>
        <div class="col">test</div>
    </div>
</div>

上面用了百分比,来做的。但是如果我给每列左右加上内补白,以及边框后,就会有问题:
html 代码

<style>
.container{
    width: 800px;
    margin: 0 auto;
}
.col{
    width: 50%;
    float: left;
    padding-left: 15px;
    padding-right: 15px;
}
</style>
<style>
[class^=col] {
    padding-top: 10px;
    padding-bottom: 10px;
    background: #ccc;
    border: 1px solid #ddd;
}
</style>
<div class="container">
    <div class="row">
        <div class="col">test</div>
        <div class="col">test</div>
    </div>
</div>

因为根据盒模型,width是内容的宽度。
倒是ie的盒模型width是包括padding和border的。
如果能使用ie的盒模型就好了,解决之道是有的,css3的box-sizing正是用来解决这个的:
html 代码

<style>
*{
    box-sizing: border-box;
}
.container{
    width: 800px;
    margin: 0 auto;
}
.col{
    width: 50%;
    float: left;
    padding-left: 15px;
    padding-right: 15px;
}
</style>
<style>
[class^=col] {
    padding-top: 10px;
    padding-bottom: 10px;
    background: #ccc;
    border: 1px solid #ddd;
}
</style>
<div class="container">
    <div class="row">
        <div class="col">test</div>
        <div class="col">test</div>
    </div>
</div>

如果我来5列呢?也没有问题:
html 代码

<style>
*{
    box-sizing: border-box;
}
.container{
    width: 800px;
    margin: 0 auto;
}
.col{
    width: 20%;
    float: left;
    padding-left: 15px;
    padding-right: 15px;
}
</style>
<style>
[class^=col] {
    padding-top: 10px;
    padding-bottom: 10px;
    background: #ccc;
    border: 1px solid #ddd;
}
</style>
<div class="container">
    <div class="row">
        <div class="col">test</div>
        <div class="col">test</div>
        <div class="col">test</div>
        <div class="col">test</div>
        <div class="col">test</div>
    </div>
</div>

下一个问题是,清除浮动事情,不清除浮动,会造成如下的情况:
html 代码

<style>
*{
    box-sizing: border-box;
}
.container{
    width: 800px;
    margin: 0 auto;
}
.col{
    width: 20%;
    float: left;
    padding-left: 15px;
    padding-right: 15px;
}
</style>
<style>
[class^=col] {
    padding-top: 10px;
    padding-bottom: 10px;
    background: #ccc;
    border: 1px solid #ddd;
}
</style>
<div class="container">
    <div class="row">
        <div class="col">in first row</div>
    </div>
    <div class="row">
        <div class="col">in second row</div>
    </div>
</div>

bootstrap清除浮动用的是:before和:after:
html 代码

<style>
*{
    box-sizing: border-box;
}
.container:before,
.container:after,
.row:before,
.row:after{
    content:"";
    display:table;
}
.container:after,
.row:after{
    clear:both;
}
.container{
    width: 800px;
    margin: 0 auto;
}
.col{
    width: 20%;
    float: left;
    padding-left: 15px;
    padding-right: 15px;
}
</style>
<style>
[class^=col] {
    padding-top: 10px;
    padding-bottom: 10px;
    background: #ccc;
    border: 1px solid #ddd;
}
</style>
<div class="container">
    <div class="row">
        <div class="col">in first row</div>
    </div>
    <div class="row">
        <div class="col">in second row</div>
    </div>
</div>

貌似现在就可以做出自己的栅格系统了。
我们假设最多10列(之所以没用12是因为10好算!),对应列样式组是:
[quote].col-1,.col-2,.col-3,.col-4,.col-5,
.col-6,.col-7,.col-8,.col-9,.col-10{
float:left;
padding-left:15px;
padding-right:15px;
}
.col-1{ width:10%; }
.col-2{ width:20%; }
.col-3{ width:30%; }
.col-4{ width:40%; }
.col-5{ width:50%; }
.col-6{ width:60%; }
.col-7{ width:70%; }
.col-8{ width:80%; }
.col-9{ width:90%; }
.col-10{ width:100%;}[/quote]
示例如下:
html 代码

<style>
*{
    box-sizing: border-box;
}
.container:before,
.container:after,
.row:before,
.row:after{
    content:"";
    display:table;
}
.container:after,
.row:after{
    clear:both;
}

.container{
    width: 800px;
    margin: 0 auto;
}
.col-1,.col-2,
.col-3,.col-4,
.col-5,.col-6,
.col-7,.col-8,
.col-9,.col-10{
    float:left;
    padding-left:15px;
    padding-right:15px;
}
.col-1{
    width:10%;
}
.col-2{
    width:20%;
}
.col-3{
    width:30%;
}
.col-4{
    width:40%;
}
.col-5{
    width:50%;
}
.col-6{
    width:60%;
}
.col-7{
    width:70%;
}
.col-8{
    width:80%;
}
.col-9{
    width:90%;
}
.col-10{
    width:100%;
}
</style>
<style>
[class^=col] {
    padding-top: 10px;
    padding-bottom: 10px;
    background: #ccc;
    border: 1px solid #ddd;
}
</style>
<div class="container">
    <div class="row">
        <div class="col-1">col-1</div>
        <div class="col-1">col-1</div>
        <div class="col-1">col-1</div>
        <div class="col-1">col-1</div>
        <div class="col-1">col-1</div>
        <div class="col-1">col-1</div>
        <div class="col-1">col-1</div>
        <div class="col-1">col-1</div>
        <div class="col-1">col-1</div>
        <div class="col-1">col-1</div>
    </div>
    <div class="row">
        <div class="col-5">col-5</div>
        <div class="col-5">col-5</div>
    </div>
    <div class="row">
        <div class="col-3">col-3</div>
        <div class="col-7">col-7</div>
    </div>
    <div class="row">
        <div class="col-2">col-2</div>
        <div class="col-6">col-6</div>
    </div>
    <div class="row">
        <div class="col-8">col-8</div>
        <div class="col-4">col-4</div>
    </div>
</div>

至此目前,简单的,列的普通排列没有什么问题,
下来我们要解决另外3个问题:列偏移、嵌套列、列排序。

首先我们看看列偏移。比如我想要某个列相对来说自己的位置向右移动两格。
怎么做?可以添加配置margin-left的样式组:
[quote].col-offset-0{ margin-left:0; }
.col-offset-1{ margin-left:10%; }
.col-offset-2{ margin-left:20%; }
.col-offset-3{ margin-left:30%; }
.col-offset-4{ margin-left:40%; }
.col-offset-5{ margin-left:50%; }
.col-offset-6{ margin-left:60%; }
.col-offset-7{ margin-left:70%; }
.col-offset-8{ margin-left:80%; }
.col-offset-9{ margin-left:90%; }
.col-offset-10{ margin-left:100%; }[/quote]
示例如下:
html 代码

<style>
*{
    box-sizing: border-box;
}
.container:before,
.container:after,
.row:before,
.row:after{
    content:"";
    display:table;
}
.container:after,
.row:after{
    clear:both;
}

.container{
    width: 800px;
    margin: 0 auto;
}
.col-1,.col-2,
.col-3,.col-4,
.col-5,.col-6,
.col-7,.col-8,
.col-9,.col-10{
    float:left;
    padding-left:15px;
    padding-right:15px;
}
.col-1{
    width:10%;
}
.col-2{
    width:20%;
}
.col-3{
    width:30%;
}
.col-4{
    width:40%;
}
.col-5{
    width:50%;
}
.col-6{
    width:60%;
}
.col-7{
    width:70%;
}
.col-8{
    width:80%;
}
.col-9{
    width:90%;
}
.col-10{
    width:100%;
}
.col-offset-0{
    margin-left:0;
}
.col-offset-1{
    margin-left:10%;
}
.col-offset-2{
    margin-left:20%;
}
.col-offset-3{
    margin-left:30%;
}
.col-offset-4{
    margin-left:40%;
}
.col-offset-5{
    margin-left:50%;
}
.col-offset-6{
    margin-left:60%;
}
.col-offset-7{
    margin-left:70%;
}
.col-offset-8{
    margin-left:80%;
}
.col-offset-9{
    margin-left:90%;
}
.col-offset-10{
    margin-left:100%;
}
</style>
<style>
[class^=col] {
    padding-top: 10px;
    padding-bottom: 10px;
    background: #ccc;
    border: 1px solid #ddd;
}
</style>
<div class="container">
    <div class="row">
        <div class="col-1">col-1</div>
        <div class="col-3 col-offset-6">col-3</div>
    </div>
    <div class="row">
        <div class="col-2 col-offset-3">col-2</div>
        <div class="col-2 col-offset-1">col-2</div>
    </div>
</div>

下来我们来看看列嵌套的问题,比如:
html 代码

<style>
*{
    box-sizing: border-box;
}
.container:before,
.container:after,
.row:before,
.row:after{
    content:"";
    display:table;
}
.container:after,
.row:after{
    clear:both;
}

.container{
    width: 800px;
    margin: 0 auto;
}
.col-1,.col-2,
.col-3,.col-4,
.col-5,.col-6,
.col-7,.col-8,
.col-9,.col-10{
    float:left;
    padding-left:15px;
    padding-right:15px;
}
.col-1{
    width:10%;
}
.col-2{
    width:20%;
}
.col-3{
    width:30%;
}
.col-4{
    width:40%;
}
.col-5{
    width:50%;
}
.col-6{
    width:60%;
}
.col-7{
    width:70%;
}
.col-8{
    width:80%;
}
.col-9{
    width:90%;
}
.col-10{
    width:100%;
}
.col-offset-0{
    margin-left:0;
}
.col-offset-1{
    margin-left:10%;
}
.col-offset-2{
    margin-left:20%;
}
.col-offset-3{
    margin-left:30%;
}
.col-offset-4{
    margin-left:40%;
}
.col-offset-5{
    margin-left:50%;
}
.col-offset-6{
    margin-left:60%;
}
.col-offset-7{
    margin-left:70%;
}
.col-offset-8{
    margin-left:80%;
}
.col-offset-9{
    margin-left:90%;
}
.col-offset-10{
    margin-left:100%;
}
</style>
<style>
[class^=col] {
    padding-top: 10px;
    padding-bottom: 10px;
    background: #ccc;
    border: 1px solid #ddd;
}
</style>
<div class="container">
    <div class="row">
        <div class="col-5">
            level1:col-5
            <div class="row">
                <div class="col-3">level2:col-3</div>
                <div class="col-7">level2:col-7</div>
            </div>
        </div>
    </div>
</div>

但是我们发现了问题:row并没有紧紧贴着其父标签,因为每一列两边都有补白,所以出现了问题。
有没有解决方案呢?row的样式我们还没定义,我们设置其边距为对应的负值来抵消:
[quote].row{
margin-left: -15px;
margin-right: -15px;
}[/quote]
测试用例如下:
html 代码

<style>
*{
    box-sizing: border-box;
}
.container:before,
.container:after,
.row:before,
.row:after{
    content:"";
    display:table;
}
.container:after,
.row:after{
    clear:both;
}

.container{
    width: 800px;
    margin: 0 auto;
}
.row{
    margin-left: -15px;
    margin-right: -15px;
}
.col-1,.col-2,
.col-3,.col-4,
.col-5,.col-6,
.col-7,.col-8,
.col-9,.col-10{
    float:left;
    padding-left:15px;
    padding-right:15px;
}
.col-1{
    width:10%;
}
.col-2{
    width:20%;
}
.col-3{
    width:30%;
}
.col-4{
    width:40%;
}
.col-5{
    width:50%;
}
.col-6{
    width:60%;
}
.col-7{
    width:70%;
}
.col-8{
    width:80%;
}
.col-9{
    width:90%;
}
.col-10{
    width:100%;
}
.col-offset-0{
    margin-left:0;
}
.col-offset-1{
    margin-left:10%;
}
.col-offset-2{
    margin-left:20%;
}
.col-offset-3{
    margin-left:30%;
}
.col-offset-4{
    margin-left:40%;
}
.col-offset-5{
    margin-left:50%;
}
.col-offset-6{
    margin-left:60%;
}
.col-offset-7{
    margin-left:70%;
}
.col-offset-8{
    margin-left:80%;
}
.col-offset-9{
    margin-left:90%;
}
.col-offset-10{
    margin-left:100%;
}
</style>
<style>
[class^=col] {
    padding-top: 10px;
    padding-bottom: 10px;
    background: #ccc;
    border: 1px solid #ddd;
}
</style>
<div class="container">
    <div class="row">
        <div class="col-5">
            level1:col-5
            <div class="row">
                <div class="col-3">level2:col-3</div>
                <div class="col-7">level2:col-7</div>
            </div>
        </div>
    </div>
</div>

但是row设置为负值以后那么,container下的row宽度不是800px了(830px)。
因此给container添加padding,来缩小container的内容宽度:
[quote].container{
width: 800px;
margin: 0 auto;
padding-right: 15px;
padding-left: 15px;
}[/quote]
测试用例如下:
html 代码

<style>
*{
    box-sizing: border-box;
}
.container:before,
.container:after,
.row:before,
.row:after{
    content:"";
    display:table;
}
.container:after,
.row:after{
    clear:both;
}

.container{
    width: 800px;
    margin: 0 auto;
    padding-right: 15px;
    padding-left: 15px;
}
.row{
    margin-left: -15px;
    margin-right: -15px;
}
.col-1,.col-2,
.col-3,.col-4,
.col-5,.col-6,
.col-7,.col-8,
.col-9,.col-10{
    float:left;
    padding-left:15px;
    padding-right:15px;
}
.col-1{
    width:10%;
}
.col-2{
    width:20%;
}
.col-3{
    width:30%;
}
.col-4{
    width:40%;
}
.col-5{
    width:50%;
}
.col-6{
    width:60%;
}
.col-7{
    width:70%;
}
.col-8{
    width:80%;
}
.col-9{
    width:90%;
}
.col-10{
    width:100%;
}
.col-offset-0{
    margin-left:0;
}
.col-offset-1{
    margin-left:10%;
}
.col-offset-2{
    margin-left:20%;
}
.col-offset-3{
    margin-left:30%;
}
.col-offset-4{
    margin-left:40%;
}
.col-offset-5{
    margin-left:50%;
}
.col-offset-6{
    margin-left:60%;
}
.col-offset-7{
    margin-left:70%;
}
.col-offset-8{
    margin-left:80%;
}
.col-offset-9{
    margin-left:90%;
}
.col-offset-10{
    margin-left:100%;
}
</style>
<style>
[class^=col] {
    padding-top: 10px;
    padding-bottom: 10px;
    background: #ccc;
    border: 1px solid #ddd;
}
</style>
<div class="container">
    <div class="row">
        <div class="col-10">
            col-10
        </div>
    </div>
</div>

下来是列排序。比如我要第一列放在第二列后面。
此时可以使用相对定位来做。首先让每一列相对自己定位
[quote].col-1,.col-2,.col-3,.col-4,.col-5,
.col-6,.col-7,.col-8,.col-9,.col-10{
position:relative;
float:left;
padding-left:15px;
padding-right:15px;
}[/quote]
然后给出推拉样式:
[quote].col-push-1{ left:10%; }
.col-push-2{ left:20%; }
.col-push-3{ left:30%; }
.col-push-4{ left:40%; }
.col-push-5{ left:50%; }
.col-push-6{ left:60%; }
.col-push-7{ left:70%; }
.col-push-8{ left:80%; }
.col-push-9{ left:90%; }
.col-push-10{ left:100%; }

.col-pull-1{ right:10%; }
.col-pull-2{ right:20%; }
.col-pull-3{ right:30%; }
.col-pull-4{ right:40%; }
.col-pull-5{ right:50%; }
.col-pull-6{ right:60%; }
.col-pull-7{ right:70%; }
.col-pull-8{ right:80%; }
.col-pull-9{ right:90%; }
.col-pull-10{ right:100%; }[/quote]
使用案例如下:
html 代码

<style>
*{
    box-sizing: border-box;
}
.container:before,
.container:after,
.row:before,
.row:after{
    content:"";
    display:table;
}
.container:after,
.row:after{
    clear:both;
}

.container{
    width: 800px;
    margin: 0 auto;
    padding-right: 15px;
    padding-left: 15px;
}
.row{
    margin-left: -15px;
    margin-right: -15px;
}
.col-1,.col-2,
.col-3,.col-4,
.col-5,.col-6,
.col-7,.col-8,
.col-9,.col-10{
    position:relative;
    float:left;
    padding-left:15px;
    padding-right:15px;
}
.col-1{
    width:10%;
}
.col-2{
    width:20%;
}
.col-3{
    width:30%;
}
.col-4{
    width:40%;
}
.col-5{
    width:50%;
}
.col-6{
    width:60%;
}
.col-7{
    width:70%;
}
.col-8{
    width:80%;
}
.col-9{
    width:90%;
}
.col-10{
    width:100%;
}
.col-offset-0{
    margin-left:0;
}
.col-offset-1{
    margin-left:10%;
}
.col-offset-2{
    margin-left:20%;
}
.col-offset-3{
    margin-left:30%;
}
.col-offset-4{
    margin-left:40%;
}
.col-offset-5{
    margin-left:50%;
}
.col-offset-6{
    margin-left:60%;
}
.col-offset-7{
    margin-left:70%;
}
.col-offset-8{
    margin-left:80%;
}
.col-offset-9{
    margin-left:90%;
}
.col-offset-10{
    margin-left:100%;
}
.col-push-1{
    left:10%;
}
.col-push-2{
    left:20%;
}
.col-push-3{
    left:30%;
}
.col-push-4{
    left:40%;
}
.col-push-5{
    left:50%;
}
.col-push-6{
    left:60%;
}
.col-push-7{
    left:70%;
}
.col-push-8{
    left:80%;
}
.col-push-9{
    left:90%;
}
.col-push-10{
    left:100%;
}
.col-pull-1{
    right:10%;
}
.col-pull-2{
    right:20%;
}
.col-pull-3{
    right:30%;
}
.col-pull-4{
    right:40%;
}
.col-pull-5{
    right:50%;
}
.col-pull-6{
    right:60%;
}
.col-pull-7{
    right:70%;
}
.col-pull-8{
    right:80%;
}
.col-pull-9{
    right:90%;
}
.col-pull-10{
    right:100%;
}
</style>
<style>
[class^=col] {
    padding-top: 10px;
    padding-bottom: 10px;
    background: #ccc;
    border: 1px solid #ddd;
}
</style>
<div class="container">
    <div class="row">
        <div class="col-3 col-push-7">
            first col-push-7
        </div>
        <div class="col-7 col-pull-3">
            second col-pull-3
        </div>
    </div>
</div>

恭喜你!看到这里基本上你已经会构建自己的栅格系统了,可以写在简历里面了。
其实这里用的是10,改成12,那么。。。
那么正是bootstrap栅格系统的源码分析。剩下就是差响应式了。
各种添加media的过程了,愿意的话,自己去研究吧。

最后总结一句话:浮动、定位、负边距懂了的话,布局基本ok了。

本文完。

用户评论