博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
margin系列之圣杯拾遗
阅读量:6412 次
发布时间:2019-06-23

本文共 3409 字,大约阅读时间需要 11 分钟。

  hot3.png

在 一文结尾时,我们谈到了圣杯布局,说这个布局的实现本身存在了一些问题:“在IE6/7下报废,不过不用慌,因为它可被修复”。

圣杯布局的一些谈资

下面节选一段来自网路上对圣杯的描述(略有调整):

圣杯是宗教传说中的圣物,耶稣曾经用这个杯子吩咐门徒喝下里面象征他的血的红葡萄酒,借此创立了受难纪念仪式。因为这个特殊的原因,后来有些人认为这个杯子具有某种神奇的能力。很多传说相信,如果能找到这个圣杯而喝下其盛过的水就将返老还童、死而复生并且获得永生,这个传说广泛延续到很多文学、影视、游戏等作品中。

而所谓的圣杯布局也并不是一个具象的形容,更多的是指借希望于它能够实现某种特殊的布局。

这种特殊布局的需求是:侧边栏宽度固定,主内容栏宽度自适应,并且需要将主内容栏放在侧边栏前面,以便优先渲染(不论是两栏或者三栏,需求都是一样的)。

遗留的问题

在  里,我们用圣杯布局做了 图0 的效果。

