任务12-负边距、三栏布局

1. 负边距在让元素偏移时和position: relative有什么区别?

通过负边距进行偏移的元素,它会放弃原来占据的空间,这样,它后面文档流中的其它元素就会“流过来填充这部分空间。

在文档流中,元素的最终边界是有 margin 决定的。margin 为负的时候相当于元素的边界向里收,文档流认的是这个边界,不会管你实际尺寸是多少。

psoition: relative; 只是“外观”变了,原来的位置依然“霸占”着,它仍然会坚守着原来占据的空间,不会让文档流其他元素趁虚而入。“页面布局”跟原来一样。偏移后不对周围的元素产生影响。

拓展阅读:

CSS布局奇淫巧计之-强大的负边距

2. 使用负 margin 形成三栏布局有什么条件?

  1. 这“三栏”都要设置浮动
  2. 中间那一栏在最前面(这一栏的宽度会与父容器的 content 一样)
  3. 左右两栏利用负margin"移动"到上面。
  4. 接着就按情况调整,父容器设置 padding、左右两栏设置偏移(relative)等等 或者 在中间那一栏加个 div 在设置两边 margin

另外,负边距对元素宽度的影响

负边距不仅能影响元素在文档流的位置,还可以增加元素的宽度!!!
这个作用的前提是,该元素没有设定 width。

补充:三栏布局

1) 用浮动实现三栏布局

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>浮动实现三栏布局</title>
    <style media="screen">
        body {
            margin: 0;
            padding: 0;
        }
        #left {
            float: left;
            width: 200px;
            height: 200px;
            background-color: red;
        }
        #right {
            float: right;
            width: 180px;
            height: 200px;
            background-color: blue;
        }
        #center {
            height: 500px;
            margin-left: 210px;
            margin-right: 190px;
            background-color: pink;
        }
    </style>
</head>
<body>
    <div id="left">left</div>
    <div id="right">right</div>
    <div id="center">center</div>
</body>
</html>

效果图:

浮动实现三栏布局.png

这种方法的缺点是:#center 必须放在 #left 和 #right (浮动两栏) 的后面。

这里三个div标签的顺序的关键是要把主体div放在最后,左右两栏div顺序任意。

此方法的优点是:代码足够简洁与高效
不足在于:中间主体存在克星,clear:both属性。如果要使用此方法,需避免明显的clear样式。

2) 利用绝对定位实现三栏布局

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>绝对定位实现三栏布局</title>
    <style media="screen">
        html, body {
            margin: 0;
            padding: 0;
            height: 100%;
        }
        #left, #right {
            position: absolute;
            top: 0;
            width: 200px;
            height: 100%;
        }
        #left {
            left: 0;
            background-color: red;
        }
        #right {
            right: 0;
            background-color: blue;
        }
        #center {
            margin: 0 210px;
            background-color: pink;
            height: 100%;
        }
    </style>
</head>
<body>
    <div id="left"></div>
    <div id="center"></div>
    <div id="right"></div>
</body>
</html>

效果图:

绝对定位实现三栏布局.png

这里的左中右三个div的顺序是可以任意调整的。

此方法的优点是,理解容易,上手简单,受内部元素影响而破坏布局的概率低,就是比较经得起折腾。缺点在于:如果中间栏含有最小宽度限制,或是含有宽度的内部元素,当浏览器宽度小到一定程度,会发生层重叠的情况。然而,一般情况下,除非用户显示器分辨率宽度>=1600像素,否则用户不会把浏览器缩小到1000像素以下的,所以该缺陷危害指数3。

3) 圣杯布局、双飞翼布局

略(下面有)

拓展阅读:
  1. CSS中的负边距
  2. 我熟知的三种三栏网页宽度自适应布局方法

3. 圣杯布局的原理是什么?简述实现圣杯布局的步骤

    <div id="content">
        <div class="main"></div>
        <div class="aside"></div>
        <div class="extra"></div>
    </div>

原理
在三列中添加了一个父级容器, 容器设置左右padding,分别等于左右两列的宽度。三列都设置为左浮动,使用负边距和定位将左右两列放置于左右两侧。中间这列设置宽度100%,达到自适应宽度。

  1. “三栏”都要被一个父元素包着。中间那一栏放在最前面(自适应宽度)
  2. “三栏”都要设置浮动
  3. “左右两栏”利用“负margin”来移动到上面去。(.aside {margin-left: -100%;}移动到左上角,.extra {margin-left: -自身宽度;}移动到右上角。)
  4. 父元素 .content 设置 padding (.main 的宽度跟 .content 的 content 相同)来“留空”
拓展阅读:
  1. 圣杯布局学习笔记
  2. 关于「圣杯布局」

