这是《CSS设计指南》的读书笔记,用于加深学习效果。css
display
是 CSS 中最重要的用于控制布局的属性。每一个元素都有一个默认的 display 值。对于大多数元素它们的默认值一般是 block 或 inline 。一个 block 元素一般被叫作块级元素。一个 inline 元素一般被叫作行内元素。html
div
是一个标准的块级元素。一个块级元素会新开始一行而且尽量撑满容器。其余经常使用的块级元素包括 p
、 form
和HTML5中的新元素: header
、 footer
、 section
等等。web
img
是一个标准的行内元素。你能够把两个 <img>
标签写在两行,但这并不影响图片再浏览器中的显示效果,它们会并列出如今一行上。并且标签直接的空白(标记中的两个<img>标签虽然分别位于两行,但这并不影响图片在浏览器中显示时的效果。图片是行内元素,因此它们显示的时候就会并列出如今一行上。并且,标签之间的空白(包括制表、回车和空格)都会被浏览器忽略。segmentfault
a
元素是最经常使用的行内元素,它能够被用做连接。浏览器
另外一个经常使用的 display 值是 none。一些特殊元素的默认 display 值是它,例如script
。display:none 一般被 JavaScript 用来在不删除元素的状况下隐藏或显示元素。
把display设置为 none,该元素及全部包含在其中的元素,都不会在页面中显示。它们原来占据的空间也会被回收。app
相对的属性是
visibility
,这个属性经常使用的值是 visible(默认)和 hidden。把元素的 visibility 设定为 hidden,元素会隐藏,但它占据的空间仍然存在。框架
还有不少的更有意思的 display 值,几乎全部HTML元素的display属性值要么为block,要么为inline。最明显的一个例外是table元素,它有本身特殊的display属性值。这里有一份详细的列表。ide
块级元素(好比标题和段落)会相互堆叠在一块儿沿页面向下排列,每一个元素分别占一行。而行内元素(好比连接和图片)则会相互并列,只有在空间不足以并列的状况下才会折到下一行显示 。布局
块级元素和行内元素是能够互相转化的:学习
/*默认为块级元素*/ p {display: inline;} /*默认为行内元素*/ a {display: block;}
属性了 display 属性以后,咱们来看下页面布局:
多栏布局有三种基本的实现方案:固定宽度
、流动
、 弹性
。
固定宽度布局的大小不会随用户调整浏览器窗口大小而变化,通常是900到1100像素宽。其中960像素是最多见的,由于这个宽度适合全部现代显示器,并且可以被1六、十二、十、八、六、五、4和3整除,不只容易计算等宽分栏的数量,并且计算结果也能获得没有小数的像素数。
流动布局的大小会随用户调整浏览器窗口大小而变化。这种布局可以更好地适应大屏幕,但同时也意味着放弃对页面某些方面的控制,好比随着页面宽度变化,文本行的长度和页面元素之间的位置关系均可能变化。Amazon.com的页面采用的就是流动中栏布局,在各栏宽度加大时经过为内容元素周围添加空白来保持内容居中,并且如今的导航条会在布局变窄到某个宽度时收缩进一个下拉菜单中,从而为内容腾出空间。
弹性布局与流动布局相似,在浏览器窗口变宽时,不只布局变宽,并且全部内容元素的大小也会变化,让人产生一种全部东西都变大了的感受。
多数状况下,布局中结构化元素(乃至任何元素)的高度是没必要设定的。事实上,我甚至想告诉你根本不该该给元素设定高度。除非你确实须要这样作,好比在页面中创造一个绝对定位的元素。
为何正常状况下都应该保持元素height属性的默认值auto不变呢?很简单,只有这样元素才能随本身包含内容的增长而在垂直方向上扩展。这样扩展的元素会把下方的元素向下推,而布局也能随着内容数量的增减而垂直伸缩。假如你明确设定了元素的高度,那么超出的内容要么被剪掉,要么会跑到容器以外——取决于元素overflow属性的设定。
与高度不一样,咱们须要更精细地控制布局宽度,以便随着浏览器窗口宽度的合理变化,布局可以做出适当的调整,确保文本行不会过长或太短。若是随意给元素添加内边距、边框,或者元素自己过大,致使浮动元素的宽度超过包含元素的布局宽度,那浮动元素就可能“躲”到其余元素下方。应该让这些内容元素自动扩展到填满栏的宽度。(这是块级元素的默认行为)
咱们先从一个简单的居中的单栏布局开始吧。看下面 HTML 代码,主要标记的 ID 是 wrapper:
<div id="wrapper"> <article> <h1>Single-Column Layout</h1> <p>这是第一段</p> <h2>This is a Second-Level Heading</h2> <p>这是第二段</p> </article> </div>
布局相关 css 以下:
#wrapper { width:960px; margin:0 auto; border:1px solid; } article { background:#ffed53; }
如图所示,经过给外包装设定宽度值,并将其水平外边距设定为 auto,这个单栏布局在页面上居中了。随着向里添加内容,这一栏的高度会相应增长。外包装中的article元素本质上就是一个没有宽度的块级盒子(关于“没有宽度的盒子”,请参见3.2节),它水平扩展填满了外包装。
下面,咱们再向外包装里添加一个导航元素,让它做为第二栏。
HTML 代码以下:
<div id="wrapper"> <nav> <ul> <li><a href="#">Link 1</a></li> <li><a href="#">Link 2</a></li> <li><a href="#">Link 3</a></li> </ul> </nav> <article> <h1>Single-Column Layout</h1> <p>这是第一段</p> <h2>This is a Second-Level Heading</h2> <p>这是第二段.</p> </article> </div>
这里咱们将两栏都添加float: left
,以让它们并排显示。
#wrapper { width:960px; margin:0 auto; border:1px solid; overflow:hidden; } nav { width:150px; float:left; /*浮动*/ background:#dcd9c0; } nav li { /*去掉列表项目符号*/ list-style-type:none; } article { width:810px; float:left; /*浮动*/ background:#ffed53; }
这里咱们把两栏的总宽度设定为外包装的宽度(150+810=960),并浮动它们,就能够创造出并肩排列的两栏来。每一栏的长度取决于内容多少。
接下来咱们添加第三栏。
<div id="wrapper"> <nav> <ul> <li><a href="#">Link 1</a></li> <li><a href="#">Link 2</a></li> <li><a href="#">Link 3</a></li> </ul> </nav> <article> <h1>Single-Column Layout</h1> <p>这是第一段</p> <h2>This is a Second-Level Heading</h2> <p>这是第二段.</p> </article> <aside> <h3>This is the Sidebar</h3> <p>这是侧边栏.</p> </aside> </div>
接下来咱们调整一下 article 这一栏的宽度,为第三栏腾出空间
#wrapper { width:960px; margin:0 auto; border:1px solid; overflow:hidden; } nav { width:150px; float:left; background:#dcd9c0; } article { width:600px; float:left; background:#ffed53; } aside { width:210px; float:left; background:#3f7ccf; }
如图所示,经过把三个浮动容器的总宽度设定为刚好等于外包装的宽度(150+600+210=960),就有了三栏布局的框架。
如今咱们再添加一个页眉和页脚:
<div id="wrapper"> <header> <h1>A Fixed-Width Layout</h1> </header> <nav> <ul> <li><a href="#">Link 1</a></li> <li><a href="#">Link 2</a></li> <li><a href="#">Link 3</a></li> </ul> </nav> <article> <h1>Single-Column Layout</h1> <p>这是第一段</p> <h2>This is a Second-Level Heading</h2> <p>这是第二段.</p> </article> <aside> <h3>This is the Sidebar</h3> <p>这是侧边栏.</p> </aside> <footer> <p>This is the footer. Phasellus pretium gravida interdum. Nam interdum posuere tempus. Ut commodo laoreet dolor, non hendrerit mi dictum vitae. Nam nec egestas libero.</p> </footer> </div>
为了让页脚在最下一栏不浮动到 aside
后边,咱们为页脚应用clear:both
,以组织它向上移动。
css 样式以下:
* {margin:0; padding:0;} #wrapper { width:960px; margin:0 auto; border:1px solid; } header { background:#f00; } nav { width:150px; float:left; background:#dcd9c0; } nav li { list-style-type:none; } article { width:600px; float:left; background:#ffed53; } aside { width:210px; float:left; background:#3f7ccf; } footer { clear:both; background:#000; }
如今效果如图:
如今各栏太拥挤,每栏的高度也都由文本内容决定,咱们如今修改一下,为内容间加上空白。
为了让内容与栏边界空开距离,为栏添加水平外边距和内边距,但这样会致使布局宽度增大,进而浮动栏下滑。
好比,咱们给 article 增长内边距:
article { width: 600px; float: left; background: #ffed53; padding: 10px 20px; }
效果如图:
因为增长了内边距致使article
的总宽度增长,致使右边的栏不能再与前两排并列在一块儿。有三种方法来预防改问题发生:
从设定的元素宽度中减去添加的水平外边距、边框和内边距的宽度和。
在容器内部的元素上添加内边距或外边距。
使用CSS3的box-sizing属性切换盒子缩放方式,好比section {box-sizing:border-box;} 。 应用box-sizing属性后,给section添加边框和内边距都不会增大盒子,相反会致使内容变窄。
一个代代相传的解决方案是经过数学计算。CSS开发者须要用比他们实际想要的宽度小一点的宽度,须要减去内边距和边框的宽度。好比咱们给600像素宽的中间栏增长了20像素的内边距,为了抵消增长的内边距,能够把栏减小40像素而设定为560像素。
值得庆幸地是你不须要再这么作了...
把外边距和内边距应用到内容元素上确实有效,不过这样的前提是这些元素没有明确的设定宽度,这样内容才会随内外边距的增长而缩小。
与其为容器中的元素添加外边距,不如在栏中再添加一个没有宽度的div,让它包含全部内容元素,而后再给这个div应用边框和内边距。如此一来,只要为内部div设定一次样式,就能够把让全部内容元素与栏边界保持一致的距离。并且,未来再须要调整时也会很方便。任何新增内容元素的宽度都由这个内部div决定。
下面咱们用这种方法修复上面第三栏浮动到下边的问题。
<article> <div class="inner"> <!-- 这里是各类内容 --> </div> </article>
接下来,咱们不只要给内部 div 应用内边距,还要给她应用外边距和边框。
/*更新 css*/ article { width:600px; float:left; background:#ffed53; } article .inner { margin:10px; border:2px solid red; padding:20px; }
效果如图:
以上措施使布局有了明显改观。就这么简单的几下,布局就显得更专业了。处理栏及其内部div的关键在于,浮动栏并设定栏宽,但不给任何内容元素设定宽度。要让内容元素扩展以填充它们的父元素——内部div。这样,只要简单地设定内部div的外边距和内边距,就可让它们以及它们包含的内容与栏边界保持必定距离。
人们慢慢的意识到传统的盒子模型不直接,因此他们新增了一个叫作 box-sizing 的CSS属性。当你设置一个元素为 box-sizing: border-box; 时,此元素的内边距和边框再也不会增长它的宽度。这里有一个与前一页相同的例子,惟一的区别是两个元素都设置了 box-sizing: border-box;
nav { -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; width:150px; float:left; background:#dcd9c0; padding:10px 10px; } article { -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; width:600px; float:left; background:#ffed53; padding:10px 20px; } aside { -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; width:210px; float:left; background:#3f7ccf; padding:10px 10px; }
这是目前为止最好的解决方法了,那最简单有效的方法就是在 css 里添加这样一条规则:
* { -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; }
中栏流动布局的目的是在屏幕变窄时,中栏变窄,左栏和右栏宽度不变。
这里咱们使用负外边距
实现。
实现三栏布局且让中栏内容区流动(不固定)的核心问题是处理右栏的定位,并在中栏内容区大小改变时控制右栏与布局的关系。
这里咱们使用Ryan Brill
给出的控制两个外包装容器的外边距的解决方案。其中一个外包装包围三栏,另外一个外保障包围左栏和中栏。
html代码示例以下:
<div id="main_wrapper"> <header> <!-- 页眉--> </header> <div id="threecolwrap">/*三栏外包装(包围所有三栏)*/ <div id="twocolwrap">/*两栏外包装(包围左栏和中栏)*/ /*左栏*/ <nav> <!-- 导航 --> </nav> /*中栏*/ <article> <!-- 区块 --> </article> </div>/*结束两栏外包装(twocolwrap)*/ /*右栏*/ <aside> <!-- 侧栏 --> </aside> </div>/*结束三栏外包装(threecolwrap)*/ <footer> <!-- 页脚 --> </footer> </div>
css规则以下:
* { margin: 0; padding: 0; } body { font: 1em helvetica, arial, sans-serif; } div#main_wrapper { min-width: 600px; max-width: 1100px; /*超过最大宽度时,居中布局*/ margin: 0 auto; /*背景图片默认从左上角开始拼接*/ background: url(images/bg_tile_150pxw.png) repeat-y #eee; } header { padding: 5px 10px; background: #3f7ccf; } div#threecolwrap { /*浮动强制它包围浮动的栏*/ float: left; width: 100%; /*背景图片右对齐*/ background: url(images/bg_tile_210pxw.png) top right repeat-y; } div#twocolwrap { /*浮动强制它包围浮动的栏*/ float: left; width: 100%; /*把右栏拉到区块外边距腾出的位置上*/ margin-right: -210px; } nav { float: left; width: 150px; background: #f00; padding: 20px 0; } /*让子元素与栏边界保持必定距离*/ nav>* { margin: 0 10px; } article { width: auto; margin-left: 150px; /*在流动居中的栏右侧腾出空间*/ margin-right: 210px; background: #eee; padding: 20px 0; } /*让子元素与栏边界保持必定距离*/ article>* { margin: 0 20px; } aside { float: left; width: 210px; background: #ffed53; padding: 20px 0; } /*让子元素与栏边界保持必定距离*/ aside>* { margin: 0 10px; } footer { clear: both; width: 100%; text-align: center; background: #000; }
基本原理:
上面两幅图展现了流动中栏布局。三栏中的右栏是210像素宽。为了给右栏腾出空间,中栏article元素有一个210像素的右外边距。包围左栏和中栏的两栏外包装上210像素的负右外边距,会把右栏拉回article元素右外边距(在两栏外包装内部右侧)创造的空间内。中栏aticle元素的宽度是auto,所以它仍然会力求占据浮动左栏剩余的全部空间。但是,一方面它本身的右外边距在两栏外包装内为右栏腾出了空间,另外一方面两栏外包装的负右外边距又把右栏拉到了该空间内。
上面的例子中,咱们用到了百分比宽度
,百分比是一种相对于包含块的计量单位。你还能同时使用 min-width 和 max-width 来限制最大或最小宽度!
你能够用百分比作布局,可是这须要更多的工做。若是咱们上边的例子中 nav 用百分比宽度作布局,当窗口宽度很窄时 nav 的内容会以一种不太友好的方式被包裹起来。
上面的例子咱们实现多栏并列的方式是使用float
,不过咱们也可使用inline-block
。下边是咱们把 float 替换为inline-block
的例子。
nav { width:150px; display: inline-block; vertical-align: top; background:#dcd9c0; } article { word-spacing:0; width:600px; display: inline-block; vertical-align: top; background:#ffed53; } aside { word-spacing:0; width:210px; display: inline-block; vertical-align: top; background:#3f7ccf; }
使用inline-block
,有一些事情须要你牢记:
vertical-align 属性会影响到 inline-block 元素,你可能会把它的值设置为 top 。
你须要设置每一列的宽度
若是HTML源代码中元素之间有空格,那么列与列之间会产生空隙
特别是第三条,若是咱们不作任何修改,两个 block 之间会存在空格,像这样:
由于列与列之间产生了空格,因此 aside 跑到了下边。这里最简单的解决办法是:
<nav> 导航 </nav><article> 内容 </article><aside> 第三栏 </aside>
其余解决方案能够参考这篇文章 Fighting the Space Between Inline Block Elements
初次以外,css 还提供了 column
、flexbox
等布局方式,这些之后有机会再介绍吧。
这篇文章咱们介绍了用浮动的有宽度的元素来建立多栏布局、如何让固定布局在页面上居中以及让它们在必定范围内能够伸缩。同时也了解了如何使用内部div在浮动元素中生成间距,而又不会改变布局的总宽度。
最后,感谢女友支持。
欢迎关注(April_Louisa) | 请我喝芬达 |
---|---|
![]() |
![]() |