【百度前端学院学习笔记】Day9 圣杯布局和双飞翼布局

  • 圣杯布局(古老而费解的方法)
  • 双飞翼布局(圣杯的改进)

参考资料:
In search of the Holy Grail - A list apart
CSS布局 – 圣杯布局 & 双飞翼布局
双飞翼布局介绍-始于淘宝UED

其实圣杯布局跟双飞翼布局的实现,目的都是左右两栏固定宽度,中间部分自适应。在实现上,DOM结构中先出现中间的部分并让它占据父元素100%宽度。两种方法中间部分不被两边遮挡的时候有所不同。

考虑这样一个DOM结构(完整html代码会放在每个方法的后面)

<div id="header"></div><div id="container"><div id="center" class="column"></div><div id="left" class="column"></div><div id="right" class="column"></div></div><div id="footer">
</div>

在指定左边蓝色的宽度为200px,右边橘色的宽度为150px的情况下,如何实现下面的布局(中间灰色自适应)?

圣杯布局(古老而费解的方法)

  1. DOM结构中(也就是html中),三个div出现的顺序为中、左、右,为什么不是左、中、右呢?接着往下看。
  2. container中留下足够的空间给leftright元素,注意这里用padding给出空间,不影响content(也就是子元素width = 100%)的大小。
    #container{padding-left: 200px;padding-right:190px;overflow: hidden /* 闭合浮动 */}

示意图如下:

  1. 中、左、右三个div都向左浮动,并将定位改成relative待用。
    #container .column{float: left;position: relative;}

此时效果示意图如下:由于center占据了父元素的content 100%的宽度,所以本来应该紧贴着centerleftright不得不被挤到下一行。

  1. left拉到上一行:
#left {width: 200px;        /* LC width */margin-left: -100%;
}

这里要理解一下margin-left设为负值的含义:

margin为正数是向外推开相邻元素以扩展空间,那么margin为负数就是让相邻元素入侵本元素的空间,或者说往反方向推元素。
经过margin-left: -100%的设置,left左边的元素 (即center) 挤占了left100%的宽度(相当于父元素content的宽度),因此会出现这样的情况:leftcenter重叠。

就像下图我画的一样,红色阴影部分为left的margin-left移动经过的区域,蓝笔为left元素的运动轨迹。本来left的位置应该是悬在center左边的,只是因为一行放不下换行了。现在将left的margin-left设为-100%就可以让left移动到新的位置,与center一行,而且遮挡了部分的center

这时候relative的定位就派上用场了:给#left 添加一个right定位,把它向右推200px,正好占满父元素container的left-padding

#left {width: 200px;        /* LC width */margin-left: -100%;  right: 200px;        /* LC width */
}


5. 把right也按照同样的方法,先左推进center同一行内,再通过relative定位推到右边。

#right {width: 150px;          /* RC width */margin-left: -150px;  /* RC width */left: 150px;
}

大功告成

6. 考虑到窗口缩小,直到center自适应的宽度小于left,就会出现这样的情况(双飞翼布局的缺点):

为了避免这种情况,我们给body设置一个最小宽度:

    body{min-width: 550px;}

7.考虑到美观性,我们应该给三个div设置一个padding,这样文字才不会紧贴着边。

【栏内的padding规则】:

  • 这里left维持大小不变,通过缩小width来给padding腾出空间。
#left {width: 180px;        /* LC fullwidth - padding */padding: 0 10px;margin-left: -100%;
}
  • 然后right也是同样地通过调整width来留出padding。
  • center则维持content的宽度100%不变,额外增加10px的上下padding和20px的左右边距(当然也可以通过box-sizing: border-box,这样不改变中间元素的实际宽度,会容易很多,但是为了演示需要,这样还是在100%的基础上额外增加了中间元素的宽度)。

【栏内padding后如何保持布局】:

  • 相应的,left元素的right位置属性要加上center的padding,因为要越过center元素,仅仅靠着margin-left:100%是不够的,还差了一个left-padding和一个right-padding。这是圣杯布局十分麻烦的一个点。
  • right则维持原样。
body {min-width: 630px;      /* 2x (LC fullwidth +CC padding) + RC fullwidth */
}
#container {padding-left: 200px;   /* LC fullwidth */padding-right: 190px;  /* RC fullwidth + CC padding */
}
#container .column {position: relative;float: left;
}
#center {padding: 10px 20px;    /* CC padding */width: 100%;
}
#left {width: 180px;          /* LC width */padding: 0 10px;       /* LC padding */right: 240px;          /* LC fullwidth + CC padding */margin-left: -100%;
}
#right {width: 130px;          /* RC width */padding: 0 10px;       /* RC padding */margin-left: -150px;  /* RC fullwidth */left: 150px;
}
#footer {clear: both;
}/*** IE Fix ***/
* html #left {left: 150px;           /* RC fullwidth */
}
  1. 最后如何使三栏的底部对齐

