いわゆるドキュメントフローとは、要素のレイアウトプロセス中に要素が左から右、上から下に自動的に配置されるフローを指します。そして最後にフォームを上から下の行に分割し、各行に要素を左から右の順に配置します。ドキュメント フローから外れるということは、要素がこの配置を乱すか、レイアウトから取り除かれることを意味します。
ドキュメントフローから抜け出すには現在、フローティングとポジショニングの 2 つの方法が知られています。
まずポジショニングについて見てみましょう。各フィールドの配置の説明を見ると、理解が容易になります。
absolute |
静的配置以外に、最初の親要素を基準にして配置される絶対配置要素を生成します。 要素の位置は、「left」、「top」、「right」、「bottom」属性によって指定されます。 |
fixed |
ブラウザウィンドウを基準にして相対的に配置された絶対配置要素を生成します。 要素の位置は、「left」、「top」、「right」、「bottom」属性によって指定されます。 |
relative |
通常の位置を基準にして相対的に配置された要素を生成します。 つまり、「left:20」は要素の左の位置に 20 ピクセルを追加します。 |
静的 | デフォルト値。位置決めを行わない場合、要素は通常のフローで表示されます (上、下、左、右、または z-index 宣言は無視されます)。 |
inherit | Position 属性の値を親要素から継承することを指定します。 |
位置の値が絶対または固定である要素はドキュメントフローから分離されますが、静的および相対はドキュメントフローから分離されません
位置位置決めテストの例(位置決めの効果に影響を与えないように、テキストは最後に配置されます) )
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <!--<script type="text/javascript" src='jquery-1.9.1.js'></script>--> <style> *{ margin: 0; padding: 0; text-align: right; color: #FFF; } #container{ position: absolute; left: 20px; margin-top: 10px; width: 600px; height: 600px; background-color: green; } #bigest{ position: static; left: 20px; margin-top: 20px; width: 500px; height: 500px; background-color: #ab2; } #biger{ position: static; left: 20px; margin-top: 30px; width: 400px; height: 400px; background-color: #00f; } #big{ position: relative; left: 20px; margin-top: 40px; width: 300px; height: 300px; background-color: #000; } #normal{ position: static; margin-left: 20px; margin-top: 50px; width: 200px; height: 200px; background-color: #aaa; } #middle{ position: absolute; left: 20px; margin-top: 60px; width: 100px; height: 100px; background-color: #aaa; } #small{ position: fixed; left: 20px; margin-top: 70px; height: 50px; width: 50px; background-color: #f00; } </style> </head> <body> <div id="container"> <div id="bigest"> <div id="biger"> <div id="big"> <div id="normal"> <div id="middle"> <div id="small">small </div>middle </div>normal </div>big </div>biger </div>bigest </div>container </div></body></html>
全体的な効果のスクリーンショット
結論:
1.静的配置はドキュメントフローから離脱せず、左/上/右/下の設定は効果がなく、マージン/に敏感です。パディング。
【証拠: #bigestpositioning left は効果がありません】
2. 親ノードと子ノードがドキュメントから分離されていない 2 つの配置 (静的、相対) のマージンがマージされ、表示効果は次のようになります。最大のマージンに基づいて優先されます。
【証拠: #bigest、#biger、#big、#normal はすべてドキュメントから分離されていない要素であり、親子ノード関係があります。その marginTop 値はそれぞれ 20px/30px/40px/50px です。 。 #bigest と #biger のマージンがマージされ、マージされた上部マージンは 30 ピクセルになります。その後、#biger は以前にマージされた結果を取得して #big のマージンとマージされ、最後にマージされた上部マージンは 40 ピクセルになります。 result 結果は #normal margin とマージされ、マージされた結果は 50px になります。したがって、最終的に結合されたマージンは 50 ピクセルになります。表示効果は以下の通りです:
もちろんパディングの影響なしです。パディングがある場合、子要素のマージンは親要素のパディングに基づいてオフセットされます。たとえば、 #big{padding-top: 10px;} 属性を設定した後、図
に示すように、#nomal の margin-top は #big の padding-top からオフセットし始めます。ここで外側のマージンについて説明します。ブロックレベル要素の垂直方向に隣接するマージンはマージされますが、インライン要素は実際には上マージンまたは下マージンを占有しません。インライン要素の左右のマージンはマージされません。同様に、フローティング要素のマージンはマージされません。負のマージン値を指定することもできますが、使用する場合は注意してください。例:
<style> #bottom10{ margin-bottom: 10px; height: 100px; width: 100px; background: #ff0; } #top50{ margin-top: 50px; height: 100px; width: 100px; background: #f00; }</style><div id='bottom10' >margin-bottom 10px</div><div id="top50">margin-top 10px</div>
効果、黄色のブロックと赤色のブロックの間の最終的な空白のギャップは 50px です。
#top50 の css を
#top50{ top: 50px; margin-top: 50px;<br /> <strong>padding-bottom: 50px;</strong> height: 100px; width: 100px; background: #f00; display: inline; }
効果は
表示されるインライン要素は、上/右/下/左、幅/高さ、マージン、および境界線の位置には影響されません。 。
もう 1 つのポイント: ドキュメント フローから切り離される要素はすべてブロック レベルの要素です。
#top50{ top: 50px; margin-top: 50px; padding-bottom: 50px; height: 100px; width: 100px; background: #f00; display: inline; }
後の 2 つのケース #top50 は、インライン要素ではなくブロックレベル要素として処理されます。
ドキュメント フローの外で位置指定を使用する場合は、「left」、「top」、「right」、「bottom」属性を使用して要素の位置を指定するのが最善です。そうしないと、望ましくない状態が発生する可能性があります。まだ前の例です
#top50{<br /> position:absolute; top: 50px; margin-top: 50px; padding-bottom: 50px; height: 100px; width: 100px; background: #f00; display: inline; }
top を設定した場合と設定しなかった場合の効果は次のとおりです
top を設定すると、top は body 要素に対して相対的に配置されますが、これは期待できます。後でtopを設定しない場合、ブラウザはドキュメントフローから外れたブロック(余白を含む)をフローレイアウトに従って配置します。ドキュメントフローから外れないように見えますが、2つのブロックの間にスペースがあります。高さ60px このような状況は私たちが予想していたものではありませんでした。 】
3.absolute は、静的配置以外に最初の親要素を基準にして配置される絶対配置の要素を生成します。静的配置では、左/上/右/下を使用して位置を設定できないため、静的に配置された要素は、(マージンなどの他の要素を考慮せずに) 親ノードのエッジと一致する必要があります。たとえば、#middle の親ノード #normal は静的に配置される要素であり、さらに上に #big が見つかった場合、それは非静的に配置される要素であるため、#middle は #big に対して相対的に配置されます。
つまり、上の画像の #middle と #big の左側の間の距離は 10px です。 #middle の上端を見ると、#normal の上端からの距離は 50px であり、これは #middle:margin-top:50px の影響です。しかし、このマージンオフセットは通常または大に基づいているのでしょうか?
実験 1: 前の実験を使用します。たとえば、#big{padding-top: 1px;} 属性を設定した後、#nomal の margin-top が #big の padding-top をオフセットし始めます。
上記の実験結果は、 #middle の margin-top が #normal に基づいていることを示しています。
実験 2: #middle に別の配置スタイル top:20px を追加すると、結果は次のようになります
ほら、この時点では #middle の top と margin-top は # ではなく #big に基づいています。普通。
したがって、絶対配置の結果は 2 つのケースで考慮されます:
1 つ目は、要素の特定の側に配置属性 (left/top/right/bottom) が設定されていない場合です (デフォルト値はauto)、この側 絶対ブロック (マージンを含む) は流体レイアウトに従って配置されます (実験 1 の結果に示されているように) もちろん、この流体レイアウトはパディングのパディングの影響を受けます。
第二种,元素的某条边设置了定位属性(left/top/right/bottom)的时候(默认值是auto),这一边就会被作为脱离文档流的边来处理,会相对于 static 定位以外的第一个父元素(的边框)进行定位,如果这时候设置了外边距,那么这一边相对于基准元素的偏移=定位值(left/top/right/bottom)+ 外边距。效果如实验2所示。作为脱离文档流来处理的边是基于那个基准元素的边框来定位的,当然不受内边距padding的影响。
4.fix定位可以看成一种特殊的绝对定位,absolute的基准元素是 static 定位以外的第一个父元素,而fix的基准元素是浏览器窗口。absolute定位结果分两种情况对于fix来说同样适用。看下面的图:第一幅没有设置top,后一幅设置了top:10px。
5.因为absolute相对于 static 定位以外的第一个父元素进行定位,所以一般要对某个元素absolute定位,则设置其父元素为relative即可。避免无法预知的基准元素。
6.强烈建议脱离文档流的定位absolute的元素内部不要在其内部包含有脱离文档流的元素存在。举一个例子,某个iframe中内容会不断增高或缩小,但是iframe不能有自己的滚动条,需要同步增高或减少父窗口和iframe的高度使得滚动父窗口滚动条滚动显示iframe的内容。这个时候,需要计算iframe中body内容真实的高度(这个高度不能使用$(document).height()来获得,看这篇文章最后总结中document总结的IE部分,获取的不一定是body内容的真实高度),对于脱离文档流的元素需要自己计算高度,而脱离文档流的元素a中还包含脱离a的元素b,咋搞哦。所以才有这里的建议。
7. 对使用absolute脱离文档流的的元素如果做到让absolute元素后面的元素自适应布局?一般使用margin定位后面的元素来处理。举个例子
左边的灰块是绝对定位absolute元素,右边黄色部分文字自适应到绿色边框的右边自动换行。这个是怎么实现的看源码
<style> #panel{ width: 500px; height: 100px; border: green solid 1px; } #left{ position:absolute; height: 100px; width: 100px; background: #000; opacity: 0.5; color: #fff; } #right{<strong> margin-left: 110px;</strong> background: #ff0; } </style> <div id="panel"> <div id="left">这个东东是position:absolute</div> <div id='right' >这个东东是position:absolute后面的元素这个东东是position:absolute后面的元素这个东东是position:absolute后面的元素这个东东是position:absolute后面的元素</div> </div>
#left绝对定位宽度是100,那么只要使#right margin-left: 110px;这样空出#left的显示空间即可。#right的自适应照常使用。
8. relative没有脱离文档流。如果原来不明白为什么,就有必要看这个例子。relative:相对定位,参造物是其本身,并不脱离文档流,不管你怎么移动,它原有的位置还是会留着。不仅如此,脱离文档流的元素相当于自身生成了一个新的文档流,父容器对其没有布局上的影响(最多是定位的影响)。但是relative却不是,父容器对其布局影响照旧。举例(还是上面的例子,我们把#right替换为如下):
#right{ margin-left: 110px; background: #ff0; position: relative; }
效果依旧,自适应依然以绿色边框的父容器为边界。我们如果将#right换成span标签,#right依然以span内联标签的方式显示。
如果我将#right换成
#right{ margin-left: 110px; background: #ff0; position: absolute; }
上图效果图右边还有部分没有截完。可以看出父容器对#right已经无法限制其边界了。#right真正的是自成一家了。
不过有一点:relative在堆叠优先级上和fixed、absolute一样,要比兄弟节点中staic节点要高。举例
<style> #panel{ width: 500px; height: 100px; border: green solid 1px; } #left{<strong> position:absolute; left: 50px;</strong> height: 100px; width: 100px; background: #000; opacity: 0.5; color: #fff; } #right{ margin-left: 110px; background: #ff0;<strong> position: static;</strong> } </style> <div id="panel"> <div id="left">这个东东是position:absolute</div> <div id='right' >这个东东是position:absolute后面的元素这个东东是position:absolute后面的元素这个东东是position:absolute后面的元素这个东东是position:absolute后面的元素</div> </div>
虽然#right写的顺序在#left后面,但是#left依然堆叠在#right上面。可以动手试一下,relative、absolute、fixed等级是一样的,static比另外三个低一级。
float 属性定义元素在哪个方向浮动。以往这个属性总应用于图像,使文本围绕在图像周围,不过在 CSS 中,任何元素都可以浮动。浮动元素会生成一个块级框,而不论它本身是何种元素。如果浮动非替换元素,则要指定一个明确的宽度;否则,它们会尽可能地窄。
注释:假如在一行之上只有极少的空间可供浮动元素,那么这个元素会跳至下一行,这个过程会持续到某一行拥有足够的空间为止。
为什么说浮动元素是脱离文档流的。
脱离文档流的元素有个标志:没有实际高度。比如例子
<style> #panel{ width: 500px; border: green solid 1px; } #left{<strong> float:left;</strong> left: 0px; height: 100px; width: 100px; background: #000; opacity: 0.5; color: #fff; } </style> <div id="panel"> <div id="left">这个东东是position:absolute</div> </div>
#left没有把#panel给撑开,#panel的高度为0。
对于浮动属性来说,位置属性(left/top/right/bottom)是没有用的。
但是在内部显示的时候,#left的兄弟节点会在#left占有的地盘之外显示。比如,我们新增#right,html代码变为
<style> #panel{ width: 500px; border: green solid 1px; } #left{ float:left; left: 0px; height: 100px; width: 100px; background: #000; opacity: 0.5; color: #fff; } #right{ background: #ff0; position: relative; } </style> <div id="panel"> <div id="left">这个东东是position:absolute</div> <span id='right' >这个东东是position:absolute后面的元素这个东东是position:absolute后面的元素这个东东是position:absolute后面的元素这个东东是position:absolute后面的元素的元素这个东东是position:absolute后面的元素的元素这个东东是position:absolute后面的元素的元素这个东东是position:absolute后面的元素的元素这个东东是position:absolute后面的元素</span> </div>
文字环绕#left。#panel被#right给撑开了。
浮动有点像玩俄罗斯方块。向左浮动,方块从右往左滑过来,如果某一行空间不够(基于父容器的宽度),那么这个块会沿着最右边的块的下边沿水平划过来,最后看卡到哪里就停止。举例
<style> #panel{ width: 200px; height: 200px; border: green solid 1px; } #left1{ float:left; height: 100px; width: 100px; background: #000; color: #ffa; } #left2{ float:left; height: 50px; width: 50px; background: #bba; } #left3{ float:left; height: 30px; width: 30px; background: #a3a; } #left4{ float:left; height: 60px; width: 60px; background: #a92; } #right1{ float:right; height: 30px; width: 30px; background: #ff0; } #right2{ float:right; height: 60px; width: 70px; background: #8f0; } </style> <div id="panel"> <div id="left1">left1</div> <div id="left2">left2</div> <div id="left3">left3</div> <div id="left4">left4</div> <div id="right1">right1</div> <div id="right2">right2</div> </div>
#left4在第一行left3后面宽度不够,换行成第二行。在left2后面宽度不够,只能在left1后面。#right1自然是从第二行开始查找位置,很幸运第二行现在唯一的元素#left4右面空间足够,放置即可。#right2在第二行中没有足够的位置,换行成第三行,找到空余位置插入。
可以看到互动元素之间连接的部分是没有空隙的。这是一个很好的特性,可以用来做排列,精确到1px。
浮动元素不占据高度,如果某个元素内部全是浮动元素,最后该元素也没有高度,如果想要父元素内的浮动元素占有原来的高度,在父元素内部最后一个元素加上css属性为clear:both的块状元素即可。如
#panel{ width: 200px; border: green solid 1px; }
<br /> <div id="panel"> <div id="left1">left1</div> <div id="left2">left2</div> <div id="left3">left3</div> <div id="left4">left4</div> <div id="right1">right1</div> <div id="right2">right2</div> <strong><div style="clear:both"></div></strong> </div>
有时也会在父元素后面加,不过该父元素不会获取到高度,但是父元素的后面的兄弟节点会认为其占用了位置。实例
<!DOCTYPE html><html lang="ch-cn"> <head> <meta charset="utf-8"> <title>chua</title> <style> #panel{ width: 200px; border: green solid 1px; } #left1{ float:left; height: 100px; width: 100px; background: #000; color: #ffa; } #left2{ float:left; height: 50px; width: 50px; background: #bba; } #left3{ float:left; height: 30px; width: 30px; background: #a3a; } #left4{ float:left; height: 60px; width: 60px; background: #a92; } #right1{ float:right; height: 30px; width: 30px; background: #ff0; } #right2{ float:right; height: 60px; width: 70px; background: #8f0; } #panel2{ width: 200px; height: 100px; border: green solid 1px; } </style> </head> <body> <div id="panel"> <div id="left1">left1</div> <div id="left2">left2</div> <div id="left3">left3</div> <div id="left4">left4</div> <div id="right1">right1</div> <div id="right2">right2</div> </div> <div style="clear:both;"></div> <div id="panel2">panel2</div> </body> </html>
如果觉得本文不错,请点击右下方【推荐】!