阅读更多

40顶
2踩

Web前端

转载新闻 IE6 很邪恶,但我爱它的盒子模型

2010-06-12 12:02 by 副主编 just_cool 评论(18) 有9179人浏览
IE6

盒子模型(Box Model)是 CSS 的核心,现代 Web 布局设计简单说就是一堆盒子的排列与嵌套,掌握了盒子模型与它们的摆放控制,会发现再复杂的页面也不过如此,然而,任何美好的事物都有缺憾,盒子模型有两种不同的诠释,一种来自 IE6,一种来自 W3C 标准浏览器。

盒子模型

下图就是一个典型的盒子模型示意图

 

在内容区外面,依次围绕着 padding 区,border 区,margin 区,这一模型结构在所有主流浏览器都是一致的。通过盒子模型,我们可以为我们的内容设置边界,留白以及边距,盒子模型最典型的应用是这样:我们有一段内容,可以为这段内容设置一个边框,为了让内容不至于紧挨着边框,可以设置 padding ,为了让这个盒子不至于和别的盒子靠得太紧,可以设置 margin。

到目前为止,一切都很完美,直到当我们想为这个盒子设置一个尺寸的时候。

IE6 和 W3C 标准浏览器对盒子模型的不同诠释

当我们试图为一个盒子设置尺寸的时候,问题出现了。IE6 和 W3C 标准浏览器对盒子模型有不同的解释,这个不同解释表现在盒子的尺寸上,下图是两种类型的浏览器对盒子尺寸的不同解释示意图:

可以看出,IE6 盒子模型中,盒子的尺寸包含了 内容区,padding, border 和 margin 这四个部分,而 W3C 的盒子模型中,盒子的尺寸只包含内容区,padding,border 和 margin 被排除在盒子尺寸之外。

为什么 IE6 的盒子模型更合理

在现实世界中,我们描述一个物理盒子的时候,如果谈到尺寸,是不会只计算其盛放的物体的尺寸的,我们还会算上空隙与盒体本身。拿集装箱装箱为例,我们有 100 只花瓶,每只花瓶用1个纸盒包装,为了防止花瓶破碎,我们在花瓶周围塞上泡沫,这相当于 padding,纸盒的外围纸板相当于 border,在装集装箱的时候,为了防止纸盒之间相互碰撞,纸盒之间塞上稻草,这相当于 margin,很显然,我们向货运公司报告我们货物尺寸的时候,是要将整个纸盒的尺寸,连同纸盒之间需要塞稻草的空隙都告诉他们的,倘若只报告花瓶的尺寸,货运公司是没有办法装箱的。

再举一个例子,假若我们有一面墙,要在上面挂10幅油画,油画是用相框裱糊的,相框的边框相当于 border,油画和边框之间的距离相当于 padding,相框之间的间隔相当于 margin,这个例子和 Web 布局设计已经很接近了,对任何人来说,使用 IE6 的盒子模型,将整个相框,包括油画当做一个整体更容易布局,当你知道了整个相框的尺寸后,不必再去考虑 padding, border, margin 这个因素的影响,每个相框就是一个整体,至于 padding, border 与 margin,这是浏览器自己事,不需要设计者去关心。

在具体的 Web 设计中

在具体 Web 设计中,尤其牵扯到复杂网格布局的时候,IE6 的盒子模型更容易控制,我们不妨看看以下几个设计场景。

1.  面板式界面设计

页面上包含几个面板,比如一个登录面板,一个最新新闻面板,一个投票面板,这类设计典型的做法是,用背景图的方式,首先逐个设计出这些面板的外观图,将需要用具体内容替换的地方空着,这些面板,无非就是一些使用面板外观图片做背景图的盒子,然后,在这些盒子里面,放上具体的内容,使用 padding 控制内容的摆放位置,使用 margin 调整面板本身的摆放位置,由于面板的尺寸是固定的,我们依此确立了盒子的尺寸之后,就无需再关心尺寸问题,然后,不论你怎样调整 padding 和 margin,都不会影响面板本身的结构。这是 IE6 盒子模型。

而在 W3C 的盒子模型中,调整 padding 和 margin ,都会影响盒子的尺寸,你在调整内容摆放位置的同时,极有可能打乱面板本身的结构。

2. 百分比级尺寸 + 像素级边界问题

W3C 盒子模型在设计中最让人头疼的是,假如你有一个不确定宽度的容器,想在里面放置两个同样大小的盒子,最合理的的做法当时是设置每个盒子的宽度为 50%,这样,不管你的容器宽度为多大,这两个盒子总能自动适应这个宽度,然而,前提是你不要设置任何 padding 或 border,而,现实中,为了防止两个盒子中的内容互相挨得太近,你肯定要设置 padding,一旦设置了 padding,就会发现你的容器被撑破了。