4. 双飞翼布局的原理?实现步骤?

双飞翼布局原理跟圣杯布局差不多。
双飞翼布局两边留白是靠 .main 里面增加一个 .wrap (设置margin-left、margin-right),由此,.aside 和 .extra 就不用在设置定位偏移了。而圣杯布局两边留白是靠 .main 的父元素 设置 padding,两边还需要设置偏移。
简单说起来就是”双飞翼布局比圣杯布局多创建了一个div,但不用相对布局了“。

总结:

圣杯布局与双飞翼布局的比较

  1. 两种布局方式都是把主列放在文档流最前面,使主列优先加载。
  2. 两种布局方式在实现上也有相同之处,都是让三列浮动,然后通过负外边距形成三列布局。
  3. 两种布局方式的不同之处在于如何处理中间主列的位置:圣杯布局是利用父容器的左、右内边距定位;双飞翼布局是把主列嵌套在div后利用主列的左、右外边距定位。

两者相比较,双飞翼布局虽然多了一个div,却减少了相对定位属性的代码,个人认为双飞翼布局在实现思路和代码简洁度上都要比圣杯布局更好一些。

拓展阅读:
  1. CSS布局中圣杯布局与双飞翼布局的实现思路差异在哪里?
  2. 浅析圣杯布局和双飞翼布局
  3. margin为负值产生的影响和常见布局应用

补充:

关于 margin

margin 参考线

margin 属性中有 2 类参考线,top 和 left 的参考线属于一类,right 和 bottom 的参考线属于另一类。

top 以 containing block 的 content 上边或者垂直上方相连元素 margin 的下边为参考线垂直向下位移;left 以 containing block 的 content 左边或者水平左方相连元素 margin 的右边为参考线水平向右位移。

right 以元素本身的 border 右边为参考线水平向右位移;bottom 以元素本身的border 下边为参考线垂直向下位移。什么叫以元素本身为参考呢,确切含义是指以自身为参考来影响周围元素的位置(实质即为影响下边和右边相邻元素的参考线)

从上我们可以看到 top 和 left 都是以外元素为参考,而 right 和 bottom 以本元素为参考。

上面的位移方向是指 margin 数值为正值时候的情形,如果是负值则位移方向相反。

示意图:


margin参考线.gif
demo: margin-bottom为负值时
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>我知道你不知道的负Margin - margin参考线举例说明</title>
    <style media="screen">
        * {
            margin: 0;
            padding: 0;
        }
        .wrap {
            width: 400px;
        }
        .example {
            width: 200px;
            height: 200px;
            background-color: #ccccff;

            /*margin: -10px 20px -30px 40px;*/
            margin-bottom: -30px;
        }
        .normal {
            width: 200px;
            height: 200px;
            background-color: #cce8cf;
            opacity: 0.5;
            /*
            normal 仅作为 example 前后(有无 margin)效果的参照
            */
        }
    </style>
</head>
<body>
    <div class="wrap">
        <div class="example">example元素:margin参考线举例说明文字,
        请查看此元素由于margin的变化所移动的位移量</div>
        <div class="normal">一个普通的Box</div>
    </div>
</body>
</html>
margin-bottom负.png

可以看出,当 .example 设置 margin-bottom: -30px; 时,对于自身并没有影响,影响的是下面的 .normal。使 .normal 上移 30px。
因为 .normal 的上边界元素是 .example 。.normal 会根据 .example 的边界来判定自身的位置。
想象下,如果 .example 的 margin-bottom: 30px;,那么 .example 将隔开下方的 .normal ,反之 margin-bottom: -30px;,下方的 .normal 因为 .margin 参考线内凹,导致 .naomal 不得不上移。

什么叫以元素本身为参考呢,确切含义是指以自身为参考来影响周围元素的位置(实质即为影响下边和右边相邻元素的参考线)

另外,margin-bottom: -30px; 并不会改变 .example border内的物理大小,但会改变 box 的逻辑大小,即:以此 box 的 margin 的下边为参考线,不是从 box 的物理位置开始,而是从逻辑位置开始。(现象:.normal 盖住了 .example 的一部分)

总结:
当 margin 4 个值都为正数时,margin 按照正常规律与周围元素产生边距。
当元素 margin 的 top 和 left 为负值时,会令元素上移和左移。
当元素 margin 的 bottom 和 right 为负值时,会影响到下边和右边相邻元素的参考线。

box 最后的显示大小等于 box 的 border 及 border 内的大小加上正的 margin 值。而负的 margin 值不会影响 box 的实际大小,如果是负的 top 或 left 值会引起 box 的向上或向左位置移动,如果是 bottom 或 right 只会影响下面 box 的显示的参考线。

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

推荐阅读更多精彩内容