CSS:你真的懂margin吗?

你真的了解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”):

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>垂直外边距合并</title>
    <style>
    .top{width:160px; height:50px; background:#ccf;}
    .middle{width:160px; background:#cfc;}
    .middle .firstChild{margin-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还是用Paddingmargin在块元素、内联元素中的区别

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中给出了定义:

“An element that is outside the scope of the CSS formatter, such as an image, embedded document, or applet”

从定义中我们可以理解到,置换元素(replaced element)主要是指 img, input, textarea, select, object 等这类默认就有 CSS 格式化外表范围的元素。进而可知,

非置换元素(non-replaced element)就是除了 img, input, textarea, select, object 等置换元素以外的元素。

margin在块级元素下,他的性能可以完全体现,上下左右任你设定。且记住块级元素的margin的参照基准是前一个元素即相对于自身之前的元素有margin距离。

如果元素是第一个元素,则就是相对于父元素的margin距离(但第一个元素相对于父元素margin-top而父元素又没有设定padding-top/border-top的话要需要印证上面的垂直外边距合并的知识)

margin也能用于内联元素,这是规范所允许的,但是margin-top和margin-bottom对内联元素(对行)的高度没有影响,并且由于边界效果(margin效果)是透明的,他也没有任何的视觉影响。

这是因为边界应用于内联元素时不改变元素的行高度,如果你要改变内联元素的行高即类似文本的行间距,那么你只能使用这三个属性:line-height,fong-size,vertical-
align。

请记住,这个影响内联元素高度的是line-height而不是height,因为内联元素是一行行的,定一个height的话,那这到底是整段inline元素的高呢?还是inline元素一行的高呢?这都说不准,所以统一都给每行定一个高,只能是line-height了。

margin-top/margin-bottom对内联元素没有多大实际效果,不过margin-left/margin-right还是能够对内联元素产生影响的。

应用margin:10px 20px 30px 40px;,左边这个css如果写在inline元素上,他的效果大致是,上下无效果,左边离他相邻元素或者文本距离为40px,右边离他相邻元素或者文本距离为20px。你可以自行尝试一番。

最后在内联元素中还有上文我们提到的非可置换inline元素(non-replaced element),这些个元素img|input|select|textarea|button|label虽然是内联元素,但margin依旧可以影响到他的上下左右!

总结下来margin 属性可以应用于几乎所有的元素,除了表格显示类型(不包括 table-caption, table and inline-table)的元素,而且垂直外边距对非置换内
联元素(non-replaced inline element)不起作用。

CSS:你真的懂margin吗?

时间: 2024-09-30 00:23:03

CSS:你真的懂margin吗?的相关文章

不要告诉我你懂margin

你真的了解margin吗?你知道margin有什么特性吗?你知道什么是垂直外边距合并?margin在块元素.内联元素中的区别?什么时候该用padding而不是margin?你知道负margin吗?你知道负margin在实际工作中的用途吗?常见的浏览器下margin出现的bug有哪些?-- 写css,你少不了与margin打交道,而对于这个平时我们最常用的css属性我们并非十分了解.介于此我打算写下这篇文章,一来是自己工作中的总结,也是对自己知识的一次梳理. Margin是什么 CSS 边距属性定

你真的懂 ajax 吗?

前言 总括: 本文讲解了ajax的历史,工作原理以及优缺点,对XMLHttpRequest对象进行了详细的讲解,并使用原生js实现了一个ajax对象以方便日常开始使用. damonare的ajax库:damonare的ajax库 原文博客地址:你真的懂ajax吗? 知乎专栏&&简书专题:前端进击者(知乎)&&前端进击者(简书) 博主博客地址:Damonare的个人博客 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志. 正文 相信每个前端程序员日常工作中都避免不了的工作就是

你真的懂软件测试吗?

所谓金山银四,又是一波求职月,不安的因素在悸动.测试行业也是如此,作为软件测试员的我也在寻求更好的职业机会,软件测试岗同时也在做筛选,所谓优胜劣汰. 那么面临跳槽季,想在测试行业大展身手的你,真的懂软件测试嘛?小黑板,划重点~ 1.基础知识掌握 这部分,属于对自身的基础能力考查.也是进入测试行业的标准,包括:软件测试原理.软件测试的测试方法了解(刚入行,先了解起来).掌握常见的测试工具(如:UI自动化测试工具TestWriter.开源测试工具QTP.selenium等)等. 2.测试流程掌握 新

CSS盒模型和margin重叠

在 CSS 中,width 和 height 指的是内容区域的宽度和高度.增加内边距.边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸.(div的实际占用尺寸变打了) 但: 一旦为页面设置了恰当的 DTD,大多数浏览器都会按照上面的图示来呈现内容.然而 IE 5 和 6 的呈现却是不正确的.根据 W3C 的规范,元素内容占据的空间是由 width 属性设置的,而内容周围的 padding 和 border 值是另外计算的.不幸的是,IE5.X 和 6 在怪异模式中使用自己的非标准模型

[置顶]云计算乱局:你真的懂,什么叫做云吗?(二)

上一章讲了什么是云,把云的概念给搭建简单的做了分析.这一章我把国内.国外的PaaS平台,即应用托管平台进行了测评对比,包括:国外的AWS.GAE和Windows Azure和国内的京东云擎JAE.百度BAE.新浪SAE.以及阿里云.IBM也宣布了落地国内的计划,IBM的公有云有好几套方案,一个是现有IBM Smarter Cloud的公有云方案,由TSAM和Websphere Pure application这种厚重的企业软件构成,最终在国内落地哪个还不得而知,这里暂不做比较. 比较可以看出,很

javascript的语法作用域你真的懂了吗

有段时间没有更新了,思绪一下子有点转不过来.正应了一句古话"一天不读书,无人看得出:一周不读书,开始会爆粗:一月不读书,智商输给猪.".再加上周五晚上看了下很久没看的湖南综艺节目<天天向上>关于出版书及读书的相关内容,看到相当多的嘉宾家里的书房让我惊叹也伴随着一种文人的向往.我虽然小的时候不太爱看书,但是随着自己一点点的长大,也不知道什么时候开始也有买书藏书看书的情节,而且正如郁钧剑老师所说的藏书有点会上瘾,即使有些书不是马上就会看.挺希望以后不工作了,有自己的一间书屋,一

css之ie6双倍margin问题

1.当一个div设置了浮动且使用了margin时,比如设置左浮动且使用了margin-left(右浮动也是类似) <html> <head> <style type="text/css"> div { width: 200px; height: 200px; background: blue; float: left; margin-left: 100px; } </style> </head> <body> &l

【转】was mutated while being enumerated 你是不是以为你真的懂For...in... ??

原文网址:http://www.jianshu.com/p/ad80d9443a92 支持原创,如需转载, 请注明出处你是不是以为你真的懂For...in... ??哈哈哈哈, 我也碰到了这个报错 .究其原因, 顾名思义 "在枚举的时候发生了变化"for...in...利用了快速枚举NSFastEnumerate当我们想要改变数组变量中的数据或者删除数组中的数据的时候,不能用for...in... 应该是Objective-C中的foreach循环与Java中的相似,在内部是用iter

云计算乱局:你真的懂,什么叫做云吗?(一)

“云”这个词已经被说得烂到不能再烂了.云计算,云平台,云+端,云服务,云……但与很多行业里的朋友聊天发现,其实大家对云计算到底是怎么个玩意,并不是太了解.作者今天为大家梳理一下,各种各样的“云”,葫芦里都在卖什么药. 云是网络.互联网的一种比喻说法,计算可以理解为计算机,因此云计算的基本模型,就是远程计算服务:用户通过网络连接到计算机上,获取计算服务.而远程计算机,因为规模效应,可以提供比个人计算机强大若干个数量级的计算能力,可以根据用户需求提可供弹性伸缩的计算资源,可以大大降低用户获取相同计算