不要告诉我你懂margin

on1y_rL on1y_rL     2022-12-15     335

关键词:

你真的了解margin吗?你知道margin有什么特性吗?你知道什么是垂直外边距合并?margin在块元素、内联元素中的区别?什么时候该用padding而不是margin?你知道负margin吗?你知道负margin在实际工作中的用途吗?常见的浏览器下margin出现的bug有哪些?……

写css,你少不了与margin打交道,而对于这个平时我们最常用的css属性我们并非十分了解。介于此我打算写下这篇文章,一来是自己工作中的总结,也是对自己知识的一次梳理。

Margin是什么

CSS 边距属性定义元素周围的空间。通过使用单独的属性,可以对上、右、下、左的外边距进行设置。也可以使用简写的外边距属性同时改变所有的外边距。——W3School

边界,元素周围生成额外的空白区。“空白区”通常是指其他元素不能出现且父元素背景可见的区域。——CSS权威指南

我比较喜欢使用“外边距”这个词来解释margin(同理padding可以称之为“内边距”,但是我又恰恰喜欢称呼padding为“补白”或者“留白”),我们可以很清楚的了解到margin的最基本用途就是控制元素周围空间的间隔,从视觉角度上达到相互隔开的目的。

Margin的特性

margin始终是透明的。

margin通过使用单独的属性,可以对上、右、下、左的外边距进行设置。即:margin-top、margin-right、margin-bottom、margin-left。

外边距的 margin-width 的值类型有:auto | length | percentage

也可以使用简写的外边距属性同时改变所有的外边距:margin: top right bottom left;(eg: margin:10px 20px 30px 40px) 记忆方式是元素周围正上方顺时针“上右下左”记忆。

并且规范还提供了省略的数值写法,基本如下:

1、如果margin只有一个值,表示上右下左的margin同为这个值。例如:margin:10px; 就等于 margin:10px 10px 10px 10px;

2、如果 margin 只有两个值,第一个值表示上下margin值,第二个值为左右margin的值。例如:margin:10px 20px; 就等于 margin:10px 20px 10px 20px;

3、如果margin有三个值,第一个值表示上margin值,第二个值表示左右margin的值,第三个值表示下margin的值。例如:margin:10px 20px 30px; 就等于 margin:10px 20px 30px 20px;

4、如果margin有四个值,那这四个值分别对应上右下左这四个margin值。例如:margin:10px 20px 30px 40px;

在实际应用中,个人不推荐使用三个值的margin,一是容易记错,二是不容易日后修改,一开始如果写成margin:10px 20px 30px;日后需求改动为上10px,右30px,下30px,左20px,你不得不还是得把这个margin拆开为margin:10px 30px 30px 20px;费力且不讨好,不如一开始就老老实实的写成margin:10px 20px 30px 20px;来的实在,不要为了现在节省俩个字节而让日后再次开发的成本上升。

垂直外边距合并问题

别被上面这个名词给吓倒了,简单地说,外边距合并指的是,当两个垂直外边距相遇时,它们将形成一个外边距。合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者。你可以查看W3Shool CSS外边距合并了解这个基本知识。

实际工作中,垂直外边距合并问题常见于第一个子元素的margin-top会顶开父元素与父元素相邻元素的间距,而且只在标准浏览器下(FirfFox、Chrome、Opera、Sarfi)产生问题,IE下反而表现良好。例子可以查看下面代码(IE下表现“正常”,标准浏览器下查看出现“bug”):

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 < html xmlns = "http://www.w3.org/1999/xhtml" > < head > < title >垂直外边距合并</ title > < style > .topwidth:160px; height:50px; background:#ccf; .middlewidth:160px; background:#cfc; .middle .firstChildmargin-top:20px; </ style > </ head >   < body > < div class = "top" ></ div > < div class = "middle" >    < div class = "firstChild" >我其实只是想和我的父元素隔开点距离。</ div >    < div class = "secondChild" ></ div > </ div > </ body > </ html >

如果按照CSS规范,IE的“良好表现”其实是一个错误的表现,因为IE的hasLayout渲染导致了这个“表现良好”的外观。而其他标准浏览器则会表现出“有问题”的外观。好了,如果你读过了上面W3Shcool的CSS外边距合并的文章后,就很容易讨论这个问题了。这个问题发生的原因是根据规范,一个盒子如果没有上补白(padding-top)和上边框(border-top),那么这个盒子的上边距会和其内部文档流中的第一个子元素的上边距重叠

