聊聊常见的布局方法

常见的页面布局

作为一个像我这样的切图仔前端而言,拿到设计图的第一步就是要分析设计图大致地划分区域,然后选择一种最合理的,结构清晰的布局。下面我先根据一些典型的网站案例列举一下几种常见的页面布局。

image.png

1. T形布局

这个是我们比较常见的布局,其页面的顶部一般放置横网站的标志或Banner广告,下方左侧是导航栏菜单,下方右侧则用于放置网页正文等主要内容。
。由于网页太长了。。没有截取底部。


image.png

2. 三栏型布局

国字型布局下最上面是网站的标题以及横幅广告条,接下来是网站的主要内寄,左右分列一些小条内容,中问是主要部分,与左右一起罗列到底,最下方是网站的一些基本信息、联系方式、版权声明等

image.png

3. POP布局

POP布局指页面布局像一张宣传海报,以一张精美图片作为页面的设计中心。常用于时尚类站点。优点显而易见:漂亮吸引人。缺点就是速度慢。人大的主页就类似这种布局。

image.png

4.左右布局型

顾名思义,就是网页主体分为左右两大块,多见为后台管理系统页面。一般左右布局型的页面需要做到两列等高。

image.png

5. 上下布局型

参见苹果的官网,类似于整屏显示的网页都为上下布局。

image.png

如何实现——常见的布局方法

关于布局的类型就先说这么多,下面来总结一下上述的布局怎么来实现。下面提一下大家应该都很熟悉的两大布局方法。圣杯布局和双飞燕布局。其实这两种方法一般多用三行三列布局。进行相应的改造也可以用在T字型布局上。用这两种方法可以很好地解决主体部分优先加载的问题。

1. 圣杯布局

<style type="text/css">
    #main {
        overflow: hidden; /*修整由子元素浮动引起的高度塌陷问题*/
        zoom: 1;/*低版本ie下:触发haslayout属性,修整由子元素浮动引起的高度塌陷问题*/
        /*将主体部分左右侧预留出左右边栏大小的空白位置*/
        padding: 0 300px 0 220px; 
    }
    .m_content, .m_leftside, .m_rightside {
        float: left;
        /*目的是将左右侧边栏拉回*/
        position: relative;
    }
    .m_content {
        width: 100%;
    }
    .m_leftside {
        width: 220px;
        /*由于m_content占据了100%空间,所以需要用负的margin值将左边栏拉回*/
        margin-left: -100%;
        /*将主体部分预留的左侧补白区域填充满*/
        left: -220px;
    }
    .m_rightside {
        width: 300px;
        /*用负的margin值将右边栏拉回自身大小个像素单位*/
        margin-left: -300px;
         /*将主体部分预留的右侧补白区域填充满*/
        left: 300px;
    }
</style>

<div id="main">
    <div class="m_content">这里是主体</div>
    <div class="m_leftside">这是左侧边栏</div>
    <div class="m_rightside">这是右侧边栏</div>
</div>

相关解释如下:

(1)中间部分需要根据浏览器宽度的变化而变化,所以要用100%,这里设左中右向左浮动,因为中间100%,左层和右层根本没有位置上去
(2)把左层margin负100后,发现left上去了,因为负到出窗口没位置了,只能往上挪
(3)按第二步这个方法,可以得出它只要挪动窗口宽度那么宽就能到最左边了,利用负边距,把左右栏定位
(4)但由于左右栏遮挡住了中间部分,于是采用相对定位方法,各自相对于自己把自己挪出去,得到最终结果

2. 双飞翼布局

<style>
    #main {overflow: hidden;zoom: 1;}/*这里不需要加padding了*/
    .m_content, .m_leftside, .m_rightside {float: left;}
    .m_content {width: 100%;}
    /*用左右边距将左右边栏的位置预留出来*/
    .m_c_wrap {margin-left: 220px;margin-right:300px;}
    .m_leftside {width: 220px;margin-left: -100%;}
    .m_rightside {width: 300px;margin-left: -300px;}
</style>

<div id="main">
    <div class="m_content">
        <!--正真的主体开始-->
        <div class="m_c_wrap">这里是主体</div>
    </div>
    <div class="m_leftside">这是左侧边栏</div>
    <div class="m_rightside">这是右侧边栏</div>
</div>

圣杯布局实际看起来是复杂的后期维护性也不是很高,在淘宝UED的探讨下,出来了一种新的布局方式就是双飞翼布局,代码如上。增加多一个父级div就可以不用相对布局了,只用到了浮动和负边距。

3. 多栏等高布局

这里详细总结了等高布局的 八大方法,我再谈谈实际项目中比较常用的,或者说比较简单的三种方法。

  • table布局
    只需要将需要等高的若干栏设置display属性为table-cell;若其中一列希望是自适应宽度,还需将父元素的display设置成table,width为100%。
    代码如下:
<style>
    #main {display: table;width: 100%}
    .m_content {display: table-cell;width: auto;}
    .m_rightside {display: table-cell;width: 200px;}
</style>