当然你会说,每个盒子的宽度不要设为 50%,可以设为 45%,然后为每个盒子再加一个 5% 的 padding,这是一个解决办法,但我们在设计中经常有这样的习惯,虽然一段内容的宽度可能不确定,但我们总喜欢它拥有固定 padding,我们并不希望 padding 自动适应,况且,在很多时候,我们希望为一个自适应宽度的盒子,设置一个 1 像素的 border,在这种情形,W3C 盒子模型将陷入困境。

而遇到这种情形,IE6 盒子模型不需要任何周折,你只管将每个盒子的宽度设置为 50%,它们会自动适应容器的宽度,然后,不管你你怎样设置 padding 和 border,都不会撑破你的容器。

W3C 在盒子模型上迷途知返

虽然 W3C 永远都不会承认,但他们显然意识到了这个问题,重新定义盒子模型是不可能了,所以,在 CSS3 中,我们看到了下面这个属性:

box-sizing

box-sizing 有两个可选值,一个是默认的 content-box 一个是 border-box,选用后者,盒子模型将按 IE6 的方式进行处理。

 

本文来源:锐商企业CMS 网站内容管理系统 官方网站 (作者:35公里)

来自: comsharp
40
2
评论 共 18 条 请登录后发表评论
18 楼 achun 2010-10-30 11:47
个人认为两种模型各有所长,并有不足
w3c不是什么迷途知返,而是需要把两种模型能通过新的属性,在同一个页面上实现支持是最好的了

如楼主说的:
百分比模式 w3c的盒子不好用一样(如果有边框和间距的设置)
IE6的那个盒子在一个问题上也是不好使:
<img style="width:50;height:50px;border:10px solid red;" src="your.gif" />
<div style="background-color:#ccc;width:50;height:50px;border:10px solid red;"></div>
img的元素的width,height成了一个特例!!!
IE6盒子的这种不一致性,,,会把人弄疯掉的

事实上设计者由于情况的不同,对这个的需求是很随意的
比如我举一个例子,margin的特性,我认为margin是要这样用的
保持相邻元素见的间隔,而不是增加间隔
A和B之间的间隔到底是多少呢?
<b style="margin:20px;">A</b><b style="margin:20px;">B</b>
标准是:40px;
我感觉更方便:20px;

<b style="margin:10px;">A</b><b style="margin:20px;">B</b>
标准是:30px;
我感觉更方便:20px;//取最大值

<b style="margin:-10px;">A</b><b style="margin:20px;">B</b>
标准是:10px;
我感觉更方便:10px;//先满足最大值需求,在满足最小值需求

所以总结一句话就是
margin 规则是,间距<=设定值(其实这个说法不标准,其实是计算问题)

那我这个想法是否合理呢?不讨论了,这个容易拍砖

还是期待,w3c好好规划这个问题吧,多为设计者考虑考虑
17 楼 kaneg 2010-06-15 14:14
ie 是将复杂的东西放在盒子里。而w3c则是把复杂的东西放在盒子外。从这里可以看出还是ie的思想更好一些(把复杂的东西封装,屏蔽起来)
16 楼 xdsnet 2010-06-13 12:34
    其实我觉得盒子模型中盒子大小以边框包括的范围,而不含外部间隔来定义是最和现实接近的。
    当然
引用
开 发 商 计 算 建 筑 面 积 时 用 的 是 I E 6 模 型 , 业 主 计 算 套 内 面 积 时 用 的 是 W 3 C 模 型 。

确实经典
15 楼 andey007518 2010-06-13 12:30
七月十五 写道
jkfzero 写道
cnbeta上一句解释亮了
引用
开 发 商 计 算 建 筑 面 积 时 用 的 是 I E 6 模 型 , 业 主 计 算 套 内 面 积 时 用 的 是 W 3 C 模 型 。


==================
经典,
14 楼 wese345 2010-06-13 10:22
到目前为止,margin与padding这2者之间在页面中的效果,仍然是不断修改代码看效果
13 楼 t42dw 2010-06-13 09:34
本人不是专业的美工由于工作原因总要被拉出来当当美工,我在做css时经常遇到你说的问题而且不知道如何解决!!

  看了你的文章终于知道原因了,呵呵如果以后还有机会做美工这个认识肯定很有用
12 楼 shinezhou 2010-06-13 09:32
盒子模型还是蛮好的。


11 楼 xingqiliudehuanghun 2010-06-13 09:06
好多书上和网上的资料都说这是IE6的问题,但如果你用dreamweaver实验下的话
会发现根本不是那样,这个文章中这个Box模型是IE5的也就是混杂模式下的盒子
模型。只要添加DOCTYPE IE6的盒子模型就和W3C基本一样了。
10 楼 hax 2010-06-13 01:55
w3c的Width/Height表示的是content的宽高。IE则是container的宽高,并不包括margin,原帖有误。

