margin 属性は多くの HTML 要素の幅と高さを決定できるため、レイアウトにおいても非常に重要な役割を果たすことができます。次に、ページ レイアウトでの CSS の margin 属性の使用方法を見てみましょう
。基本
1. ボックスを含む要素の幅と高さはコンテンツの幅と等しい
HTML
<p class="wrap"> <p class="item1"></p> <p class="item2"></p> </p>
CSS
.wrap { float: left; border: 2px solid #000; } .item1 { width: 100px; height: 100px; background: #fdf; margin-left: 10px; margin-top: 10px; margin-right: 20px; margin-bottom: 30px; } item2 { width: 50px; height: 50px; background: #adf; }
原則 1 を満たすことができる条件は 1 つだけです。 、要素には幅がなく、ドキュメント内にありません。フローでは、この時点で、親要素のラップによって生成される包含ボックスの幅と高さは、親要素のボーダーボックスの幅と高さに等しくなります。子要素にマージンの幅と高さを加えたものです。つまり、子要素のマージンの値は、その要素を含むボックスの幅と高さでもあります。マージンの基準線には 2 種類あります。1 つ目は margin-top と margin-left の基準線です。1 つ目は margin-bottom と margin-right の基準線です。上の例で示したように、要素 .item1 の margin-top と margin-left の値を調整すると、その位置に基づいてボックスの端の線が基準線となります。要素 .item1 が配置されているボックスも変化するため、そのエッジの線も常に変化し、これにより .item1 要素自体の位置も変化します。 .item1 自体が移動したように見えます。 2 番目のタイプのマージンの基準線は、要素自体のエッジ ラインに基づいています (マージンの外側がエッジ ラインです)。同様に、上の例では margin-bottom の値、 の margin-bottom を調整します。 item1 も常に変化しており、それ自体のエッジ ラインが常に移動しており、それが .item2 の移動にもつながります。上記の議論に基づいて、マージンの調整は、それ自体の相対的な基準線の位置を移動させると同時に、基準線に対して相対的に移動する要素を移動させることと同等であると結論付けることができます。要素自体は、包含ボックスのエッジ線に対して相対的に移動し、要素自体の兄弟である要素は、要素自体のエッジ線に対して相対的に移動します。基準線の模式図は図のようになります。基準線の矢印方向の変化のマージン値はすべて正の値になります。
要約すると、マージンを使用して要素自体を移動することも、隣接する要素を移動することもできます。移動するときに知っておく必要があるのは、その要素が含まれるボックスのサイズも変化するということです。
要約すると、要素の幅と高さがコンテンツの幅と高さに等しい場合、その要素を含むボックスのサイズは、コンテンツのマージン値を調整することで調整できます。 contains-box は要素自体を移動させることもできます。つまり、要素を移動したり、要素間の間隔を調整したりすることもできると言われています。
2. 要素コンテンツの幅は、その要素を含むボックスの幅と等しくなります
<p class="wrap"> <p class="wrap-inner"></p> </p>
.wrap { width: 100px; border: 2px solid #000; margin: 0 auto; } .wrap-inner { height: 50px; background: #fdf; }
上の例では、要素の Wrap-inner のボーダーボックスの幅に、マージンのサイズは、その包含ボックスの幅に等しいため、包含ボックスの幅が固定されている場合、式 'margin-left' + 'border-left-width' + 'padding-left' + ' に従います。 width' + 'padding-right' + 'border-right-width' + 'margin -right' = 包含ブロックの幅。独自の margin-left または margin-right 値を調整すると、wrap-inner 自体のサイズが変更されます。 margin-left が正の値で徐々に大きくなると、wrap-inner 自体の幅が徐々に小さくなり、margin-left が負の値で徐々に小さくなると、wrap-inner 自体の幅が徐々に大きくなります。同じことがマージン右にも当てはまります。ここでの幅の継承は、基本的に width:100% とは異なることに注意してください。width:100% はそのボックスの 100% に等しく、そのマージン、ボーダー、またはパディングとは何の関係もありません。詳細については、「」を参照してください。幅と高さについて説明する一連の記事の 3 番目の記事の例は少し冗長ですが、ここは間違いが起こりやすい箇所です。注意しなければなりません、注意しなければなりません、注意しなければなりません! ! ! 。大事なことは3回言いましょう。
図に示すように、左右のマージンを-10pxに調整すると、計算に従ってラップ内側が広くなります
将margin-left和right调整为10px,如图,根据计算,wrap-inner变窄
综上,当元素宽或高度等于其containing-box的宽度或高度时,且containing-box的宽度固定我们便可以利用margin对其进行自身宽度大小的调整。也就是说宽高度和containing-box有关系时,我们利用margin可进行内里元素大小的调整。
不同元素margin的计算
行内级元素
Inline,非置换元素:如果margin值为auto,则margin-left和margin-right的计算值也就为0
Inline,置换元素:同上
Inline-block,置换元素在文档流中:同上
Inline-block,非置换元素在文档流中:同上
块级元素
块级非置换元素,在文档流中
'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
下面的情况下,如果margin值为auto
如果width是auto值,那么其他值是auto的值就为0
如果margin-left和margin-right的值为auto,使用的值相等,那么就相对于包含块水平居中。
块级置换元素,在文档流中
同块级非置换元素一样。
小结
行内级置换元素和非置换元素,在margin值为auto时,margin-left和margin-auto的计算值都为0。
块级置换元素和非置换元素:
'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
如果width是auto值,那么其他值是auto的值就为0
如果margin-left和margin-right的值为auto,使用的值相等,那么就相对于包含块水平居中。
利用Margin进行布局
通常在布局中我们会遇到那些问题呢?下面是我自己实践中遇到的一些问题
问题1
当我们拿到一份设计稿,然后这份设计稿有像下面这样的布局,整体居中,里面元素排一排,当然布局的方式会有很多种,那么如果我们采用浮动布局或者display:inline-block进行布局会出现什么问题呢,如图我们可以看出,若采用上述两种方式进行布局,那么每个块的宽度加上间隙,就会超出包含块的宽度,当然我们也可以将包含块的宽度进行增大以留下足够的位置供元素摆放,但是这种方法明显是不可取的,那么如何解决这个位置不够的问题呢,可以看下面的栗子1 。
栗子
html
<p class="container"> <p class="inner-wrap"> <p class="inner"></p> <p class="inner"></p> <p class="inner"></p> </p> </p>
css
body { margin: 0; } .container { margin: 0 auto; width: 980px; } .inner-wrap { margin-left: -10px; } .inner { float: left; margin-left: 10px; width: 320px; height: 200px; background: #2df; }
此布局便利用了原理2,利用负margin增加了inner-wrap的宽度,但不改变整体的宽的情况下,实现效果。如下
问题2
上面的例子仅仅只是实现了三列固定宽度的布局,这样的布局当屏幕宽度发生变化的时候便会出现问题。因此我们便会有如下需求。
左右列固定,中间列自适应
栗子
html
<p class="main"> <p class="main-content"></p> </p> <p class="left"></p> <p class="right"></p>
css
.main { float: left; width: 100%; } .main-content { height: 200px; background: #2da; margin: 0 200px; } .left,.rightright { float: left; width: 200px; height: 200px; background: #ccc; } .left { margin-left: -100%; } .rightright { margin-left: -200px; }
效果如下,当你缩小屏幕时,中间部分会随着屏幕的缩小而缩小,另外两部分宽度不变,同样也满足了主要内容优先加载的需求,可谓一举两得
分析:
可以看出上面的布局利用了原理2,但是这里仍然会有几个为什么要问。
首先,为什么main里面一定要嵌套main-content,为什么不能直接使用单个main(假设1)?
其次,为什么main上一定要设置float:left,可以设置其他值吗,如position:absolute(假设2)?
分析上面的布局之前,我们也要了解到上面的布局满足了我们的什么需求,这里有两点1.主要内容优先加载。2.主要内容自适应。这里我们可以分析一下,我们是怎样达到上述两个目的的。首先,要达到目的1,我们就的把p.main放在前面来写,因为浏览器是从下到下渲染页面的,放在前面的也就会先渲染。且由于p.main为文档流中的块级元素,因此会独占一行,因此我们需要使其脱离文档流,这样才能使下面的元素能有机会上的来(这里之所以不考虑display:inline-block是因为p.main的长度会独占一行,就算设置display:inline-block也没有任何作用,下面的元素仍然上不来)。而要达到目的2,需要用到原理2。同时在上面提出的两个问题中,有两个假设。
假设1,如果使用单个main可不可以满足上述两个需求?我们可以试试。
html
<p class="main"></p> <p class="left"></p> <p class="right"></p>
css
body { margin:0; } /*这里注意需要改掉main的流方式,下面的元素才上的来*/ .main { float:left margin: 0 210px; height: 200px; background:#2da; } .left,.rightright { float: left; width: 200px; height: 200px; background: #ccc; } .left { margin-left: -100%; } .rightright { margin-left: -200px; }
从中线分开的黄色两部分为各自为main的左右外边距
从结果中,我们可以看出使用单个main是不行的,因为在不设宽度且元素不在文档流中时,元素的宽度为0,不能满足我们的需求,正因为我们同时要满足1.main元素不在文档流中2.元素不设宽度且在文档流中。这两个条件当然是不能同时在一个main元素下能达到的,因此我们需要再嵌套一个main-content让它来满足条件2。这也就解释了为什么一定要嵌套一个main-content。
解决了问题1,现在我们来说问题2。
假设2,main上的float值可以换为position:absolute吗?
同样的,我们试试
html
<p class="main"> <p class="main-content"></p> </p> <p class="left"></p> <p class="right"></p>
css
body { margin: 0; } .main { position:absolute; width:100%; } .main-content { margin: 0 210px; height: 200px; background: #2da; } .left,.rightright { width: 200px; height: 200px; background:#ccc; } .left { float: left; } .rightright { float: rightright; }
答案是可以的,只是我们需要改掉一些值,而当main为float之所以要给p.left与p.right要设置margin-left值是因为浮动元素浮动时,当它的外边缘碰到包含框或者另一个浮动框的边框为止。而为浮动元素的p.main占据了整整一行,因此下面的浮动元素p.left与p.right便被挤了下来,而设置它们的margin-left值便可以把它们移上去,这里便运用了原理1。而当我们把p.main的float值改为position:absolute时,便不会存在被挤下来的问题,可直接设置p.left与p.right的float的值。效果如下。
如若只需要达到宽度自适应的要求,那么,这时候便可以将p.main放在最后面且不用嵌套p.main-content,具体如何实现,大家可以自己试试。
问题3
如下所示设计稿,在我们进行布局的过程中,可能会出现border重合的情况,因为一方面我们需要对整个整体加上border,而另一方面我们又需要利用border隔开那三个小块。那么如果我们对每个小块都加上右边框,可以想象,最右边就会出现边框的堆叠而这不是我们希望看到的,所以,要如何解决这个问题,可以看如下例子给出的答案。
栗子
html
<ul> <li>1</li> <li>2</li> <li>3</li> </ul>
css
ul { position:absolute; margin: 0; padding:0; list-style:none; border: 4px solid #c5c5c5; } li { float:left; width: 200px; height: 50px; line-height: 50px; text-align: center; border-right: 4px solid #c5c5c5; }
没在li上加margin-right:-4px;前,效果如图,发生了堆叠。
加了margin-right: -4px后,达到预期效果。因为加上了ul的右边框发生了移动与第三个li的右边框进行了重叠。因此效果上来看便符合了预期,如图
このレイアウトは原則 1 を利用し、隣接する要素の位置を要素ごとに制御することで目的の効果を実現します。
原則 1 は、要素の中央揃えのレイアウトを実現するためにも使用できます。まず、要素の上端と左端のマージンを 50% 移動し、次に要素の上端と左端のマージンの値を要素自体の幅の半分に設定します。要素自体を移動します。これにより、要素を中央に配置するという目的が達成されます。
概要
1. 要素の幅が包含ボックスの幅と等しい場合。
マージン値を調整することで要素の幅を調整できます。
2. 要素の幅が包含ボックスと関係がない場合。
マージン値を調整することで要素の位置を移動できます。
以上がページレイアウトで CSS の margin 属性を使用するためのガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。