ホームページ > 記事 > ウェブフロントエンド > CSS マジック ホール: Float の埋もれた野心について語る_html/css_WEB-ITnose
測位システムで最初に理解するのが難しいのは Normal flow、2 番目に理解するのが難しいのは Float です。 Float が理解するのが難しい理由は 2 つあります。 . 最初に使用します 間違っています; ノーマルフローに近すぎます。この記事では、Float の特性と動作特性を明らかにすることを目的としています。間違いがある場合は、修正してください。
通常、float を使用するのはどのような場合か思い出してください。それは複数列レイアウトですか、それとも複数列レイアウトですか:)?実際、これが望んでいることであり、これがやりたいことです - テキストの折り返しです。CSS2 には、上記の効果を実現するフローティング以外の属性はありません。では、その実装原理を理解するにはどうすればよいでしょうか?段階的に分析して詳しく説明しましょう。
'float'Value: left | right none |noneApplies to: allInherited: no float:left が設定されている場合、要素の対応するマージン左 エッジは、その要素が属するブロックの左境界にできるだけ近くなります。 float:left が設定されている同じ行の左側に要素がある場合、その要素はできるだけ近くになります。兄弟要素のマージン右端。
<div style="background:#06F;width:200px;height:100px;position:relative;left:20px;"> <div style="background:#1F0;width:50px;height:50px;float:right;"></div> <div style="background:#F60;width:50px;height:50px;float:right;"></div></div>
(float:left は効果を強調表示できないため、float:right が使用されます)例: 青色の領域が包含ブロック範囲で、緑色と赤色のブロックは右側のフローティングを使用します) フローティングが設定されている場合、display:inline の実際の値は display:block に書き換えられるため、ボックスの内容は発生しません。 display:inline;height:100px;line-height:0;float:left の高さを 100px にする びっくりしました。たとえ残りのスペースが display:inline;float:left ボックス全体を格納するのに十分でない場合でも、ボックス全体は植字のために次の行に移動されます (通常のフローの場合は、移動されます)。ホワイトスペース、ワードラップ、ワードブレークに従って入力することにより、ボックス全体ではなく、ボックス内のコンテンツの一部をラップすることが決まります。) 簡単に言うと、ボックスに気質を持たせるのは float:left ではありません。米バケツ5杯分は曲がらないことですが、display:blockの貢献と、フローティングボックスが水平方向の組版になるため、display:inline-blockを使用して、フローティングの水平方向の組版と行の折り返し動作を理解できます。ポジショニング。
<div style="background:#06F;width:200px;height:100px;"> <span style="background:yellow;width:100px;height:50px;float:left;">I'm span</span> <span style="background:#F01;width:110px;height:50px;float:left;">I'm span too</span></div>
float が設定されている場合、display の実際の値は block ですが、width:auto に関する限り、表示は inline-block を使用することに似ていると思います。幅は子要素によって決まります。こちらはラッピングです! (方向が異なるだけで、同じことが float:right にも当てはまります。) 注: 浮動要素自体のみを考慮するという前提の下では、float:left の効果は、display:inline-block の効果と同じです。親コンテナの方向:ltr の違いは、親コンテナの高さの計算にフローティング要素が含まれないことです
<div style="border:solid 1px #06F;"> <span style="background:#F01;float:left;">float:left</span></div><br clear="both"/><br/><div style="border:solid 1px #06F;"> <span style="background:#F01;display:inline-block;">float:none</span></div>
Float を断片的に理解することは難しくありません。難しいのは、Float を通常のフローと組み合わせて理解することです。一緒に話し合ってみましょう!警告、前方に高エネルギー、前方に高エネルギー! !
Absolute 位置決めと Float はどちらも位置決めの基礎として Normal フローを使用します。つまり、最初に Normal フローで配置された仮想ボックスがあると仮定します。これに基づいて Float 属性を追加し、他のボックスのレイアウトに影響を与えます。フローティング位置はボックス自体の水平位置にのみ影響するため、インライン レベルのボックスの場合は垂直位置は変更されませんが、ブロック レベルのボックスではマージンの縮小が無効になり、垂直方向の移動が発生する可能性があります。
<div style="background:#0f6;width:200px;height:50px;margin-bottom:50px;"></div><div style="background:#f06;width:200px;height:50px;margin:50px 0;"></div><div style="background:#06F;width:200px;height:50px;margin-top:50px;float:left;">float:left</div>
フローティング配置の仮想ボックスは実際にはスペースをとらないことに注意してください。したがって、その後のフローティングクロージャとフローティングクリアリングが存在します。
テキストの折り返しは明らかにテキストを両側に絞り込み、「兄」のための場所を残します。弟はやりすぎないようにしてください。彼らはいつも兄をサポートしなければなりません。では、長兄はどのようにして弟たちを罠にかけたのでしょうか?次に、外力 - ラインボックスを使用する必要があります。テキストはグリフの形式でレンダリングされ、同じ行のインライン レベルのボックスは同じ行ボックスに配置されます。ラインボックスは、収容ブロックと浮遊ボックスの間にかろうじて生き残っていると言える。
<div style="overflow:hidden;line-height:1.5;background:#06F;"><img src="john.png" style="float:left;margin:10px"/>These days it takes a diverse and complex collection of components to power a web browser. <img src="john.png" style="float:right;margin:10px"/>It’s fair to think of all those parts coming together as a single piece of machinery, and we often talk about our web platform as an “engine”.</div>
ライン ボックスの幅がグリフとインライン レベル ボックスを収容するのに十分でない場合、N 個の新しいライン ボックスが下に生成され、インライン レベルが分割されます。必要に応じてボックスを配置し、グリフとインライン レベルのボックスを各行の行ボックスに分配します。
ラインボックスと比較すると、ブロックレベルのボックスは譲れないように見えます。 width:auto が使用される場合、その幅は常に、包含ブロックの幅を占める姿勢を維持します。ただし、同じスタッキング コンテキスト内にあるフローティング位置のボックスは、通常のフロー内のボックスと同じ Z インデックスを持ちますが (どちらも自動です)、フローティング位置のボックスには特別な優先順位があり、常にフローティング フロー内に配置されます。ボックスの上の通常の流れ。 (階層表示については「CSSの魔術館:z-indexって本当に理解していますか?」を参照してください。)
<div style="float:left;border:solid 1px red;width:100px;height:50px;">float:left</div><div style="background:#06f;width:200px;height:100px;"></div>
同样是盒子,为啥你就可以在我上面呢?你有Float罩着,我也找弄个新的BFC来跟你抗衡。我们知道通过float:left|right或position:absolute|fixed或display:inline-block|table-cell|table|table-caption或overflow:auto|scroll|hidden均可让盒子产生新的BFC。而产生BFC的盒子间天生排斥彼此。(但可通过后天的努力position:relative让他们又互有交集^_^)那现在的问题是采用Normal flow定位模式的会产生新的BFC的盒子到底是紧跟在Float定位盒子的后面,还是另起一行呢?答案是两者都有可能,具体看剩余的宽度是否足以容纳该盒子。其实就是如同设置父容器产生BFC,而该盒子采用Float定位模式。不信,你看
<div style="float:left;border:solid 1px red;width:100px;height:50px;">float:left</div><div style="background:#06f;width:200px;height:100px;overflow:hidden;"></div>
我想各位都看过各种版本的clearfix实现,而最简单粗暴的方式就是添加一个9f1a3abdb6765f20be73bc08da0941f016b28748ea4df4d9c2150843fecfba68来清除浮动。我还听过另一个名称——”浮动闭合”,那到底两者有什么区别呢?在作区分之前我们先要明确问题的本身。对于height:auto的容器而言,我们希望它能恰好包裹着所有子元素,但不幸的是采用浮动定位模式的子元素将不纳入父容器的高度计算当中,那就会出现子元素戳穿父容器的风险。从之前的内容我们了解到文字和inline-level boxes会环绕Float定位的盒子,而block-level box则被它踩在脚下。但现在希望后续盒子不再与Float定位的盒子有任何瓜葛。面对这两种需求,我们分别得出”浮动闭合”和”清除浮动”两套方案。
就是让height:auto的父容器包裹所有子元素,包括Float定位的子元素。方式很简单,就是好让父容器产生BFC。
就是为浮动影响的范围划边界。方式也很简单,就是以一个clear:left|right|both的盒子作为边界即可,其实就是引入空隙(clearance)。首先clear属性仅对block-level box有效,clear:left表示盒子的margin-left-edge不与浮动盒子接触,而clear:right表示盒子的margin-right-edage不与浮动盒子接触,clear:both自然是左右两条margin-edge均不与浮动盒子接触啦。有点虚,直接看疗效吧!
<div style="float:left;width:200px;height:50px;background:#06F;">float:left</div><div style="clear:left;width:200px;height:50px;background:#F60;">clear:left</div><div style="float:right;width:200px;height:50px;background:#06F;">float:right</div><div style="clear:right;width:200px;height:50px;background:#F60;">clear:right</div>
简单地说就是float:left用clear:left来清除,float:right用clear:right来清除。而我们会发现一个怪异的现象,那就是设置clear:left|right|both的盒子的border top edge紧接着Float定位盒子的margin bottom edge,其实这是clearance来作祟。当设置clear:left|right|both的盒子A的border top edge与Float定位盒子B的margin box重叠时,那么就会在A的margin box和border top edge之间引入clearance,恰好让A的的border top edge恰好不与B的margin bottom edge重叠。
<div style="margin-bottom:50px;background:#06F;height:100px;width:200px;float:left;"></div><div style="margin-top:50px;border: solid 10px red;height:50px;width:200px;clear:left;"></div>
不管是浮动闭合也好,清除浮动也罢,我们的目的往往是两者结合——Float定位的范围与Normal flow定位的范围分明,且采用Normal flow的父容器包裹所有子元素。那么可归结为Normal flow的父容器包裹所有子元素。因此得到如下的HTML Markup
<div class="container clearfix"> <!-- Float定位的范围 --></div><!-- Normal flow定位的范围 -->
而具体的方案如下:方案1
.clearfix::after{ content: "."; display: block; clear: both; line-height: 0; visibility: hidden;}.clearfix{ *zoom: 1; /*for IE5.5/6/7*/}
伪元素after表示创建一个display:block,innerText是content属性值的元素作为该元素的最后一个子元素。注意content属性值不能为空白,否则无法清除浮动。方案2
.clearfix::after{ content: "\u200B"; /*通过零宽空白字符,省略visibility属性*/ display: block; clear: both; line-height: 0;}.clearfix{ *zoom: 1; /*for IE5.5/6/7*/}
注意:若页面不是采用UTF-8编码方式,那么\u200B表示的将不是零宽空白字符,从而导致方案2出问题。方案3由Nicolas Gallagher大湿提出的
.clearfix::before, .clearfix::after{ content: ""; display:table;}.clearfix::after{ clear: both;}.clearfix{ *zoom: 1; /*for IE5.5/6/7*/}
这里有2个奇妙的地方:
我们可以通过position属性来设置Normal flow或Absoluting positioning,但却要通过float属性来设置Float,这让我一度怀疑Float到底是不是定位模式的一员呢?我是这样理解的,Normal flow(包括Relative positioning)与Absoluting positioning是非我即你的关系,而Float和Relative positioning则是可叠加影响定位效果的关系,显然必须另设一个属性来设置更恰当。
有没有发现通过float:left|right我们仅能得到要么图片靠左要么图片靠右的文字环绕效果,那如果我们希望得到如下的四周环绕的效果呢?虽然已有案例是通过absolute positioning模拟出类似的效果,但布局排版固定导致无法适应大部分场景。如果有个float:both属性值那该多好啊!另外大家是否觉得以下的环绕效果更有艺术范呢?听说通过CSS3的shapes特性可以实现四周环绕和上面非四四方方的环绕效果,日后好好研究研究!2016/04/19补充-参考《CSS网站布局实录-基于Web标准的网站设计指南(第2版)》的5.2.2 不规则文字环绕
<style type="text/css">.article{ font-size: 14px; line-height: 1.5; text-align: justify;}.figure{ position: absolute; z-index: -1;}.figure-shape{ margin: 0; padding: 0;}.figure-shape li{ list-style-type:none; height: 1.5em; float: left; clear: left;}.figure-shape li:nth-child(1){ width: 150px;}.figure-shape li:nth-child(2){ width: 180px;}.figure-shape li:nth-child(3){ width: 180px;}.figure-shape li:nth-child(4){ width: 160px;}.figure-shape li:nth-child(5){ width: 148px;}.figure-shape li:nth-child(6){ width: 150px;}.figure-shape li:nth-child(7){ width: 148px;}.figure-shape li:nth-child(8){ width: 144px;}.figure-shape li:nth-child(9){ width: 136px;}</style><div class="article"><img src="./beyonce.jpg" class="figure"/><ul class="figure-shape"><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul>初中时候语文老师说我会是个写作天才,因为我写的东西足够真实,取材身边,造句简单,用语文书垫桌脚的同时翻烂了韩寒的1988,那时督促我已经成为她的习惯。时至今日再次遇见语文老师时候我惭愧的告诉她我已经不写文了,也没有像她说的那样成为一个天才,我只能微微一笑告诉她我至少还没停下笔。</div>
重构了几次总算写完了,想写得清楚而又不哆嗦真心不易,继续努力:)
KB011: フロート KB009: CSS ポジショニング システムの概要 CS001: フロートをクリーンアップするいくつかの方法と対応する仕様 CSS フロートの徹底した研究、詳細な説明と拡張 (1) CSS フロート In-深さの研究、詳細な説明と拡張 (2) https://www.w3.org/TR/CSS2/visuren.html#flow-controlCS001: float をクリーンアップするいくつかの方法とそれに対応する仕様 疑似要素で 'float: center' を偽装する標準について語る - CSS コアのビジュアル フォーマット モデル (ビジュアル フォーマット モデル) 第 10 回: フロートの配置を制御する - クリア機能 長年にわたって一緒にクリアしてきたフロート
フロントエンドスタックエンジニアの個人ホームページ · 私の記事 · 1 ·