<div id="main">
    <div class="m_content"></div>
    <div class="m_rightside"></div>
</div>
  • padding补白
    这是前不久在网上看到的一种办法,实质就是为栏目添加一个足够大的padding-bottom值,将栏目撑开,然后再添加相同大小的负的margin-bottom值将内容移动回来。注意要在负盒子上加上overflow: hidden的属性。
    代码如下:
<style>
    #main {width: 100%;overflow: hidden;}
    .m_content {width: auto;float:left;}
    .m_rightside {width: 200px;padding-bottom: 10000px;margin-bottom: 10000px;float:left;}
</style>

<div id="main">
    <div class="m_content"></div>
    <div class="m_rightside"></div>
</div>

其实发现这不过是BFC中的几个情况而已。更多关于BFC的请移步:

FLEX布局

Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。

flex布局的基本思想是通过flex容器来伸缩控制子项目的宽度和高度,以此来完全填充flex容器的可用空间。子项目的宽高、排列方式等都是通过设置相关属性改变的。那么以这种方式布局上述几种布局就简单多了。子项目默认的排列方式与浮动布局略为相似。

image.png

flex容器的定义方式:

div{display:flex}

flex容器分为主轴和侧轴。主轴决定容器子项的排列方向。侧轴与主轴相互垂直。主轴可有垂直和水平两个方向。
flex容器可对子项进行的操控有:(即设置在容器的属性。这个很重要!)
子项目的排列方向(也就是刚刚说的定义主轴)—— flex-direction

  • 子项目的换行方式(就是超出flex容器跨度时换不换行=。=怎么换) —— flex-wrap
  • 同时进行子项目排列方向和换行方式的设定 —— flex-flow
  • 子项目在主轴的对齐方式(想象成文字的对齐方式就容易理解了) —— justify-content
  • 子项目在侧轴的对齐方式 —— align-items
  • 同时进行子项目主轴和侧轴对齐方式的设定 —— align-content

下面来看看每一个属性的取值和实现效果
flex-direction:

div{ flex-direction: row /*水平排列,默认*/ 
                     <row-reverse> /*水平排列,但子项目从右侧开始排列*/             
                     <column> /*垂直排列*/ 
                     <column-reverse>; /*垂直排列,但子项目从下侧开始排列*/ }

测试中我令flex容器的宽度为100px,高为200px,定义了5个未定义宽高的子项目,演示了上述的四种排列情况。效果:

image.png

这里需要说明的是:在未定义子项目的伸缩方式时,默认是按子项目本身大小渲染的。
flex-wrap

div{ flex-direction: nowrap /*当子项目在主轴上的总跨度大于主轴长度时,不进行换行,而是缩小每个子项目的跨度。默认*/
                     <wrap> /*---同上---进行换行显示*/ 
                     <wrap-reverse> /*从侧轴的末端进行换行(在主轴的排列方向不变)。实际不常用*/ }

测试中我定义了每个子项目的宽度为30px,flex容器还是原来的100px宽。效果:

image.png
image.png
image.png

由于这里设定的是子项目宽度,所以对于主轴为垂直方向的容器子项没什么影响。
flex-flow

div{ flex-flow: <flex-direction> || <flex-wrap>; 
/*就是上述两个属性的结合简写 默认:flex-flow:row nowrap*/ }

justify-content

div{ justify-content: flex-start /*以项目开始进行排列的那端进行对齐,默认左对齐*/ 
                      <flex-end> /*以项目结束排列的那端进行对齐,默认右对齐*/                 
                      <center> /*居中对齐,默认水平居中*/
                      <space-between>  /*两端对齐且项目之间的间隔都相等(贴边显示)*/ 
                      <space-around>  /*第一个元素前的空间以及最后一个元素后的空间为其他空白空间的一半下平均分布*/}

测试时我设定了flex容器宽高都为200px,子项没有设定宽高。 效果:
主轴为水平方向时:


image.png

主轴为水平垂直时:


image.png

align-items

div{ align-items: flex-start /*侧轴起始点对齐*/ 
                  <flex-end> /*侧轴终止点对齐*/ 
                  <center> /*侧轴中点点对齐*/ 
                  <baseline>  /*项目的第一行文字的基线对齐*/ 
                  <stretch> /*默认值,如果项目未设定宽(高度),则占满整个容器侧轴跨度*/ }
image.png

最后的baseline看起来跟flex-start没啥区别,因为我给每个子项设置高度。设置高度后:

image.png

align-content

div{ align-content: flex-start /*与侧轴起始点对齐*/
                    <flex-end> /*与侧轴终止点对齐*/ 
                     <center> /*与侧轴中点点对齐*/ 
                     <space-between>  /*与侧轴两端对齐,各子项在各轴上的间距相等*/ 
                     <space-around> /*各子项在各轴上的间距相等,项目间距比边距间距大一倍*/ 
                     <stretch>/*项目占满整个侧轴*/  }

上面已提到过,对于单轴线的子项来说,本属性不起作用。但是默认情况下是只有子项目是一根轴线的(flex-wrap默认是nowrap),所以要使这个属性看到效果,必须设置flex-wrap。已下是flex-wrapwrap
的几种情况。