下面是我们在上篇文章中写的圣杯布局核心代码(当然,这个 #demo 容器你也可以利用 body来取代):

HTML

12345678
头部
主内容栏自适应宽度
底部

CSS

1234567891011121314151617181920
#demo {    width: 80%;}#bd {    *zoom: 1;    overflow: hidden;    padding-left: 210px;}#main {    float: left;    width: 100%;}#aside {    _display: inline;    float: left;    position: relative;    left: -210px;    width: 200px;    margin-left: -100%;}

大家可以使用各种浏览器来测试一下这个示例 

一般情况下,你会发现除了IE6外,其它的浏览器看起来都算正常,然而问题的范围可能并不仅限于这些,大部分问题没被看出只不过是因为没到达边界。

问题列表:

  • IE6 布局错乱,侧边栏位置不对;
  • IE7 resize窗口时,侧边栏会跳动;
  • IE7及其它浏览器,当窗口缩小到主内容栏的宽度小于侧边栏的宽度时,布局错乱;

上面这几个问题,大家其实都可以自己去测测看,应该是当前的实现中都存在的。

对于第3点,我们看看上述的代码实现,还是能非常轻松的理解的。因为侧边栏定义了 margin-left: -100%,在这个场景中,100% 其实就等同于主内容栏的宽度。如果主内容栏的宽度小于侧边栏,那么侧边栏偏移了一个比自己小的宽度,自然是放不下自己的。

对于第1点,这个就有点意思了,基本上这又算是IE6的一个Bug,描述一下这个Bug的现象:

在IE6中,假定是处于默认的书写模式下,当一个浮动的元素定义了margin的值是一个百分比,那么此时,浮动元素的margin百分比参照最近的清除了浮动的包含块的父元素的宽度进行计算,或者参照body。(然而标准描述只是参考包含块的宽度进行计算,详情请参阅我之前的文章 )

我会用一段伪代码来详述这个事,代码如下:

1
body > c > b > a

假设上述代码中的 a 就是我们说的浮动元素,正常情况下 a 设置了一个百分比的margin,百分比是要参考 b 的宽度进行计算的。

然后 IE6 并没有实现这个规则,它的特征是:

  • 浮动元素 a 定义了百分比的margin,假设它的祖先元素 b 和 c 都没有清除浮动,那么就会参照 body 的宽度进行百分比换算;
  • 假设 b 清除了浮动,那么就会参照 c 的宽度进行百分比换算;

对于这个Bug,我写了一个示例,大家可以对照着描述来看这个例子:

好了,知道了在 IE6 中有这个Bug之后,关于问题列表中的第1点,我们就也能够理解了,因为 position: relative; left: -210px; 这个定义对于 IE6 来讲,其实是多余的。

对于第2点,应该是在resize过程中,不断的重绘造成的,它需要不断的去计算这个百分比的使用值。

杀死它们

所以如果想使得圣杯布局变得更靠谱一些,我们要么就是见招拆招,修复这个问题(比如说为 IE6 重置掉 position: relative; left: -210px; 定义),要么就避免遇上这些问题,我更喜欢第二种的方式。

我们如何做才能避免遇上这些问题?

其实我们可以细看一下,问题列表中的几点,其实都是因浮动元素的margin百分比引发的。既然浮动元素的margin百分比,在各浏览器下需要差异化处理,那么干脆弃用百分比,改用固定值(复杂度其实并没有上升,因为用百分比的时候,还得给left定义一个固定的偏移量)。

那么,新的问题来了。如果改用margin固定值,我们要如何知道这个固定值是多少?比如在这个布局中我们的容器宽度是视窗的 80%,我们无法得到侧边栏需要偏移的固定值是多少,除非我们使用运算表达式 calc(),但是它的兼容性并不是我们想要的。

这是因为主内容栏和侧边栏都是左浮动,并且侧边栏浮动在主内容栏后面,所以我们需要让侧边栏偏移 #main + #aside 的宽度,才能让侧边栏出现在正确的位置。

所以,其实我们可以转变一下思路,让主内容栏和侧边栏朝不同的方向浮动,这样的话,侧边栏只需要偏移自身的宽度就能出现在正确的位置上,不在需要使用margin百分比值。

新路

我们按照前面说的将代码调整一下,HTML不变:

CSS

123456789101112131415161718
#demo {    width: 80%;}#bd {    *zoom: 1;    overflow: hidden;    padding-left: 210px;}#main {    float: right;    width: 100%;}#aside {    _display: inline;    float: left;    width: 200px;    margin: 0 10px 0 -210px;}

我们来看看这个  效果,你会欣喜的发现,问题列表中的3个问题都被我们跳过了,这是一个更健康的实现。

当然,它也是可以任意调整列呈现顺序的,我们只需要这样就行:

CSS

123456789101112131415161718
#demo {    width: 80%;}#bd {    *zoom: 1;    overflow: hidden;    padding-right: 210px;}#main {    float: left;    width: 100%;}#aside {    _display: inline;    float: right;    width: 200px;    margin: 0 -210px 0 10px;}

于是我们就得到了一个  的布局。

总体来讲,圣杯布局只是有能力达成我们的需求,但就其本身来讲并不是太先进的布局,灵活性相对局限。

另外,你可能关注到了代码中出现的 margin 定义,它并不是一个单纯的负值,而是多了一个 10px,这其实是为了解决 IE6/7 右浮动子元素的向右负偏移量最大只能是自身宽度的问题(感兴趣的童鞋可以看看这个测试:),所以额外处理的间隙,但这其实并不影响其他浏览器。

最后

本文,更多的在于补全之前的那篇文章,算个简单的完结。本意其实并不在于说让大家去折腾那些古老而无趣的浏览器,而是希望看到的是对待任何事情,我们首先要觉得它可以解决,然后再抽丝剥茧的去实现它。未知并不可怕,可怕是恐惧未知。

转载于:https://my.oschina.net/jsan/blog/796779

你可能感兴趣的文章
判断是否为数字方法
查看>>
[翻译] EF Core in Action 关于这本书
查看>>
js Uncaught TypeError: undefined is not a function
查看>>
数据库存储引擎
查看>>
[2019.2.13]BZOJ4318 OSU!
查看>>
版本号带两个小数点的,如何比较大小?( NSStringCompareOptions )
查看>>
QCustomplot使用分享(三) 图
查看>>
什么是java?
查看>>
WPF路径动画(动态逆向动画)
查看>>
Low Level Reader Protocol (LLRP) 简介
查看>>
[Micropython]TPYBoard v10x NRF24L01无线通讯模块使用教程
查看>>
mysql中show processlist过滤和杀死线程
查看>>
最新Sublime Text 2 激活 汉化
查看>>
基础数据类型之字典
查看>>
第七次作业
查看>>
Oracle中NVARCHAR2与VARCHAR2的区别
查看>>
php debug
查看>>
Ubuntu构建LVS+Keepalived高可用负载均衡集群【生产环境部署】
查看>>
lvm实现快速备份文件及数据库,lvm快照原理
查看>>
设计模式之Factory Method(工厂方法)
查看>>