再说了白点就是:父元素的第一个子元素的上边距margin-top如果碰不到有效的border或者padding.就会不断一层一层的找自己“领导”(父元素,祖先元素)的麻烦。只要给领导设置个有效的 border或者padding就可以有效的管制这个目无领导的margin防止它越级,假传圣旨,把自己的margin当领导的margin执行。
对于垂直外边距合并的解决方案上面已经解释了,为父元素例子中的middle元素增加一个border-top或者padding-top即可解决这个问题。

一般说来这个问题解释到这里,大多数文章就不会再深入下去了,但作为一名实战开发者,最求的是知其然知其所以然,原本使用margin-top就是为了与父元素隔开距离,而按照你这么一个解法,其实是一种“修复”,为了“弥补修复”这个父子垂直外边距合并这个CSS规范“Bug”,而强制在父元素上使用border-top和padding-top,不舒服,也不容易记住,下次再发生这样的情况还是会忘记这条准则,而且在页面设计稿里如果不需要border-top加个上边框,这么一加反而画蛇添足,为以后修改留下隐患。

为什么一定要用border-top,padding-top去为了这么一个所谓的标准规范而多写这么一行代码呢?答案你可以参考另外一篇文章用Margin还是用Padding里找到答案。

用Margin还是用Padding

何时应当使用margin:
需要在border外侧添加空白时。
空白处不需要背景(色)时。
上下相连的两个盒子之间的空白,需要相互抵消时。如15px + 20px的margin,将得到20px的空白。

何时应当时用padding:
需要在border内测添加空白时。
空白处需要背景(色)时。
上下相连的两个盒子之间的空白,希望等于两者之和时。如15px + 20px的padding,将得到35px的空白。

个人认为:margin是用来隔开元素与元素的间距;padding是用来隔开元素与内容的间隔。margin用于布局分开元素使元素与元素互不相干;padding用于元素与内容之间的间隔,让内容(文字)与(包裹)元素之间有一段“呼吸距离”。

这里我截取了部分另外一篇文章的内容,详细内容请见用Margin还是用Padding

margin在块元素、内联元素中的区别

HTML(这里说的是html标准,而不是xhtml)里分两种基本元素,即block和inline。顾名思义,block元素就是以”块”表现的元素(block-like elements),inline元素即是以”行”表现的元素(character level elements and text strings)。二者表现的主要差别在于,在页面文档中block元素另起一行开始,并独占一行。inline元素则同其他inline元素共处一行。

block元素(块元素)大致有:P|H1|H2|H3|H4|H5|H6|UL|OL|PRE| DL | DIV | NOSCRIPT | BLOCKQUOTE | FORM | HR | TABLE | FIELDSET | ADDRESS(随着html5标准的推进,一些元素将被废除,而一些新的元素将被引入)注意的是并非所有的block元素的默认display属性都是block,像table这种display:table的元素也是block元素。

inline元素(内联元素)大致有:#PCDATA(即文本)| TT | I | B | BIG | SMALL|EM | STRONG | DFN | CODE |SAMP | KBD | VAR | CITE | ABBR | ACRONYM|A | IMG | OBJECT | BR | SCRIPT | MAP | Q | SUB | SUP | SPAN | BDO|INPUT | SELECT | TEXTAREA | LABEL | BUTTON

其中有类特殊的元素:如img|input|select|textarea|button|label等,他们被称为可置换元素(Replaced element)。他们区别一般inline元素(相对而言,称non-replaced element)是:这些元素拥有内在尺寸(intrinsic dimensions),他们可以设置width/height属性。他们的性质同设置了display:inline-block的元素一致。

或许有朋友对非置换元素(non-replaced element)有点疑惑,稍微帮助大家理解一下。非置换元素,W3C 中没有给出明确的定义,但我们从字面可以理解到,非置换元素对应着置换元素(replaced element),也就是说我们搞懂了置换元素的含义,就懂了非置换元素。置换元素,W3C中给出了定义:

查看详情

你告诉我你在做什么,工作?你确定你活着?

...来学会如何写代码,如何用框架,如何这样那样。其实我告诉你,你所看的,所想的一切其实都是假的,或者说其实他们根本就是设定好的,你只是一个傻子,你相信吗?傻子~哈哈哈哈!!!且听我给你慢慢道来~ 程序是个... 查看详情

github标星115k,这个文件传输神器别告诉我你还不知道

点击机器学习算法与Python学习,选择加星标精彩内容不迷路开源最前线(ID:OpenSourceTop) 整编综合自:https://github.com/dutchcoders/transfer.sh今天,和大家分享一个简单,方便,快捷的命令行文件分享服务—... 查看详情

github标星115k,这个文件传输神器别告诉我你还不知道