image.png

子项

以下这些属性设置在子项上。子项自身的操控有

  • 子项目的排列顺序 —— order
    数值越大,排列越靠后。默认为0
  • 子项目的放大比例 —— flex-grow
    默认为0,即如果主轴上有剩余空间,也不放大子项。
  • 子项目的缩小比例 —— flex-shrink
    默认为1,即如果主轴空间不足,即缩小子项。
  • 设置子项在主轴上的跨度,简单地说就是设置宽高。——flex-basis
  • 同时设定前三者 —— flex
  • 设定单个项目其自身在侧轴的对齐方式 —— align-self

那么分别来看看每个属性的取值和实现效果
order利用这个属性可以解决某个区块优先加载但是在页面上的显示较靠后的问题。

div .item {order:<integer>}
/*数值越大,排列越靠后。默认为0*/
image.png

这里我设置了第一个子项的order为1。

flex-grow如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的空间将比其他项多一倍。

div .item {flex-grow:<number>}

设置flex-grow前:


image.png

设置后:


image.png

第二个项目的flex-grow为2,其他为0:
<注意这个时候就不需要给子项设置宽度了>


image.png

flex-shrink如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。

div .item {flex-shrink:<number>}

我给每个子项设定了200px的宽度,而flex容器宽度为500px,这时候若不设置flex-shrink,则每个项目都会以相同比例缩小自身大小来适应容器。此时我给第二个项目设置了flex-shrink: 0;
该项目大小不变。

image.png

flex-basis这个属性设置子项在主轴上的跨度,简单地说就是设置宽高。

div .item {flex-basis:<length> | auto/*auto是默认值,就是项目本身大小*/}

flex这个就是把flex-grow、flew-shrink、flex-basis结合一起的写法啦=。=

div .item {flex:none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]}

flex-grow必须。默认为0 1 auto
align-self这个属性用来单独设定某个子项目在侧轴的对齐方式。

div .item {align-self:flex-start|flex-end|center|baseline|stretch}
image.png

有关flex布局的方法就总结和介绍到这里了。有兴趣看可以看一下下面大大们写的相关方面的文章。Flex布局教程——阮一峰 传送门A Complete Guide to Flexbox 传送门2一个完整的Flexbox指南 传送门3

栗子(利用flex进行上述几种布局实现)

下边把利用flex布局实现上述几种布局的代码贴出来(可有多种实现方法)。

T布局

image.png
<!--css--><style type="text/css">
    *{margin: 0;padding: 0;}
    header, footer {background: sandybrown;height: 50px;} 
    section {display: flex;align-items: flex-start;height: 500px;} 
    article {order: 1;flex: 3;align-self: stretch;background: wheat;} 
    aside {flex: 1;background: seashell;height: 100px;}
</style>
<!--html-->
<header></header>
<section> 
    <article></article> 
    <aside></aside>
</section>
<footer></footer>

国字型布局

image.png
<!--css-->
<style type="text/css"> 
    *{margin: 0;padding: 0;} 
    header, footer {background: sandybrown;height: 50px;} 
    section {display: flex;align-items: flex-start;height: 500px;} 
    article {order: 1;flex: 3;align-self: stretch;background: wheat;} 
    aside {flex: 1;background: seashell;height: 100px;} 
    section.sidebar {order: 2;flex: 1;height: 100px;background: seashell;}
</style>
<!--html-->
<header></header>
<section> 
    <article></article> 
    <aside></aside>   
    <section class="sidebar">
</section></section>
<footer></footer>

grid布局

grid布局是W3C提出的一个二维布局系统,通过 display: grid 来设置使用,对于以前一些复杂的布局能够得到更简单的解决。本篇文章通过几个布局来对对grid布局进行一个简单的了解。目前,grid仅仅只有Edge使用前缀能够支持,为了更好地体验,可以使用 Chrome 浏览器,在chrome://flags开启#enable-experimental-web-platform-features`选项。另外,更多的例子可以前往 Grid by examples, 更多的用法可以前往 W3 Specification,也可以前往 A Complete Guide to Grid

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容

  • 前言 FlexBox是css3的一种新的布局方式,天生为解决布局问题而存在的它,比起传统的布局方式,我们使用Fle...
    zevei阅读 1,416评论 23 3
  • H5移动端知识点总结 阅读目录 移动开发基本知识点 calc基本用法 box-sizing的理解及使用 理解dis...
    Mx勇阅读 4,437评论 0 26
  • 移动开发基本知识点 一.使用rem作为单位 html { font-size: 100px; } @media(m...
    横冲直撞666阅读 3,460评论 0 6
  • 前言 温馨提示:本文较长,图片较多,本来是想写一篇 CSS 布局方式的,但是奈何 CSS 布局方式种类太多并且实现...
    sunshine小小倩阅读 3,123评论 0 59
  • title: flex布局date: 2017-07-07 14:13:33tags: css笔记 flexbox...
    Gary23阅读 1,525评论 0 0