这里有一个小技巧,即设置一个很长的padding-bottom(要超过原来最长的那个栏),再通过margin-bottom往回压,最后通过父元素的overflow:hidden来修剪。父元素的overflow:hidden属性根据最长子元素的margin位置来确定在哪里修剪。

#container .column {padding-bottom: 20010px;  /* X + padding-bottom */margin-bottom: -20000px;  /* X */
}

这里就是根据右边橘色栏向下padding后又往回margin的位置20010-20000=10px(即修改前右边橘色栏下方10px)的位置修建,效果如下:

最终圣杯布局的完整代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>圣杯布局</title>
<style type="text/css">body{min-width: 630px;}#container{padding-left: 200px;padding-right:190px;overflow: hidden;}#container .column{float: left;position: relative;padding-bottom: 2000px;}#center{padding: 10px 20px;background-color:#d6d6d6;width:100%;}#left{background-color:#77bbdd;width: 180px;right:240px;margin-left: -100%;padding: 0 10px;margin-bottom: -500px;}#right{background-color:#ff6633;width: 130px;padding:0 10px;margin-left: -150px;left:150px;margin-bottom: -500px;}.footer,.header{font-size: 30px;background-color:#999999;clear: both;position: relative;display: flex;}.footer h4,.header h4{margin:0 auto;}p{word-break: break-all;}</style>
</head>
<body>
<div class="header"><h4>header</h4>
</div>
<div id="container"><div id="center" class="column"><h4>middle</h4> <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla.</p></div><div id="left" class="column"><h4>left</h4><p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla.</p></div><div id="right" class="column"><h4>right</h4><p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla.</p></div></div><div class="footer"><h4>footer</h4></div>
</body>
</html>

双飞翼布局(圣杯的改进)

双飞翼在圣杯的基础上进行改进,更加直观。

  1. 首先不再在外层容器中通过padding压缩content的空间来给两个侧边栏预留空间。而是在center里添加一个子元素inside,用子元素的margin来预留空间。
    于是DOM结构改成了:
<div id="header"></div><div id="container"><div id="center" class="column"><div id="inside"></div> <!-- 新增一个inside容器 --></div><div id="left" class="column"></div><div id="right" class="column"></div></div><div id="footer">
</div>



3. 用同样的浮动方法,将左栏和右栏目通过margin-left为负值的方法拉到同一行。下图表示了在没有设置insidemargin的情况下的尴尬场景:inside里的文字左右边都受到了遮挡。

inside加上左右相应大小的margin就可以解决。可以看到,想给center添加额外的padding是很容易的。

    #inside{margin-left: 220px; /* 200px是左边元素的宽度,额外加20px是为了美观 */margin-right:170px; /* 150px是左边元素的宽度,额外加20px是为了美观 */}


双飞翼的完整代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>双飞翼</title>
<style type="text/css">body{min-width: 630px;}#container{overflow: hidden;}#container .column{float: left; padding-bottom: 2010px;margin-bottom: -2000px;}#center{background-color:#d6d6d6;width:100%;}#inside{margin-left: 220px;margin-right:170px;}#left{background-color:#77bbdd;width: 180px;padding: 0 10px;margin-left: -100%;}#right{background-color:#ff6633;width: 130px;padding:0 10px;margin-left: -150px;}.footer,.header{width: 100%;font-size: 30px;background-color:#999999;clear: both;position: relative;display: flex;}.footer h4,.header h4{margin:0 auto;}p{word-break: break-all;}</style>
</head>
<body>
<div class="header"><h4>header</h4>
</div>
<div id="container"><div id="center" class="column"><div id="inside"><h4>middle</h4> <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla.</p></div></div><div id="left" class="column"><h4>left</h4><p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla.</p></div><div id="right" class="column"><h4>right</h4><p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla.</p></div></div><div class="footer"><h4>footer</h4></div>
</body>
</html>

