CSS-实现全等四宫格的方案【Collection】

2016-02-20  本文已影响3111人  UolCano
全等四宫格.png

如上图,需求如下:

一个未知宽高的容器,要被均分为四个相同大小格子(即四个容器),且格子间有10px间距(即十字型空隙),有哪些方法可以解决呢?

分析问题

一般实现布局,用的多的是CSS的几大属性display float position flex
其中display的应用很灵活,用的最多的是tabletable-cellfloat实现浮动排列,多行可以每行套个容器,也可以不套而是在每行第一个元素前生成用于清除浮动的隐藏内容(::before display:block clear:both; height:0; line-height:0; overflow:hidden; visibility:hidden;);
flex就不用多说了,专为布局而生;
position实现布局需要考虑精确位移,可能需要用到top right bottom left transform:translate() calc()。要注意的是设置position:absolute;的元素是也可以通过设置margin(这个之前记错了,以为设置定位的元素不能使用margin)的来实现定位。(仅CSS而言,暂时想不到其他实现精确位移的方式了)

结构设定

统一CSS设置:

/*CSS Reset*/
.container, .container * { padding: 0; margin: 0; line-height: 0; }
.cell>div { width: 100px; height: 100px; background-color: #598; }

主要HTML结构:

<div class="container">
    <div>
        <div class="cell no1">
            <div></div>
        </div>
        <div class="cell no2">
            <div></div>
        </div>
    </div>
    <div>
        <div class="cell no3">
            <div></div>
        </div>
        <div class="cell no4">
            <div></div>
        </div>
    </div>
</div>

解决方案

以下是目前可想到的解决方案

/* 方案一 ———— table*/
.container {
    display: table;
}
.cell {
    display: table-cell;
}
.cell>div {
    margin: 5px;
}

优点:简单、简洁,松散耦合
缺点:tabletable-cell在IE6/7中可能有兼容性问题

/*方案二 ———— flex*/
.container {
    display: flex;
    flex-flow: column;
}
.container>div {
    display: flex;
    margin: 5px 0;
}
.cell>div {
    margin: 0 5px;
}

优点:简单,松散耦合,布局灵活性大
缺点:flex的兼容性问题

/*方案三 ———— float + clear:both*/
.container>div::before {
    /*主要是清除第二个框前面的浮动*/
    content: '.';
    display: block;
    clear: both;
    height: 0;
    width: 0;
    line-height: 0;
    overflow: hidden;
    visibility: hidden;
}
.cell {
    float: left;
}
.cell>div {
    margin: 5px;
}
/*方案三·改 —— 将清除浮动改为overflow: hidden;*/
.container>div {
    overflow: hidden;
}

优点:兼容性良好;“方案三·改”也可以让代码简洁
缺点:代码量大,并且后面紧跟的页面元素还需要先清除浮动才能保证不影响页面;“方案三·改”在IE6/7可能有兼容性问题

/*方案四 ———— translate + calc()
 *calc()方法 参考自:http://ued.ctrip.com/blog/translation-css-layout-math-read-calc.html
 */
.container {
    position: relative;
}
.container>:last-child {
    transform: translateY(10px);
}
.cell {
    position: absolute;
}
.container>:first-child>.cell:last-child {
    transform: translate(calc(100% + 10px),0);
}
.container>:last-child>.cell:first-child {
    transform: translate(0, 100%);
}
.container>:last-child>.cell:last-child {
    transform: translate(calc(100% + 10px), 100%);
}

优点:不对页面其他元素构成影响
缺点:transformcalc会有兼容性问题。
----割----
之前搞错了position元素使用margin的特性,今天看其他代码时,才发现记错了。所以又想出个方案

/* 方案五 ———— position:relative + margin */
.container {
    /* 用于修正整个四宫格区域对后面页面的影响 */
    overflow: hidden;
    width: 210px;
    height: 210px;
}
.container>:last-child {
    position: relative;
    top: -90px;
}
.cell {
    position: relative;/* 利用相对定位可以位移的特性 */
}
.container .cell:last-child{
    top: -100px;
    left: 110px;
}
/* 方案五·改————可以将top:-90px;部分替换成下面这个 */
.container>:last-child {
    margin-top: -90px;
}

优点:兼容性良好
缺点:因为relative的元素任然会在文档中占用位置,所以会影响四宫格后面的页面内容的布局。不过还好可以对整个四宫格的区域设置固定宽高并且overflow:hidden来解决。可是宽高又是强耦合了。
-----割-----
今天看其他同学引用其他同学的代码(绕得有点...),看到可以实现三列布局效果,但是就是看不明白原理,然后决定一步一步注释了看效果。花了不少时间,但是加深了,对floatpositionrelativeabsolutemargin的理解。因此又想出了一个方案。

/* 方案六 ———— position */
.container {
    /* 用于解决不占用文档位置而影响后面布局的问题 */
    width: 210px;
    height: 210px;
}
.container>div {
    position: relative;
}
.container>div:last-child {
    top: 110px;
}
.cell {
    position: absolute;/* 所有.container>div高度都会变为0 */
}
.cell:last-child {
    left: 110px;
}

优点:绝对兼容
缺点:因为每个格子使用的绝对定位,而且它们的容器(.container>div)以及容器的容器(.container)的高度都未设置也就是默认的跟随内容的auto,所以整个四宫格区域不会占用页面位置,从而后面的页面元素会跑到四宫格下面去。可以通过方案五的方式,给.container设置固定宽高来解决,但是不需要overflow:hidden;

关于CSS方法calc的使用可以看看这篇文章:
【译】CSS的布局数学:读懂calc – 携程设计委员会

以上
欢迎交流。

上一篇下一篇

猜你喜欢

热点阅读