点击机器学习算法与Python学习,选择加星标精彩内容不迷路开源最前线(ID:OpenSourceTop) 整编综合自:https://github.com/dutchcoders/transfer.sh今天,和大家分享一个简单,方便,快捷的命令行文件分享服务—... 查看详情

你别告诉我你还在用excel做数据透视分析吧,太low了!

来到大数据分析的时代,大量的大数据分析软件涌现,尽管如此,如果今天有人问起最常用的数据透视分析工具是什么的时候,我猜想Excel应该是大家的不二之选。 但是其实我想说,用现在的手机来打比方,Excel就好比老人... 查看详情

我需要了解哪些技术才能设置时事通讯?

...ascript、MySQL。我可以根据情况学习新的编程语言或技术。不要告诉我“你不能做你说的”,“你不能没有团队”。告诉我你知道的一切 查看详情

告诉django不要跟随外键?

】告诉django不要跟随外键?【英文标题】:telldjangonottofollowforeignkey?【发布时间】:2011-08-0206:22:26【问题描述】:有没有办法告诉django在实例化模型实例时不要遵循外键关系?模型本身要放什么东西?传递给查询集的东西?我想... 查看详情

java示例代码_告诉代理服务器不要缓存响应

java示例代码_告诉代理服务器不要缓存响应 查看详情

别告诉我你连线程池都不会用~一文搞懂线程池(代码片段)

线程池作用降低资源消耗:通过池化技术重复利用已创建的线程,降低线程创建和销毁造成的损耗。提高响应速度:任务到达时,无需等待线程创建即可立即执行。提高线程的可管理性:线程是稀缺资源,... 查看详情

如何告诉先知不要预测负值

】如何告诉先知不要预测负值【英文标题】:Howtotellprophettonotforecastnegativevalues【发布时间】:2018-01-2721:58:16【问题描述】:在R中使用facebooks\'Prophet\'包进行预测。想知道是否有办法使用它,使其不会预测负值?谢谢!【问题讨... 查看详情

如何告诉 Google 翻译不要翻译网站的某个部分?

】如何告诉Google翻译不要翻译网站的某个部分?【英文标题】:HowcanItellGoogleTranslatetonottranslateasectionofawebsite?【发布时间】:2012-03-2613:49:54【问题描述】:谷歌翻译有一个developertool,可以在网站上启用谷歌翻译。有没有办法告诉... 查看详情

不知何故告诉编译器“不要处理代码行”

】不知何故告诉编译器“不要处理代码行”【英文标题】:Somehowtellcompilerto"Donotprocesslineofcode"【发布时间】:2018-10-0721:58:52【问题描述】:我正在尝试创建一个用于调试日志记录的宏。这是一个额外的简化版本:#ifdefined_... 查看详情

如何告诉 gcc 不要内联函数?

】如何告诉gcc不要内联函数?【英文标题】:HowcanItellgccnottoinlineafunction?【发布时间】:2010-12-0105:39:21【问题描述】:假设我在源文件中有这个小函数staticvoidfoo()我构建了我的二进制文件的优化版本,但我不想内联这个函数(出... 查看详情

如何告诉 qmake 不要创建文件夹?

】如何告诉qmake不要创建文件夹?【英文标题】:HowtellqmakeNOTtocreateafolder?【发布时间】:2014-05-3112:55:44【问题描述】:我想配置我的qmake,以便它可以使我的可执行文件进入./build/debug(或发布)。我已经用下面的代码成功地做到... 查看详情

java示例代码_如何告诉xalan不要使用";文件";作用

java示例代码_如何告诉xalan不要使用";文件";作用 查看详情

告诉 UITableView 在不可见时不要释放单元格

】告诉UITableView在不可见时不要释放单元格【英文标题】:TellUITableViewtonotreleasecellwhennotvisible【发布时间】:2012-04-1215:34:38【问题描述】:有没有什么方法可以告诉UITableView在单元格变得不可见时不释放单元格?我问这个是因为... 查看详情

如何告诉 Fluent NHibernate 不要映射类属性

】如何告诉FluentNHibernate不要映射类属性【英文标题】:HowtotellFluentNHibernatenottomapaclassproperty【发布时间】:2010-10-2819:10:45【问题描述】:我有一个在fluentnhibernate中映射的类,但我希望映射忽略其中一个类属性。下面的类和映射... 查看详情

告诉谷歌不要索引网站的某些部分[关闭]

】告诉谷歌不要索引网站的某些部分[关闭]【英文标题】:Tellgooglenottoindexsomepartsofwebsite[closed]【发布时间】:2013-04-2608:35:08【问题描述】:我在一个网站上工作,我无法告诉谷歌不要索引一个&lt;div&gt;,它通常在加载时是... 查看详情