至于w3c的盒子模型在排版时遇到的困难,其实原因在于缺少高级排版特性,比如multicolumn,而设计者必须用其他方式来模仿才导致的。
9 楼 qn_lf 2010-06-12 22:53
都用ie8吧 不过我更喜欢firefox
8 楼 wannago 2010-06-12 22:14
w3c定义box为5x5,margin -6px
那么ie6定义这个box就是:长-1px,宽-1px,
看起来怪怪的。
7 楼 七月十五 2010-06-12 20:15
jkfzero 写道
cnbeta上一句解释亮了
引用
开 发 商 计 算 建 筑 面 积 时 用 的 是 I E 6 模 型 , 业 主 计 算 套 内 面 积 时 用 的 是 W 3 C 模 型 。

6 楼 CrystalBear 2010-06-12 17:29
试试在宽屏机器上的ie6:百分比级尺寸 + 像素级边界问题 ,前一天有个bug和宽屏IE6有关
5 楼 jkfzero 2010-06-12 17:11
cnbeta上一句解释亮了
引用
开 发 商 计 算 建 筑 面 积 时 用 的 是 I E 6 模 型 , 业 主 计 算 套 内 面 积 时 用 的 是 W 3 C 模 型 。
4 楼 全冠清 2010-06-12 17:02
标准不过是商业工具而已
3 楼 fkpwolf 2010-06-12 16:28
mark,这个东西最早在firefox看到时,头都晕了
2 楼 hellas 2010-06-12 12:38
说的很不错
1 楼 trarck 2010-06-12 12:34
ie的宽度是那么定义的吗?加上DOCTYPE与ie与w3c的盒子是一样的。

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 使用GDB查看和修改寄存器的值

    gdb查看,修改CPU中寄存器的值 打印寄存器的值 debug的时候,如果想查看register中的内容,可以使用"i register"命令,i是info命令的缩写,表示列出寄存器的信息。 (gdb) i registers rax 0x7ffff7dd9f60 140737351884640 rbx 0x0 0 rcx ...

  • 逆向学习笔记(4)——动态反调试技术

    1.SEH异常处理 windows中存在许多的异常处理类型,如下: EXCEPTION_DATATYPE_MISALIGNMENT (0x80000002) EXCEPTION_BREAKPOINT (0x80000003) 断点异常 EXCEPTION_SINGLE_STEP (0x80000004) 单步执行 EXCEPTION_ACCESS_VIOLATION (0x8000000

  • 反调试学习

    1. INT 2D INT 2D 原为内核模式中用来触发断点异常的指令,也可以再用户模式下触发异常。但程序调试时不会触发异常,只是忽略。在调试模式中执行完INT 2D后,下条指令的第一个字节将被忽略,后一个字节会被识别为新的指令继续执行。INT 2D的另一个特征是,使用F7 F8命令跟踪INT 2D时,程序不会停在下条指令开始的地方,而是一直运行,知道遇到断点,就像使用F9命令运行程序一样,原因

  • Windows软件调试学习笔记(七)—— 单步步入&单步步过

    软件调试学习笔记(七)—— 单步步入&amp;单步步过单步步入设置单步异常处理单步异常实验1:单步异常的设置与处理单步步过实现思路实验2:实现单步步过 单步步入 描述: 单步步入的实现依赖于单步异常。 当我们需要观察每一行代码(包括函数内部的代码)执行之后寄存器与内存的变化,通常会采用单步步入。 当使用单步步入时,可采用在下一行代码的首字节设置INT 3断点的方式实现。 CPU为我们提供了一种更为方便的方法,即使用陷阱标志位(TF位)。 设置单步异常 TF位:置1 处理单步异常 单步产生的异常与硬件断

  • C语言实现基于单步调试器

    主进程通过创建远程进程来进行调试设置 eFlag 寄存器中的 tf 标志位,使程序执行一条指令后,产生单步执行异常。在异常处理过程中,记录程序执行时所有数据(每一步的 EIP、八个寄存器的值等)。

  • SEH异常处理机制

    1.SEH是windows操作系统提供的异常处理机制。 2.在程序中可以使用__try、__except、__finally关键来实现异常处理。 3.SEH属于系统级的异常处理,是不同于C++中try、catch的。SEH诞生的更早一些。 4.异常处理过程: 正常情况:程序执行-&gt;抛出异常-&gt;程序SEH处理函数-&gt;系统默认SEH处理函数。 调试情况:程序执行-&gt;抛出异常-&gt;调试器中断处理-&gt;程序SEH异常处理-&gt;系统默认异常处理 如果程序没有异常处理函数

  • 冬天OS(六):中断

    -------------------------------------------------------- 初始化 8259A -------------------------------------------------------- 上一节我们编写了 Makefile ,享受到了 Makefile 带给我们的便利,这节我们乘着 make 的便利来设置中断... 一,in...

  • 通过硬件断点对抗hook检测

    前言 我们知道常见的注入方式有IAT hook、SSDT hook、Inline hook等,但其实大体上可以分为两类,一类是基于修改函数地址的hook,一类则是基于修改函数代码的hook。而基于修改函数地址的hook最大的局限性就是只能hook已导出的函数,对于一些未导出函数是无能为力的,所以在真实的hook中,Inline hook反而是更受到青睐的一方。 hook测试 这里我用win32写了一个MessageBox的程序,当点击开始按钮就会弹窗,这里我写了一个Hook_E9函数用来限制对Message

  • [原创]windows-SEH详解

    SEH是window操作系统默认的异常处理机制,逆向分析中,SEH除了基本的异常处理功能外,还大量用于反调试程序(这里SEH时保存在栈中的,漏洞利用的时候会用到) 1.SEH SEH是windows操作系统异常处理机制,在程序源代码中使用__try,__except,__finally关键字来具体实现。 2.OS异常处理的办法 2.1正常运行时候的异常处理方法 进程运行过程中若发生异常,OS会委托进程进行处理。若进程代码中存在具体的异常处理(如SEH异常处理器)...

  • 调试寄存器(DRx)理论与实践

    导读: 标 题:DRx寄存器的使用(待续) (4千字)发信人:hume  时 间:2003-06-18 17:33:11详细信息:调试寄存器(DRx)理论与实践By Hume/冷雨飘心前言+牢骚:生活的苦痛就象烈火,时时煎熬着伤痕累累疲惫不堪的那颗心。我拼力挣扎,然而却无济于事……太残酷了….上帝也在苦笑。                                       

  • EXCEPTION_RECORD structure

    Describes an exception.描述异常的结构体 Syntax C++ typedef struct _EXCEPTION_RECORD { DWORD                    ExceptionCode; DWORD                    ExceptionFlags; struct _EXCEPT

  • 手机射频中的常见术语

    2G:GSM/CDMA 3G:EVDO/WCDMA 4G:TD-LTE/FDD-LTE BB:BaseBand基带 PA:功率放大器,比如B1的,在PA之前是0,经过PA后是22.5db或者22db。 TRX:主集接收和发送的公共端 DRX:分集接收,4G专用 PRX:主集接收,2G,3G,4G使用 FDD:频分双工,联想和电信使用,,移动终端和基站上行和下行使用不同频率电波传输 TDD:时分双工,中国移动使用,移动终端和基站上行和下行使用相同频率电波传输。 T...

  • 常见动态反调试技术总结

    软件安全|反调试技术|动态反调试技术总结

  • 浅析Windows异常处理结构与实现

    浅析Windows异常处理结构与实现   Windows异常处理是操作系统处理程序错误的一种手段,一般有两种:SHE(结构化异常处理)和VEH(向量化异常处理),而UEF(TopLevalEH顶层异常处理)是基于SHE的(这之后应该还有一种VCH),下面我就从上面三方面分析一下Windows异常处理结构。 一、异常处理的个人理解简述   当正在运行一个程序产生了一个异常后,就会利用自身的异常处理来...

  • DrX调试寄存器使用 二 (转)

    DrX调试寄存器使用 二 (转)[@more@]DrX调试寄存器使用 二XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" /&gt;...

  • 调试器相关笔记

    调试器的工作流程 1 调试器进程和目标进程 1.1 调试器进程和目标进程是两个独立的进程.两个进程拥有独立的内存地址. 1.2 一般情况下,调试进程和目标进程的关系有两种,主要区别在于目标进程和调试进程谁先运行: 1.2.1 目标进程由调试器进程创建(调试进程已经运行,目标进程尚未运行,调试器进程通过CreateProcess()创建目标进程.) 1.2.2 调试器进程附加到目标进

  • 从操作系统(Windows)的角度讨论中断和异常机制

    本章的内容是针对Windows XP的32位版本的,但是绝大多数内容也适用于Windows的其他32位版本(Windows NT、Windows 2000和Windows Vista),并且可以比较容易地推广到64位版本的Windows系统。 11.1 中断描述符表 在保护模式下,当有中断或异常发生时,CPU是通过中断描述符表(Interrupt Descriptor Table,IDT)来寻找处理函数的。因此,可以说IDT是CPU(硬件)与操作系统(软件)交接中断和异常的关口(gate)。操作系统在启

  • RF电路图的理解

    RF总体的连接图如下 左边为天线开关模块跟功放的集成体,如RF360,QFE23XX,SKYXXXX                                                  下边以SKY简称 中间的WTR4X05作用:射频收发器,工作过程为(基带信号上/下变频滤波放大信号)    下边以WTR简称 最右边modem_ic指处理器芯片,我们这里可以假设为高通的MS

Global site tag (gtag.js) - Google Analytics