【百度前端学院学习笔记】Day9 圣杯布局和双飞翼布局相关推荐

  1. 【百度前端学院学习笔记】Day6 浮动/BFC

    [百度前端学院学习笔记]Day6 浮动/BFC 一.什么是浮动? 二.普通流 / 浮动 / 绝对定位 三.BFC/Flow Root 3.1 什么是BFC? 3.2 BFC 的特性 3.2.1 特性一 ...

  2. 【WEB】百度糯米学院学习笔记

    一.鼠标悬浮模糊效果(css3实现) 1.图片模糊 -webkit-filter:blur(2px); 2.字体流光渐变效果 (1)绘制渐变背景图 background-image: -webkit- ...

  3. 2018年百度前端技术学院学习笔记

    对百度前端技术学院心仪已久,今天开始正式学习了,特地开个博客记录今后的学习 学了几个月的前端了,之前也做过一些百度前端学院的练习,终于等到2018年前端学院开始,在开头先立flag,本次前端学院的任务 ...

  4. 前端开发学习笔记(一):HTML

    前端开发学习笔记(一):HTML 文章目录 前端开发学习笔记(一):HTML 一. HTML的文档结构 二.标签属性 2.1. 标签属性 2.2. 文字格式化标签 2.3. html实体转义 三. t ...

  5. 尚硅谷谷粒学院学习笔记(防坑点的总结部分勘误)

    谷粒学院学习笔记 部分勘误 数据库设计规约 模块说明 环境搭建 创建一个Spring Boot 的父工程,版本使用:2.2.1.RELEASE 父工程pom.xml里面添加 在pom.xml中添加依赖 ...

  6. 百度前端学院_小薇课堂_task2

    任务目的 针对设计稿样式进行合理的HTML架构,包括以下但不限于: 掌握常用HTML标签的含义.用法 能够基于设计稿来合理规划HTML文档结构 理解语义化,合理地使用HTML标签来构建页面 掌握基本的 ...

  7. 双飞翼布局内容不换行_web前端入门到实战:圣杯布局和双飞翼布局

    稍微了解前端的人都知道,圣杯布局和双飞翼布局是前端面试时必问的问题,因为它既能体现你懂HTML结构又能体现出你对DIV+CSS布局的掌握,毕竟我们学习CSS主要就是为了更好地布局带来最好的用户体验嘛~ ...

  8. 前端面试+学习笔记(HTML+CSS+JavaScript+ES6+Vue+NodeJs)

    前端面试+学习笔记(HTML+CSS+JavaScript+ES6+Vue+NodeJs) 一. HTML 1. 盒子模型 是什么:每个元素被表示为一个矩形的盒子,有四个部分组成:内容(content ...

  9. 百度前端学院_小薇课堂_task_4

    小薇课堂Task_4 在做这个任务前课参考这篇文章 任务目标 实践HTML/CSS布局方式 深入了解position等CSS属性 任务描述 实现如 示例图(点击打开) 的效果 灰色元素水平垂直居中,有 ...

最新文章

  1. 身份证第18位(校验码)的计算方法
  2. mave工程中的一个类调用另一个聚合工程的一个类_谈谈设计模式:建造者模式在jdk中的体现,它和工厂模式区别?...
  3. 近期code(11.16)
  4. android学习笔记---48_实现软件国际化,实现文字国际化,和图片国际化
  5. es6 日期字符串转日期_小数转成百分数,日期字符串互相转换,这几个SQL问题该如何解决?...
  6. 过程改进的疑惑 - 习惯能改么?
  7. shell批量文件编码转换
  8. 计算机网络网络层之IP(2)——IP分片
  9. 29. PHP 错误控制
  10. python下载手机app视频教程_Python实例教学
  11. 单片机学习入门一 学习概述
  12. 职场Word使用技巧大全,教你成为职场高手!
  13. Android初级基础知识复习(十八) —— 自定义通知栏
  14. svga插件_如何压缩SVGA格式的礼物特效文件
  15. java接口返回pdf时修改文件名称问题
  16. 游戏服务器编程-iocp及封包处理
  17. C语言头文件.h互相包含所引发的一系列错误C2143之类的解决方法
  18. pchip和spline区别
  19. Vscode上使用opencv(C++接口,Windows篇)
  20. Mysql批量插入数据问题解决和优化

热门文章

  1. 如何在word中插入横线?
  2. css修改图片尺寸后图片变模糊的问题
  3. vue3 electron 记录
  4. canvas在图片上绘制标记,可拖拽、缩放,基于ZRender
  5. 172.16.82.0/25的含义,IP段,掩码
  6. linux加载不了设备,linux – Debian无法启动:udevd无法加载设备...
  7. 有一天,我们能这样相爱吗?
  8. Linux下常用软件安装
  9. c语言中求一个数的平方根
  10. VLSI数字信号处理系统——第十三章位级运算架构