以前は、margin 属性は非常に単純な属性だと常に思っていましたが、最近プロジェクトに取り組んでいるときにいくつかの問題に遭遇したとき、margin 属性にはまだいくつかの「落とし穴」があることに気づきました。以下に、margin 属性の基礎知識を紹介します。マージンとそれらの「ピット」。このブログ記事は主に以下のパートに分かれています:
margin--基礎知識
margin--兄弟要素間の適用(非親子関係)
margin--親要素についてと サブ要素間の適用 (重要なポイント)
マージン - マージン値の単位が % の場合のいくつかの状況
パート 1: マージン - 基礎知識
マージンの基礎知識を紹介します、私たち CSSボックスモデル(ボックスモデル)について話すのは避けられません 一般的に、CSSボックスモデルはデザインとレイアウトに使用されます。これは本質的には、マージン、ボーダー、パディング、中央のコンテンツを含むボックスです。下の図はボックス モデルです (ここでは W3C 仕様の標準ボックス モデルについてのみ説明し、IE5 および IE6 の奇妙なモードで使用される非標準ボックス モデルについては説明しません):
必要なマージン最後にご紹介するのは、外側のレイヤーではマージン(余白)を透明にする必要があるため、異なるボックスの間に一定の隙間を残すことで、美しいレイアウトなどの効果を得ることができます。上記のボックス モデルから、マージンがすべての側面に存在することがわかります。margin-top、margin-right、margin-bottom、および margin-left を使用して、これら 4 つの方向のマージン値をそれぞれ設定できます。 (注: この部分の知識は比較的基本的なため、この部分ではこれ以上の紹介は行いません)
第 2 部: margin--兄弟要素間の適用 (非親子関係)
この部分では主に紹介します水平方向と垂直方向のマージンを結合する問題。
(1) 水平方向のマージンを結合します
2 つの水平方向のボックスが接し、それらの間の最終的な距離は、左のボックスの右マージンと右のボックスの右マージンの合計になります。
例 1:
コードは次のとおりです:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>水平方向的两个盒子</title> <style> *{ margin:0; padding:0; border:0; } body{ font-size: 0; } .left{ width: 100px; height: 100px; background: red; display: inline-block; margin-right: 50px; font-size: 20px; } .right{ width: 100px; height: 100px; background: yellow; display: inline-block; margin-left: 50px; font-size: 20px; } </style> </head> <body> <p class="left">宽为100px,右边距为50px</p> <p class="right">宽为100px,左边距为50px</p> </body> </html>
効果は次のとおりです:
この時点で、2 つの間の距離はちょうど 100px です。
追加説明: ご覧のとおり、2 つの p (ブロック要素) を通常のドキュメント フローから外すために、display:inline-block; 属性も変更しました。本文のフォントサイズ 0 に設定すると、インラインブロック自体の問題を解決できます。そうしないと、2 つの p の例が 100px より大きくなります。もちろん、float を使用して 2 つの p を同じ行に表示することもできます。
(2) 縦のマージンを結合
2つの縦のボックスが接するとき、縦方向の距離は、上のボックスの下のマージンと下のボックスの上のマージンの大きい方に等しくなります。
例 2:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>水平方向的两个盒子</title> <style> *{ margin:0; padding:0; border:0; } .top{ width: 100px; height: 100px; margin-bottom: 100px; background: red; } .bottom{ width: 100px; height: 100px; margin-top: 50px; background: green; } </style> </head> <body> <p class="top">高为100px,下边距为100px</p> <p class="bottom">高为100px,上边距为50px</p> </body> </html>
効果は次のとおりです:
2 つの縦の例は、100 ピクセル以上ではなく、約 100 ピクセル (実際には 100 ピクセル) です。 50=150px; これは、2 つの垂直ボックスが接するとき、垂直距離が上のボックスの下マージンと下のボックスの上マージンの大きい方に等しいためです。
もう 1 つの興味深い例は次のとおりです。 margin-top と margin-bottom が同時に設定された要素があるが、その内容が空であるとします。その場合、2 つのマージン値も重ね合わされ、その値は2 つのうちの最大のものは、2 つのボックスのマージン値を垂直方向に重ね合わせたものに似ています。コードは次のとおりです:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>水平方向的两个盒子</title> <style> *{ margin:0; padding:0; } .top{ width: 500px; height: 100px; background: red; } .middle{ margin-top: 100px; margin-bottom:50px; } .footer{ width: 500px; height: 100px; background: green; } </style> </head> <body> <p class="top">上面的p,高100px</p> <p class="middle"></p> <p class="footer">下面的p,高100px</p> </body> </html>
最終的な効果は次のとおりです:
上の p と下の p の間の例は 100+50=150px ではなく、2 であることがわかりました。そのうちの最大のものは 100px です。
それでは、なぜ W3C はそのような標準を設定し、水平方向と同じ標準を設定しないのでしょうか?つまり、マージン値の重ね合わせです。実際、これも意味があります。たとえば、複数の段落で構成されるページをデザインする必要があります。最初の段落とページの上部との間に距離があり、最後の段落と下部の間に距離があるように、margin-top と margin-bottom を設定する必要があります。以下はオーバーレイなしとオーバーレイありのレンダリングです:
我们可以看到左边的页面没有重叠,那么两个段落之间的举例就是最上方的两倍间距了,而右边的页面发生了重叠,则所有的间距都是相等的。或许这就是这样设定标准的目的吧,谁知道呢?
第三部分:margin--在父元素和子元素之间应用(重点)
第二部分介绍了同级元素之间使用margin,而这一部分将要介绍最有意思的父元素和子元素之间margin的应用。这一部分,我们同样从两个方面来讨论。一方面是子元素设置水平方向上的margin值,另一方面是子元素设置竖直方向的margin值。
(1)在子元素中设置水平方向的margin值
我们可以设置margin-left来控制子元素的左边框和父元素的左边框之间的举例。
例3:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>margin</title> <style> *{padding:0; margin:0; border:0;} .father{ width: 500px; height: 500px; background: red; } .son{ width: 100px; height: 100px; background: green; margin-left: 100px; } </style> </head> <body> <p class="father"> <p class="son">宽度为100px,margin-left为100px。</p> </p> </body> </html>
我将子元素的margin-left设置为了100px;效果如下:
即子元素的左边框和父元素的左边框之间的距离为100px。与在同级元素之间设置margin不同,因为同级元素之间的margin不会考虑到padding,但是在父元素和子元素就不同了,那么如果父元素中如果有padding,效果会是什么样的呢?请看下面一个例子:
例4:
下面我们在上面例子的基础上给父元素添加padding值。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>margin</title> <style> *{padding:0; margin:0; border:0;} .father{ width: 500px; height: 500px; padding:100px; background: red; } .son{ width: 100px; height: 100px; background: green; margin-left: 100px; } </style> </head> <body> <p class="father"> <p class="son">宽度为100px,margin-left为100px。</p> </p> </body> </html>
上面的代码给父元素添加了100px的padding值,效果如下:
我们可以看到子元素举例上方的距离为100px,因为子元素一定是在父元素的content的部分的,这点毫无疑问。
但是经过测量可以发现子元素的左边框距离父元素的左边框之间的距离为200px,因为其中还有100px的左padding值,前面的例子因为我没有设置padding值,所以没有观察出来,因此这就说明了在子元素中设置margin-left,其值实际上是子元素的左边框距离父元素左padding内侧的距离。
例5:margin-right的使用和margin-left的使用是相似的,我在这里只举一个例子。
这个例子在子元素中设置了margin-right值,如下所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>margin</title> <style> *{padding:0; margin:0; border:0;} .father{ width: 500px; height: 500px; padding:100px; background: red; } .son{ float: right; width: 100px; height: 100px; background: green; margin-right: 100px; } </style> </head> <body> <p class="father"> <p class="son">宽度为100px,margin-right为100px。</p> </p> </body> </html>
这个例子与例4的区别仅在与子元素的位置不同。效果如下:
通过这个例子可以说明margin-right的值是子元素的右边框和父元素的右padding内侧的距离。只是前面的几个例子我没有使用padding,所以无法观察出来。
(2)在子元素中设置竖直方向的margin值
按照前面的经验,理论上来说,我们同样可以通过设置margin-top的值使得子元素的上边框和父元素的上padding的内侧留有一定的距离。那么我们就试试吧!
例6:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>margin</title> <style> *{padding:0; margin:0; border:0;} .father{ width: 500px; height: 500px; background: red; } .son{ width: 100px; height: 100px; background: green; margin-top: 100px; } </style> </head> <body> <p class="father"> <p class="son">高度为100px,margin-top为100px。</p> </p> </body> </html>
这个例子我设置了margin-top为100px,效果如下:
这并不是我们想要的效果啊,我们希望子元素的上部距离父元素的上部为100px,可是我们看到的却是父元素的上部距离浏览器页面的上部有100px的距离,这是为什么呢?哪里出现问题了呢?
实际上这是因为当父元素没有设置padding值以及border值时,出现了一个bug--父元素的上方与子元素的上方完全重合在了一起,无法分开。所以才会导致上述这种父元素和子元素同时向下的情况。
对于这种问题解决方法有下面几种:
方法一:给父元素添加padding-top值
方法二:给父元素添加border值
方法三:给父元素添加属性overflow:hidden;
方法四:给父元素或者子元素声明浮动float
方法五:使父元素或子元素声明为绝对定位:position:absolute;
方法六:给父元素添加属性 overflow:auto; positon:relative;(注:此方法为后续添加,感谢博友@小精灵Pawn提供此方法)
方法一:基于例6,在父元素的css代码中添加padding-top:1px;效果如下:
方法的唯一缺点就是增加了1px的误差。
方法二:基于例6,在父元素的css代码中添加border-top:1px solid transparent;效果如下:
同样达到了效果, 缺点同方法一。
方法三:基于例6,在父元素的css代码中添加overflow:hidden;效果如下:
同样达到了效果,并且没有任何误差的存在。堪称perfect!!!!
方法四:给父元素或者子元素声明float;基于例6,在子元素css代码添加float:left;或者在父元素css代码添加float:left;均达到效果,这里不再展示相同的图片。
优点:没有像素的误差。 缺点:float有时是不必要的。
方法五:给父元素或者子元素添加position:absolute;属性。 同样达到效果。
优点:同方法四。 且只要我们不使用top和left也不会有任何影响,所以这也是一种不错的方法。
方法六:给父元素添加overflow:auto;和position:relative;同样达到效果。
第四部分:margin值的单位为%时的几种情况
之前我举例子时使用margin,它的值都是以px为单位的,这个理解起来没有问题。但是如果margin值是以%为单位呢?实际上这时候百分比(%)是相对于该元素的父元素(容器),对于同级元素和父子元素都是如此。(再次感谢 博友@小精灵Pawn 提供的建议!!基于此建议补充这部分内容) 但是在同级元素中使用竖直方向的margin时会出现意想不到的结果,下面举例说明。
(1)同级元素在水平方向使用值为%的margin
例7:
<head> <meta charset="UTF-8"> <title>margin</title> <style> *{ margin:0; padding:0; } .first{ float: left; width: 200px; height: 200px; background: green; } .second{ float: left; width: 200px; height: 200px; background: red; margin-left: 20%; } </style> </head> <body> <p class="first">宽为200,无margin</p> <p class="second">宽为200,margin-left为20%;</p> </body> </html>
这个例子中,设置两个元素向左浮动,以便于观察两者水平方向的margin。其中左边p无margin,右边p的margin-left为20%,效果如下:
从效果图可以看出两个p之间的间距始终为父元素(这里右边p的父元素即为body,其宽度为浏览器宽度)的20%。
(2)同级元素在竖直方向使用值为%的margin
根据例7的启发,我们可以猜想,如果在竖直方向上使用margin,且值的单位为%,那么最终两者之间的距离将是父元素(上例中为body)的百分数。那么究竟是不是这样呢?看下面的例子。
例8
<head> <meta charset="UTF-8"> <title>margin</title> <style> *{ margin:0; padding:0; } .first{ width: 200px; height: 200px; background: green; } .second{ width: 200px; height: 200px; background: red; margin-top: 10%; } </style> </head> <body> <p class="first">高为200,无margin</p> <p class="second">高为200,margin-top为20%;</p> </body> </html>
这里设置上面的p无margin,下面的p的margin-top为10。效果如下:
我们发现,当我在缩小浏览器的高度时,竖直方向上的间距并没有缩小!!! 而当我缩小浏览器的宽度时,竖直方向上的距离缩小了!!!
这就说明:统计元素之间在竖直方向上使用margin,当值的单位为%时,它是相对于父元素的宽度。
那么这里为什么不是如我们所希望的那样相对于浏览器的高度呢?知乎上有大神是这样解释的:
(3)父子元素使用值为%的margin
对于父子元素,如果在子元素中使用单位为%margin,那么这个margin值是相对于父元素的宽度和高度(注意:这时的确是相对于父元素的高度!)的。
例9
代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> *{ margin:0; padding:0; } .father{ width: 500px; height: 300px; background: red; overflow: hidden; } .son{ width: 100px; height: 100px; background: green; margin-top: 20%; margin-left: 20%; } </style> </head> <body> <p class="father"> <p class="son"></p> </p> </body> </html>
この例では、margin-left の値を 20%、margin-top の値を 20%、親要素の幅を 500px、親要素の高さを 300px に設定します。以下で効果を見てみましょう。
上の図からわかるように、子要素のマージントップの値は、最終的には高さではなく、親要素の幅に相対します。
概要:
このブログ記事はマージンに関する知識の一部を紹介するだけですが、読んで皆さんが何かを得ることができれば幸いです。急いでまとめたものと知識不足のため間違いは避けられませんので、もし間違っている点があればご意見いただければ幸いです。
以上がこの記事の全内容です。皆さんの学習に役立つことを願っています。また、皆さんも PHP 中国語 Web サイトをサポートしていただければ幸いです。
CSS の margin 属性に関連するその他の記事については、PHP 中国語 Web サイトに注目してください。