Web 上で 2 列アダプティブ レイアウトを実装する方法について話したいなら、片手で数えることができます。なぜこれらの方法でアダプティブ レイアウトが実現できるのか考えたことがあるでしょうか?
この記事では、流体特性と BFC 特性に基づく 2 列アダプティブ レイアウト、または従来のレイアウトについて詳しく説明します。フレックスボックス レイアウトやグリッド レイアウトなどの一部の最新のレイアウトについては、この記事では説明しません。
タイトルとその前の 1 ~ 2 段落を読んで、流動性や BFC など、すべて私が知っている概念であることに気づいた人もいました~~ それで彼らは怒りながら立ち去りました。これは私たちがよく言う衝動的なものです。謙虚な心を持ち、注意深く読んでください。いわゆる「一緒に歩く人には私の先生がいるはずです」。そう、この文章はあなたに読んでもらうために書いたものであり、自己反省と監督でもあります。
div 要素 (以下同様) などのブロックの水平方向の要素は、デフォルト (非フローティング、絶対配置など) で、水平方向は外側のコンテナを自動的に埋めます。margin-left/margin-right、padding-left/padding-right、border-left-width/border-right-width などがある場合、実際のコンテンツ領域はそれに応じて狭くなります。
百聞は一見にしかず、例は千の写真に値します。 div 要素の流動的な特性を確認するには、次の例を参照してください。
画像の幅は常に width: 100% になり、その結果、マージン、パディング、ボーダーが表示されます。を使用すると、利用可能な幅が自動的に減少し、アダプティブ効果が形成されます。コンテナ内に配置された水流と同じように、コンテンツ領域はマージン、パディング、境界線の外観で残りのスペースを自動的に埋めます。これはブロック要素の流動的な特性です。
次に、div はコンテナの左マージンから 150 ピクセル離れており、内部の画像もコンテンツ領域に 100% 適応します。 HTML は次のとおりです:
.flow-box { width: 500px; background-color: #eee; overflow:auto; resize:horizontal;}.flow-content { margin-left: 150px;}
<div class="flow-box"><div class="flow-content"><img src="mm1.jpg" width="100%" height="190"></div></div>
画像の右下隅に 2 つのスラッシュがあります (最新のブラウザーとモバイル以外のアクセスでは) 150 ピクセルが常に空白のままであることがわかります。左側、コンテナの幅に応じて画像が変化し、適応的に変化します。
この時点で、2 列の適応効果を実現できるように、左側の 150 ピクセルの空白を有効に活用する必要があります。 ?
元の流体の特性に影響を与えないように、フロート (float:left) や絶対配置 (position:absolute) などの破壊的なアトリビュートを使用できます。
次のように HTML を直接調整できます:
<div class="flow-box"><img src="mm1.jpg" width="128" style="float:left;"><div class="flow-content"><img src="mm1.jpg" width="100%" height="190"></div></div>
<div class="flow-box"><img src="mm1.jpg" width="128" style="position:absolute;"><div class="flow-content"><img src="mm1.jpg" width="100%" height="190"></div></div>
結果は次のとおりです:
もちろん、左側に複数の float を配置したり、left float + right float にすることもできます。したがって、2 列の適応効果だけでなく、複数列の適応効果も実現できます。
ただし、ブロック要素の流動的なプロパティを使用するアダプティブ レイアウトには欠点があります。つまり、フローティング コンテンツまたは絶対配置されたコンテンツのサイズを知る必要があります。次に、流体コンテンツには、位置補正のために対応するマージン、パディング、または境界値を含めることができます。そこで問題が発生します。サイト全体で使用できる .clearfix のような共通のクラス名を単純に使用することはできません。異なる適応シーンの空白距離が異なるためです。
この時点で、ブロック要素の BFC 特性を使用して、より強力でスマートな複数列適応レイアウト (この記事の焦点) を実装できます。
BFC の正式名は「ブロック フォーマット コンテキスト」、中国語では「ブロック レベル フォーマット コンテキスト」です。バンバンのプロパティを一言で説明するのは難しいので、優先順位を混乱させないようにここでは詳しく説明しません。つまり、BFC 要素の特性の表現の原則を覚えておいてください。それは、内部の要素が世界をどんなにひっくり返しても、曇りでも雨でも、外部の要素には影響を与えないということです。したがって、証拠金の侵入を回避し、浮きを解消する方法が簡単に理解できます。
BFC はいつトリガーされますか?一般的なものは次のとおりです:
float の値は none ではありません。
オーバーフローの値は、auto、scroll、または hidden です。
display の値は、table-cell、table-caption、inline-block のいずれかです。
位置の値は相対的でも静的でもありません。
BFC には多くの機能がありますが、ここでは 1 つの機能、つまり float 要素に隣接する場合のパフォーマンスのみに注目します。
上で紹介した流体特性の div であれば、フローティング要素と兄弟である場合、オーバーレイ関係になります (テキストの折り返し画像効果が想像できます)。ただし、要素がBFCになった後は、「内側は衝撃的で欺瞞(ハーモニー)がゴーストに爆発し、外側はまだ静かに大物を釣っている」という原則に沿って、当然フローティングとは重なりません(考えてください)クリアがある場合:両方とも外側の浮遊物と戦わない)ので、ブロックが隣接しているので、下のボタンをクリックして感じてください。
通常の流体要素の BFC 後、浮動要素との交差を避けるために、浮動エッジに沿って独自の閉じたコンテキストを形成していることがわかります。以下のスクリーンショット:
同时, 元素原本的流体特性依然保留了 。哈,这个很重要,也就是,虽然不与浮动交集,自动退避浮动元素宽度的距离,但,本身作为普通元素的流动性依然存在,反映在布局上就是自动填满除去浮动内容以外的剩余空间。哟,这不就是自适应布局嘛!!
然而,模块过于亲密接触,可能不是我们想要的。一般而言,我们需要一点间距。
说到间距,我们的第一反应就是margin. 于是,我们给BFC元素增加一个margin-left:20px, CSS代码如下:
.float-left { float: left;}.follow-content { margin-left: 20px; background-color: #cad5eb; overflow: hidden;}
结果……纳尼~ 怎么还是像狗屁膏药贴在一起啊??
您可以狠狠地点击这里: BFC元素增加一个margin无效demo
实际上,这里的 margin并不是无效,而是值不够大 ,鞭长莫及啊!
用一个形象的Gif表示就是下面这样:
左侧浮动的图片就好比上面Gif图片中男孩的胳膊,妹子就是BFC元素,结果两人紧密接触。然后,margin-left就是妹子的胳膊个脚,虽然也甩出去了,可惜长度有限,于是,毫无影响。
如果按照上面的解释,那我们把margin-left:20px改成margin-left:150px就应该有间距了? 一试便知!
.float-left { float: left;}.follow-content { margin-left: 150px; background-color: #cad5eb; overflow: hidden;}
结果,当当当当:
注意:我这里举margin这个例子,不是让大家这样使用,只是为了让大家可以深入理解BFC元素与浮动元素混排的特性表现。实际开发,我们完全没有必要对BFC元素设置margin, 因为又回到了流体布局,明明是固定的15像素间距,但是,每个布局都要写一个不同的margin值,完全没有重用价值。
但是,间距部分的高潮来了!
我们可以使用浮动元素的margin-right或者padding-right轻松实现间距效果。间距是20像素,直接:
.float-left { float: left; margin-right: 20px;}
与浮动元素的宽度是多少没有任何关系。不仅如此,我们还可以使用BFC元素的padding-left撑开间距(虽然margin-left作用鸡肋)。
于是,我们可能就会有:
.l { float: left; }.ovh { overflow: hidden; }
的自适应固定搭配。再配合 zxx.lib.css CSS样式库的margin和padding家族,快速布局可谓所向披靡。
BFC自适应布局优势我总结了下面2点:
自适应内容由于封闭,更健壮,容错性强。比方说,内部clear:both不会与兄弟float产生矛盾。而纯流体布局,clear:both会让后面内容无法和float元素在一个水平上,产生布局问题。
自适应内容自动填满浮动以为区域,无需关心浮动元素宽度,可以整站大规模应用。而纯流体布局,需要大小不确定的margin/padding等值撑开合适间距,无法CSS组件化。
如下效果,图片能大能小,布局依然良好:
而CSS代码就是非常简单的:
.float-left { float: left; margin-right: 20px; }.bfc-content { overflow: hidden; background-color: #beceeb;}
可以说,有了BFC自适应布局,基本上没有了纯流体特性布局存在的价值。然而,只是理论上如此。如果,BFC自适应布局真那么吊炸天,那为何并没有口口相传呢?
那我们就得进一步深入理解了。
理论上,任何BFC元素和浮动搞基的时候,都可以实现自动填充的自适应布局。
但是,由于绝大多数的触发BFC的属性自身有一些古怪的特性,所以,实际操作的时候,能兼顾流体特性和BFC特性来实现无敌自适应布局的属性并不多。下面我们牵驴遛马一个一个瞅瞅(类似行为仅出1个代表示意,你懂的,如float:left/right):
float:left浮动元素本身BFC化,然而浮动元素有破坏性和包裹性,失去了元素本身的流体自适应性,因此,无法用来实现自动填满容器的自适应布局。不过,其因兼容性还算良好,与堆积木这种现实认知匹配,上手简单,因此在旧时代被大肆使用,也就是常说的“浮动布局”,也算阴差阳错开创了自己的一套布局。
position:absolute这个脱离文档流有些严重,过于清高,不跟普通小伙伴玩耍,我就不说什么了……
overflow:hidden这个超棒的哦!不像浮动和绝对定位,玩得有点过。也就是溢出剪裁什么的,本身还是个很普通的元素。因此,块状元素的流体特性保存相当完好,附上BFC的独立区域特性,可谓如虎添翼,宇宙无敌!哈无诶瓦(However), 就跟清除浮动:
.clearfix { overflow: hidden; _zoom: 1; }
一样。由于很多场景我们是不能overflow:hidden的,因此,无法作为一个通用CSS类整站大规模使用。因此,float+overflow的自适应布局,我们可以在局部(你确定不会有什么被剪裁的情况下)很happy地使用。
display:inline-blockCSS届最伟大的声明之一,但是,在这里,就有些捉襟见肘了。display:inline-block会让元素尺寸包裹收缩,完全就不是我们想要的block水平的流动特性。唉,只能是一声叹气一枪毙掉的命!然而,峰回路转,世事难料。大家应该知道,IE6/IE7浏览器下,block水平的元素设置display:inline-block元素还是block水平,也就是还是会自适应容器的可用宽度显示。于是,我们就阴差阳错得到一个比overflow:hidden更牛逼的声明,即BFC特性加身,又流体特性保留。
.float-left { float: left;}.bfc-content { display: inline-block;}
当然,*zoom: 1也是类似效果,不过只适用于低级的IE浏览器,如IE7~
display:table-cell让元素表现得像单元格一样,IE8+以上浏览器才支持。跟display:inline-block一样,会跟随内部元素的宽度显示,看样子也是不合适的命。但是,单元格有个非常神奇的特性,就是你宽度值设置地再大,大到西伯利亚,实际宽度也不会超过表格容器的宽度。
因此,如果我们把display:table-cell这个BFC元素宽度设置很大,比方说3000像素。那其实就跟block水平元素自动适应容器空间效果一模一样了。除非你的容器宽度超过3000像素,实际上,一般web页面不会有3000像素宽的模块的。所以,要是你实在不放心,设个9999像素值好了!
.float-left { float: left;}.bfc-content { display: table-cell; width: 9999px;}
看上去,好像还不错。但是,还是有两点制约,一是IE8+以上浏览器兼容,有些苦逼的团队还要管IE6;二是应付连续英文字符换行有些吃力(可以嵌套table-alyout:fixed解决)。但是,总体来看,适用的场景要比overflow:hidden广博很多。
display:table-row对width无感,无法自适应剩余容器空间。
display:table-caption一无是处……还有其他声明也都是一无是处,我就不全部展开了……
总结:我们对BFC声明家族大致过了一遍,能担任自适应布局重任的也就是:
overflow:auto/hidden IE7+
display:inline-block IE6/IE7
display:table-cell IE8+
由于overflow有剪裁和出现滚动条等隐患,不适合作为整站通用类,于是,最后,类似清除浮动的通用类语句:
.clearfix { *zoom: 1;}.clearfix:after { content: ''; display: table; clear: both;}
两栏或多栏自适应布局的通用类语句是(block水平标签,需配合浮动):
.cell { display: table-cell; width: 9999px; *display: inline-block; *width: auto;}
这就是 zxx.lib.css CSS样式库中.cell的由来!
当然,由于和浮动元素合作,清除浮动还是要的,于是,就有了.fix + .l/.r + .cell的无敌组合,可以多栏,也可以无限嵌套。
如果是局部,且确认安全;或有连续英文字符换行的隐患,你也可以使用.fix + .l/.r + .ovh的无敌组合,可以多栏,也可以无限嵌套。
估计本文是春节前的最后一篇文章了,小生在这里提前祝大家「羊年快乐」「万事如意」「事业蒸蒸日上」!
另,本文内容非权威,多个人理解与感悟,仅供参考。欢迎交流,提出您的真知灼见!
感谢阅读!
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址: http://www.zhangxinxu.com/wordpress/?p=4588