开发者社区> 问答> 正文

CSS布局问题 , 如何实现一行多列div,类似于表格

也就是可以像表格那样,自由地把一行拆分成多列,甚至列内也做拆分,并且每列所占的大小/比例可以精确控制

大家都有哪些实践经验可以分享?我试过使用float为left来控制,总感觉不灵活,而且容易算不准。

展开
收起
a123456678 2016-03-25 13:53:49 2660 0
2 条回答
写回答
取消 提交回答
  • float: left; flex-direction: row; 均可实现
    2019-07-17 19:14:09
    赞同 展开评论 打赏
  • 水平拆分方案A:百分比宽度+float
    可以全浏览器兼容,但是需要用到一些hack解决float定位的问题,同时需要考虑清除浮动。
    
    在很多比例(1/3、2/3是最常见的情形)不能整除的情况下,在一些情形下出现1px的误差。
    
    水平拆分方案B:百分比宽度+不带间隙的inline-box
    缺点同上。hack量和方案A不相上下。
    
    额外的好处是有很多vertical-align方式可以指定,额外的坏处是很多vertical-align的属性值对于各个浏览器来说都不一样。最常见的vertical-align还是middle和baseline,顶多再加个top和bottom。
    
    水平拆分方案C:表格
    用表格当然是全浏览器支持的选择。
    
    水平拆分方案D:display属性代替表格
    用display:table和display:table-cell等属性替代表格,以兼顾语义。IE8+和现代浏览器支持。
    
    更多前瞻属性……
    使用css3的新特性calc来计算值 + float/inline-box
    使用flexbox
    下面介绍bootstrap的一套可复用的方案,这套方案是从方案A发展而来,主题思想是抽取出布局中可以复用的类。
    
    一个常见的列拆分如下:
    
    <div class="container">
      <div class="row">
        <div class="col-md-3"></div>
        ...
      </div>
    </div>
    bootstrap的栅格系统的核心,即是使用这样的一个三层结构,最内层使用width来分配100%的父级宽度。
    
    对于单列的类名规则是:col-[lg/md/sm/xs]-[1~12]。详情见bootstrap栅格选项。
    
    中间的变量跟响应式media查询有关,这里不详细解释。最后一个值x,既等分父容器的1/12乘以x。如下:
    
    .col-md-3 { float:left; }
    @media (min-width: 992px) {
      .col-md-3 { width: 25%; }
      /* 父级容器的3/12 */
    }
    在bootstrap栅格系统中,每个col之间都有30px间隙,如何做到等分间隙呢?见如下CSS属性:
    
    /* 列容器设置左右padding */
    .col-md-3 {
      min-height: 1px;
      padding-right: 15px;
      padding-left: 15px;
    }
    /* 行容器设置负margin撑开 */
    .row {
      margin-right: -15px;
      margin-left: -15px;
    }
    /* 行容器清理浮动 */
    .row:before,
    .row:after {
      display: table;
      content: " ";
    }
    .row:after {
      clear: both;
    }
    /* container再补完被row挖去的15px */
    .container {
      padding-right: 15px;
      padding-left: 15px;
    }
    等等,是不是有哪里不对?计算一下宽度:
    
    每一个col-md-3的最终宽度 = 父容器宽度 * 25% + 15px * 2 (padding宽度) + 0 (border宽度)
    怎么会每个都1/4等分父容器呢?
    
    还有这个属性在作用:
    
    *, *:before, *:after {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    }
    bootstrap使用*来选取所有元素(这是我对bootstrap感到厌烦的原因,为了开发效率,牺牲选择器效率),并强制使用border-box计算宽度,因而达到了布局上的大和谐这样的计算公式:
    
    父容器宽度 * 25% = 每一个col-md-3的最终宽度 + 15px * 2 (padding宽度) + 0 (border宽度)
    这样做以后,可以很方便地拿出对应的类来使用,也可以级联,类似于row-col-row-col-row-col……
    
      div.container
            h1 test
            div.row
                div.col-sm-6
                    div.row
                        div.col-sm-6
                            img(data-src="holder.js/100%x180")
                        div.col-sm-6
                            img(data-src="holder.js/100%x180")
                div.col-sm-6
                    div.row
                        div.col-sm-3
                            img(data-src="holder.js/100%x180")
                        div.col-sm-9
                            img(data-src="holder.js/100%x180")
    2019-07-17 19:14:09
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
零基础CSS入门教程 立即下载
低代码开发师(初级)实战教程 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载