最近『図解CSS3』のレイアウト部分を見て、以前読んだレイアウトの知識と合わせて、CSS2と3をベースにした様々なレイアウト方法をまとめました。
デザイン案をいただいたら、フロントエンドスタッフとして、まずデザイン画の領域を大まかに分け、最も合理的で構造が明確なレイアウトを選択します。以下では、まず、いくつかの典型的な Web サイトのケースに基づいて、いくつかの一般的なページ レイアウトをリストします。
これは、通常、ページの上部に横型 Web サイトのロゴまたはバナー広告が配置され、左下がナビゲーション バー メニュー、右下がレイアウトです。 Web ページのメインコンテンツなどのメインコンテンツを配置するために使用されます。 Segmentfault のホームページは T 字型のレイアウトになっています。 Web ページが長すぎるためです。 。底は切り取られていません。
中国語フォント レイアウトの上部は Web サイトのタイトルとバナー広告で、続いて Web サイトのメイン コンテンツ、左右に小さなコンテンツのストリップがいくつかあり、中央の質問が続きます。がメイン部分で、左右に並んでいます。最後に、Web サイトの基本情報、連絡先情報、著作権表示などがいくつか表示されます。
この事例の写真は、2011 年に Tencent が行った以前の筆記試験の問題からのものです。興味のある学生はご覧ください。 2011 Tencent フロントエンド インタビュー ドラフト
POP レイアウトとは、ページのデザインの中心に美しい写真を使用したプロモーション ポスターのようなページ レイアウトを意味します。ファッションサイトなどでよく使われています。利点は明白です:美しくて魅力的です。欠点は遅いことです。
全国人民代表大会のホームページもこのレイアウトと似ています。
その名が示すように、Web ページの本体は左と右の 2 つの大きなブロックに分かれており、そのほとんどがバックグラウンド管理システムのページです。一般に、左右のレイアウト ページには同じ高さの 2 つの列が必要です。
例:
全画面表示と同様の Apple 公式 Web ページはすべて上下レイアウトです。
以上で、上記のレイアウトの実装方法をまとめてみましょう。誰もがよく知っている 2 つのレイアウト方法について触れてみましょう。 聖杯レイアウトと双飛燕レイアウト。実際、この 2 つの方法は、中国の形のレイアウトで一般的に使用されます。 3行3列のレイアウト用に設計されています。対応する変更を加えれば、T 字型レイアウトでも使用できます。これら 2 つの方法は、本編の優先読み込みの問題をうまく解決できます。
基本的なレイアウト:
<div id="header"></div><div id="main"></div><div id="footer"></div>
コードの主要部分に焦点を当てます
<style type="text/css"> #main { overflow: hidden; /*修整由子元素浮动引起的高度塌陷问题*/ zoom: 1;/*低版本ie下:触发haslayout属性,修整由子元素浮动引起的高度塌陷问题*/ /*将主体部分左右侧预留出左右边栏大小的空白位置*/ padding: 0 300px 0 220px; } .m_content, .m_leftside, .m_rightside { float: left; /*目的是将左右侧边栏拉回*/ position: relative; } .m_content { width: 100%; } .m_leftside { width: 220px; /*由于m_content占据了100%空间,所以需要用负的margin值将左边栏拉回*/ margin-left: -100%; /*将主体部分预留的左侧补白区域填充满*/ left: -220px; } .m_rightside { width: 300px; /*用负的margin值将右边栏拉回自身大小个像素单位*/ margin-left: -300px; /*将主体部分预留的右侧补白区域填充满*/ left: 300px; }</style><div id="main"> <div class="m_content">这里是主体</div> <div class="m_leftside">这是左侧边栏</div> <div class="m_rightside">这是右侧边栏</div></div>
上記は、Holy Grail のレイアウト方法です。基本的な考え方は、コードがフローティング プラス配置であることです。より複雑であり、同じ高さの 3 つの列をシミュレートすることはできません。
レイアウトの効果は聖杯と同じですが、コードが異なります。 Shuangfeiyan レイアウトのコードはよりシンプルで、レイアウト用の div を追加するだけです。基本的なレイアウトコードは同じです。
本編:
<style> #main {overflow: hidden;zoom: 1;}/*这里不需要加padding了*/ .m_content, .m_leftside, .m_rightside {float: left;} .m_content {width: 100%;} /*用左右边距将左右边栏的位置预留出来*/ .m_c_wrap {margin-left: 220px;margin-right:300px;} .m_leftside {width: 220px;margin-left: -100%;} .m_rightside {width: 300px;margin-left: -300px;}</style><div id="main"> <div class="m_content"> <!--正真的主体开始--> <div class="m_c_wrap">这里是主体</div> </div> <div class="m_leftside">这是左侧边栏</div> <div class="m_rightside">这是右侧边栏</div></div>
上記の 2 つのレイアウト方法を理解すると、多くのレイアウトを簡単に記述することができます。ただし、複数列と同じ高さのレイアウトを扱うにはまだ少し不十分です。それでは、複数列の等高レイアウトの方法について説明しましょう。
ここでは、同じ高さのレイアウトの 8 つの方法の詳細な概要を示します。クリックして、実際のプロジェクトでよく使用される、または比較的単純な 3 つの方法について説明します。
画像シミュレーション
たとえば、上記のようなレイアウトを作成する必要がある場合、そのような小さな側面画像をキャプチャし、側面部分とコンテンツ部分で囲まれた要素の背景をタイル表示して、高さと高さをシミュレートする必要がありますサイドバーのビジュアルとコンテンツの一貫性が高い。
テーブル レイアウト
テーブル セルと同じ高さにする必要がある複数の列の表示属性を設定するだけで済みます。列の 1 つを適応幅にしたい場合は、親要素の表示も設定する必要があります。テーブルに移動し、幅は 100% です。コードは次のとおりです:
<style> #main {display: table;width: 100%} .m_content {display: table-cell;width: auto;} .m_rightside {display: table-cell;width: 200px;}</style><div id="main"> <div class="m_content"></div> <div class="m_rightside"></div></div>
これは、少し前にインターネットで見た方法です。本質は、十分な大きさの padding-bottom 値を列に追加し、列を拡張してからです。同じサイズを追加します
負の margin-bottom 値はコンテンツを後方に移動します。 overflow: hidden 属性をネガティブボックスに追加する必要があることに注意してください。
コードは以下の通りです:
<style> #main {width: 100%;overflow: hidden;} .m_content {width: auto;float:left;} .m_rightside {width: 200px;padding-bottom: 10000px;margin-bottom: 10000px;float:left;}</style><div id="main"> <div class="m_content"></div> <div class="m_rightside"></div></div>
フレックスレイアウト
フレックスレイアウトを行うには、
フレックスコンテナを定義し、そのサブアイテムを処理する必要があります。コンテナがフレックス コンテナとして定義されている限り、その子要素はその子アイテムと呼ばれます。
flex布局的基本思想是通过flex容器来伸缩控制子项目的宽度和高度,以此来完全填充flex容器的可用空间。 子项目的宽高、排列方式等都是通过设置相关属性改变的。那么以这种方式布局上述几种布局就简单多了。子项目默认的排列方式与浮动布局略为相似。
flex容器的定义方式:
div{display:flex}
flex容器分为主轴和侧轴。 主轴决定容器子项的排列方向。侧轴与主轴相互垂直。主轴可有垂直和水平两个方向。
flex容器可对子项进行的操控有:(即设置在容器的属性。这个很重要!)
子项目的 排列方向(也就是刚刚说的定义主轴)—— flex-direction
子项目的 换行方式(就是 超出flex容器跨度时换不换行=。=怎么换) —— flex-wrap
同时进行子项目排列方向和换行方式的设定 —— flex-flow
子项目 在主轴的对齐方式(想象成文字的对齐方式就容易理解了) —— justify-content
子项目 在侧轴的对齐方式—— align-items
同时进行子项目主轴和侧轴对齐方式的设定 —— align-content
下面来看看每一个属性的取值和实现效果
div{ flex-direction: row /*水平排列,默认*/ <row-reverse> /*水平排列,但子项目从右侧开始排列*/ <column> /*垂直排列*/ <column-reverse>; /*垂直排列,但子项目从下侧开始排列*/ }
测试中我令flex容器的宽度为100px,高为200px,定义了5个未定义宽高的子项目,演示了上述的四种排列情况。效果:
这里需要说明的是:在未定义子项目的伸缩方式时,默认是按子项目本身大小渲染的。
div{ flex-direction: nowrap /*当子项目在主轴上的总跨度大于主轴长度时,不进行换行,而是缩小每个子项目的跨度。默认*/ <wrap> /*---同上---进行换行显示*/ <wrap-reverse> /*从侧轴的末端进行换行(在主轴的排列方向不变)。实际不常用*/ }
测试中我定义了每个子项目的宽度为30px,flex容器还是原来的100px宽。效果:
由于这里设定的是子项目宽度,所以对于主轴为垂直方向的容器子项没什么影响。
div{ flex-flow: <flex-direction> || <flex-wrap>; /*就是上述两个属性的结合简写 默认:flex-flow:row nowrap*/ }
div{ justify-content: flex-start /*以项目开始进行排列的那端进行对齐,默认左对齐*/ <flex-end> /*以项目结束排列的那端进行对齐,默认右对齐*/ <center> /*居中对齐,默认水平居中*/ /*两端对齐且项目之间的间隔都相等(贴边显示)*/ <space-between> /*第一个元素前的空间以及最后一个元素后的空间为其他空白空间的一半下平均分布*/ <space-around> }
测试时我设定了flex容器宽高都为200px,子项没有设定宽高。 效果:
主轴为水平方向时:
主轴为水平垂直时:
div{ align-items: flex-start /*侧轴起始点对齐*/ <flex-end> /*侧轴终止点对齐*/ <center> /*侧轴中点点对齐*/ /*项目的第一行文字的基线对齐*/ <baseline> /*默认值,如果项目未设定宽(高度),则占满整个容器侧轴跨度*/ <stretch> }
最后的baseline看起来跟flex-start没啥区别,因为我给每个子项设置高度。设置高度后:
div{ align-content: flex-start /*与侧轴起始点对齐*/ <flex-end> /*与侧轴终止点对齐*/ <center> /*与侧轴中点点对齐*/ /*与侧轴两端对齐,各子项在各轴上的间距相等*/ <space-between> /*各子项在各轴上的间距相等,项目间距比边距间距大一倍*/ <space-around> /*项目占满整个侧轴*/ <stretch> }
上面已提到过,对于单轴线的子项来说,本属性不起作用。但是默认情况下是只有子项目是一根轴线的( flex-wrap默认是 nowrap),所以要使这个属性看到效果,必须设置 flex-wrap。
已下是 flex-wrap为 wrap的几种情况。
以下这些属性设置在子项上。子项自身的操控有
子项目的 排列顺序—— order
子项目的 放大比例—— flex-grow默认为0,即如果主轴上有剩余空间,也不放大子项。
子项目的 缩小比例—— flex-shrink默认为1,即如果主轴空间不足,即缩小子项。
同时设定前三者 —— flex
设定单个项目 其自身在侧轴的对齐方式—— align-self
那么分别来看看每个属性的取值和实现效果()
order
利用这个属性可以解决某个区块优先加载但是在页面上的显示较靠后的问题。
div .item {order:<integer>}/*数值越大,排列越靠后。默认为0*/
这里我设置了第一个子项的order为1。
flex-grow
如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的空间将比其他项多一倍。
div .item {flex-grow:<number>}
设置flex-grow前:
设置后:
第二个项目的flex-grow为2,其他为0:
<注意这个时候就不需要给子项设置宽度了>
flex-shrink
如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。
div .item {flex-shrink:<number>}
我给每个子项设定了200px的宽度,而flex容器宽度为500px,这时候若不设置flex-shrink,则每个项目都会以相同比例缩小自身大小来适应容器。
此时我给第二个项目设置了 flex-shrink: 0;该项目大小不变。
flex-basis
这个属性设置子项在主轴上的跨度,简单地说就是设置宽高。
div .item {flex-basis:<length> | auto/*auto是默认值,就是项目本身大小*/}
flex
这个就是把flex-grow、flew-shrink、flex-basis结合一起的写法啦=。=
div .item {flex:none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]}
flex-grow必须。 默认为0 1 auto。
align-self
这个属性用来单独设定某个子项目在侧轴的对齐方式。
div .item {align-self:flex-start|flex-end|center|baseline|stretch}
有关flex布局的方法就总结和介绍到这里了。有兴趣看可以看一下下面大大们写的相关方面的文章。
Flex布局教程——阮一峰 传送门
A Complete Guide to Flexbox 传送门2
一个完整的Flexbox指南 传送门3
下边把利用flex布局实现上述几种布局的代码贴出来(可有多种实现方法)。
<!--css--><style type="text/css"> *{margin: 0;padding: 0;} header, footer {background: sandybrown;height: 50px;} section {display: flex;align-items: flex-start;height: 500px;} article {order: 1;flex: 3;align-self: stretch;background: wheat;} aside {flex: 1;background: seashell;height: 100px;}</style><!--html--><header></header><section> <article></article> <aside></aside></section><footer></footer>
国字型布局
<!--css--><style type="text/css"> *{margin: 0;padding: 0;} header, footer {background: sandybrown;height: 50px;} section {display: flex;align-items: flex-start;height: 500px;} article {order: 1;flex: 3;align-self: stretch;background: wheat;} aside {flex: 1;background: seashell;height: 100px;} section.sidebar {order: 2;flex: 1;height: 100px;background: seashell;}</style><!--html--><header></header><section> <article></article> <aside></aside> <section class="sidebar"></section></section><footer></footer>
等高布局
真心简单。
<!--css--><style type="text/css"> *{margin: 0;padding: 0;} html,body {height: 100%;} section {display: flex;height: 100%;} article {order: 1;flex: 3;background: wheat;} aside {flex: 1;background: seashell;}</style><!--html--><header></header><section> <article></article> <aside></aside> <section class="sidebar"></section></section><footer></footer>
拖了半个多月的博文。。也算是写完了,感谢大家阅读。