CSS最大的用处之一就是能够将内容和元素定位到任何咱们想要的位置,使咱们的设计具备结构,使内容更加易懂。css
CSS有好几种不一样的定位属性,每种都有本身的使用场景。在这节课中咱们会经过不一样的案例——可复用的布局和针对单元素的布局——来介绍每种方法。html
定位的其中一种方法就是使用float
属性。float
属性很是好用,能够用在不少地方。前端
本质来讲,float
属性是使元素脱离正常的流式布局,并将它放置在父元素的左侧或右侧。而后页面中全部的元素都会环绕浮动元素布局。例如咱们将段落间的一张图片设置为浮动,那么这些段落都会围绕图片换行。segmentfault
当咱们将多个元素同时设置为浮动元素,那么这些元素将呈现相邻或相对布局,如多列布局。浏览器
float
有好几个值,最经常使用的值是left
和right
。使元素浮动到父级元素的左侧或右侧。ide
img { float: left; }
咱们先建立一个通用页面,含有页头,页脚,中间有两列。最理想的状况就是在<body>
元素内建立第二节课"了解HTML"中提到的<header>
,<section>
,<aside>
和<footer>
元素。布局
<header>...</header> <section>...</section> <aside>...</aside> <footer>...</footer>
<section>
和<aside>
元素都是块状元素,它们默认上下布局。但咱们实际上想要它们并排显示。因此在此,咱们就能够将<section>
元素设为左浮动,将<aside>
元素设为右浮动,使它们呈现彼此相对的两列。
CSS代码以下:学习
section { float: left; } aside { float: right; }
在此提一下,元素设为浮动后,会浮动到父级元素的边缘。若是没有父级元素,那么它会浮动到页面的边缘。flex
当咱们设置一个元素为浮动,咱们就将它从HTML文档的正常流式布局中取出,这就致使元素的默认宽度取决于其内容的宽度。有时咱们用可复用的布局建立多列的时候并不但愿如此,那就能够为列设置一个固定宽度。另外,为了防止浮动元素紧靠在一块儿,使内容彼此紧贴,可使用margin
属性来建立元素间的空隙。
以下所示:网站
section { float: left; margin: 0 1.5%; width: 63%; } aside { float: right; margin: 0 1.5%; width: 30%; }
浮动会改变元素display的状态
有一个重要的点须要记住:将元素设为浮动就是将它从正常的流式布局中脱离,而这会改变元素默认的display
值。float
属性依赖于display
属性为block
的元素。若是一个元素的默认display
值不是block
,那么它会将默认值改为block
。
例如,span
是一个内联元素,它默认的display
值为inline
,width
和height
值是不生效的。然而,若是咱们将这个内联元素设置为浮动,那么它的默认display
值会变成block
,这时候width
和height
值就生效了。
当咱们设置元素为浮动时,都须要注意display
值的变化。
若只有两列,咱们能够将其中一个元素设置为左浮动,另外一个元素设置为右浮动,但如果多列的时候就须要换一种方法。例如,咱们但愿在<header>
和<footer>
元素之间添加一行三列的结构,能够先删掉以前写的<aside>
元素并使用三个<section>
元素,以下所示:
<header>...</header> <section>...</section> <section>...</section> <section>...</section> <footer>...</footer>
要将三个<section>
元素并排显示,咱们再也不用以前的左浮动加右浮动的模式,而是将三个元素都设置为左浮动。同时也要为元素设置宽度使其排列更合理。
section { float: left; margin: 0 1.5%; width: 30%; }
如今呈如今咱们眼前的就是三列宽度和外边距一致,都向左浮动的元素。
float
元素最初的设置是为了在内容中插入图片,使内容天然地环绕图片显示。虽然它在图片中使用很是完美,可是float
属性并非为了定位和布局设计的,因此在这方面存在一些缺陷。
其中一个缺陷就是浮动元素的下一个兄弟元素和父元素的样式可能会渲染异常。当元素浮动时它脱离了正常布局,致使围绕在浮动元素周围的元素的样式都受到了影响。
最多见的就是margin
和padding
属性值渲染异常,由于它们shi与浮动元素融为一体。固然,也有一些其它的样式也受到了影响。
另外一个缺陷是有时咱们不想内容围绕环绕浮动元素显示。浮动元素会从文件流中脱离,其余元素会彻底占有它周围的空间,但不少时候咱们并不但愿这样。
在上述两个元素并排显示的例子中, 咱们将<section>
元素和<aside>
元素设为浮动。在设置元素的width
属性以前,咱们能够看到<footer>
元素环绕两个浮动元素显示,占用全部可用空间。如此,<footer>
元素就显示在两个浮动元素之间的凹槽中。以下所示:
为了不这种状况,咱们就须要将浮动元素包裹起来或者清除浮动,使它们回到正常文件流中。接下来,咱们先着眼于如何清除浮动,再来介绍怎么包裹浮动元素。
清除浮动
清除浮动须要用到clear
属性,它最经常使用的属性值是:left
,right
,both
。
div { clear: left; }
属性值left
清除左浮动,right
清除右浮动。both
清除同时左浮动和右浮动,这也是咱们最推荐使用的属性值。
回到上例中,咱们为<footer>
元素添加clear:both
属性就能够清除浮动了。清除浮动可使页面回归正常文件流,因此很是重要。
footer { clear: both; }
包裹浮动元素
除了清除浮动,还能够包裹浮动元素。这两种方式页面呈现的效果是差很少的,但包裹元素的方式还有助于确保样式都渲染正常。
包裹元素就是将浮动元素置于父元素中,父元素做为容器会置于正常的文件流中。咱们为父元素添加一个class
属性group
,并为其设置CSS:
.group:before, .group:after { content: ""; display: table; } .group:after { clear: both; } .group { clear: both; *zoom: 1; }
上述写了不少代码,但实际上就是为class值为group
元素中的浮动元素清除浮动,使其回归正常文件流。
再具体点,代码中使用了在第四节中有提到过的:before
和:after
两个伪类,它们在class为group
的元素先后分别添加了一个动态元素。这些元素不包含任何内容,并以与块状元素block
很类似的表格元素table
的形式呈现。动态生成的元素:after
清除了class为group
的元素内的元素浮动。在.group
中设置的清除浮动则清除了排版在它之上的兄弟元素的浮动。老版本的浏览器也能够很好的兼容。
clear:both
单独声明会很合适。
回到示例,咱们能够将<section>
和<aside>
元素放置在一个父元素内,以下所示:
<header>...</header> <div class="group"> <section>...</section> <aside>...</aside> </div> <footer>...</footer>
.group:before, .group:after { content: ""; display: table; } .group:after { clear: both; } .group { clear: both; *zoom: 1; } section { float: left; margin: 0 1.5%; width: 63%; } aside { float: right; margin: 0 1.5%; width: 30%; }
这种包裹元素清除浮动的方式被称为clearfix
,咱们能够很容易在其它网站中找到定义它的class名clearfix
或cf
。咱们示例中使用了group
,它表明一组元素,更好地表达了内容的意义。
设置浮动元素时咱们要时刻注意它是否影响了页面的布局,并确认是否已根据须要清除浮动。不清除浮动会致使不少头疼的问题,尤为当页面多行多列排版的时候。
接下来,咱们打开“样式讨论会”网站来尝试将一部份内容浮动。
main.css
中的grid样式下添加清除浮动的样式group
,以下所示:/* ======================================== Clearfix ======================================== */ .group:before, .group:after { content: ""; display: table; } .group:after { clear: both; } .group { clear: both; *zoom: 1; }
-如今咱们要将<header>
元素内的<h1>
设置为左浮动,其余元素环绕这个元素显示。
先为<h1>
添加一个class属性,值为logo
,并在CSS中将其设置为左浮动:
<h1 class="logo"> <a href="index.html">Styles Conference</a> </h1>
/* ======================================== Primary header ======================================== */ .logo { float: left; }
<br/>
元素,使两个单词分两行显示。padding
。<h1 class="logo"> <a href="index.html">Styles <br> Conference</a> </h1>
.logo { border-top: 4px solid #648880; padding: 40px 0 22px 0; float: left; }
<h1>
设置为浮动,那么就须要在最靠近它的父级元素<header>
上添加class属性值group
来清除浮动:<header class="container group"> ... </header>
<header>
元素上的操做已经完成,接着咱们来处理<footer>
元素。与<header>
元素设置类似,咱们将包含版权信息的<small>
设置为左浮动,其余元素围绕这个元素显示。<header>
不一样的是,咱们不直接在浮动元素上添加class属性设置浮动。咱们先为其父元素添加一个class属性值,而且使用这惟一的选择器选中元素设置浮动。首先在<footer>
上添加class属性值primary-footer
。因为咱们已事先知道了要将<footer>
元素中的某个元素设为浮动,因此在<footer>
中添加class属性值group
。<footer class="primary-footer container group"> ... </footer>
<footer>
上添加了class属性值primary-footer
。咱们能够以其为预选择器选中<small>
元素并添加左浮动。以下所示:/* ======================================== Primary footer ======================================== */ .primary-footer small { float: left; }
primary-footer
的元素内的<small>
元素,例子中对应的就是<footer>
元素。<footer>
元素设置纵向padding
,使<footer>
的内容与其它内容分离。咱们能够直接在primary-footer
上添加样式:.primary-footer { padding-bottom: 44px; padding-top: 44px; }
<header>
和<footer>
的设置以后,咱们要将这些修改应用到每一个页面中。除了浮动,咱们也能够经过display:inline-block
来布局定位。它主要是帮助咱们作页面布局或同行元素间的的布局。
在此回顾一下,display:inline-block
使元素同行显示外,接受全部盒子模型的属性,包括height
,width
,padding
,border
和margin
。inline-block
能够充分使用盒子模型的全部属性,而且不须要清除浮动。
咱们来看上述三列并排显示的例子,HTML结构以下:
<header>...</header> <section>...</section> <section>...</section> <section>...</section> <footer>...</footer>
以前咱们为<section>
元素设置了浮动,如今咱们以display:inline-block
来代替,并保留以前设置的margin
和width
。 CSS呈现以下:
section { display: inline-block; margin: 0 1.5%; width: 30%; }
此时,代码并无很好的解决问题,最后一个<section>
元素掉到了下一行。行内块元素是行内一个接着一个布局,但它们之间有一个空格。当咱们将空格占用的空间和全部元素的width
、margin
相加,那么占用宽度会很是大,会将最后一个<section>
挤到下一行。为了让全部<section>
显示在同一行,咱们就须要把这些空格移除。
inline-block
元素之间的空格有好几种方法能够移除掉空格,但有些方法会相对复杂一些。咱们将介绍两种最简单的方法,都是应用在HTML中的。
第一中解决方案是将<section>
的开始标签和前一个<section>
的结束标签写在同一行。一行内的代码以开始标签为结尾,以下所示:
<header>...</header> <section> ... </section><section> ... </section><section> ... </section> <footer>...</footer>
用这种方法要确保HTML在书写时元素之间时没有空格,那么最终渲染时页面也不会呈现出空格。
另外一种方法是在元素之间添加注释。结束标签和开始标签之间以注释链接,注释必须紧跟元素。这么写能够容许HTML元素在书写时换行,代码以下:
<header>...</header> <section> ... </section><!-- --><section> ... </section><!-- --><section> ... </section> <footer>...</footer>
这两种方法没有一种是很是完美的,但它们都很好用。我(做者)更倾向于添加注释的方案,由于它更利于排版,但你彻底能够根据你的喜爱来选择。
在构建网站时,编写可复用的模块是很是有益的,而可复用的布局就是可复用代码中很是重要的一部分。布局可使用float
或者inline-block
元素的方法实现,但那一种方法更好呢?
这是值得商榷。我(做者)的作法是使用inline-block
元素实现页面的网格或布局,而当我想让某部份内容环绕某个元素显示时会使用float
(float
原本是用于处理图片的)。并且我也发现inline-block
元素的布局方式更简单,更易处理。
和前面说的同样,你能够根据本身的须要选择最合适的方案,若是你对其中一种方法更满意,那你就能够选择它。
目前,新的CSS规范提到了flex
和grid-
开头的属性——它们有助于实现页面的最佳布局。要时常关注留意这些新的方法。
对可复用的布局有所了解以后,咱们将其实施到咱们的Styles Conference
网站。
inline-block
元素来实现一个一排三列的可复用布局。能够将其分为等宽的三列,或者分为两列,一列占2/3宽,一列占1/3宽。class
选择器定义列宽width
,在main.css
文件中定义占1/3宽的选择器col-1-3
,占2/3宽的选择器col-2-3
。以下所示:.col-1-3 { width: 33.33%; } .col-2-3 { width: 66.66%; }
inline-block
元素的方式呈现,咱们就须要确保它们垂直对齐为顶部对齐。.col-1-3, .col-2-3 { display: inline-block; vertical-align: top; }
col-1-3
,col-2-3
之间用逗号,
隔开。逗号表示第一个选择器结尾,后面跟着第二个选择器。第二个选择器后跟随大括号{
标识样式开始申明。用逗号隔开选择器可让共用的样式同时绑定到多个选择器上。padding
。padding
属性。grid
的class
选择器,将其添加到共用的padding
定义中。代码以下所示,选择器以前一样用逗号隔开:.grid, .col-1-3, .col-2-3 { padding-left: 15px; padding-right: 15px; }
padding
后,咱们须要当心。上节课中,咱们建立了一个宽度为960px
,class名为container
的元素,并相对于页面左右居中。如今若是咱们将grid
元素嵌入container
元素中,那么它们的横向padding
就会相加,咱们的列与其余的部分呈现出的宽度会不一致。container
和grid
选择器共享一部分样式。具体的来讲,就是共享宽度width
(确保咱们的页面固定在960px
宽)和外边距margin
(使grid
元素居中),代码以下所示:.container, .grid { margin: 0 auto; width: 960px; } .container { padding-left: 30px; padding-right: 30px; }
class
属性包含有container
或者grid
的元素宽度都为960px
,并相对于页面居中。此外,咱们也将container
选择器的横向padding
分离写到了另外一个样式集中。index.html
主页的三个宣传栏开始,将它们设置为三列。如今它们由一个class名为container
的<section>
包裹。咱们要将这个container
替换为grid
,以下所示:<section class="grid"> ... </section>
class
属性col-1-3
添加到每一个gird
元素内的<section>
元素上:<section class="grid"> <section class="col-1-3"> ... </section> <section class="col-1-3"> ... </section> <section class="col-1-3"> ... </section> </section>
inline-block
元素,咱们要确保咱们移除了它们之间的间隙。咱们用注释来完成这一工做,并在每块中添加一些模块说明,以便更好的组织咱们的代码。<section class="grid"> <!-- Speakers --> <section class="col-1-3"> ... </section><!-- Schedule --><section class="col-1-3"> ... </section><!-- Venue --><section class="col-1-3"> ... </section> </section>
<\section>
后紧跟了注释,在第9行添加了用以标识的注释“Schedule”,并在11行开始标签<section>
前闭合了注释。相同的注释结构贯穿第13行和第17行,标识内容替换为Venue
。总的来讲咱们已经将全部的间隙都注释掉了并为每一块<section>
添加了标识。这是练习的源代码。点击下载
咱们经常想要定位一个元素,但float
和inline-block
并不能知足这种需求。浮动将元素从正常的文档流中移除,常常出现咱们不但愿获得的环绕浮动元素显示的布局。inline-block
元素,除非咱们建立多列,不然不易实现咱们想要的定位。针对这些状况,咱们可使用position
属性来作位置偏移。
position
属性表示元素应该怎样定位在页面中,是否按正常文档流显示。这须要结合盒子的位移属性——top
,right
,bottom
和left
——经过定义位移值设置不一样方向的位p移来定位元素在什么位置显示。
position
属性的默认值为static
,他表示元素以正常文档流呈现,而且不接受盒子位移属性。static
经常会被relative
和absolute
这两个值复写。这就是咱们接下来要讲的内容。
position:relative
在容许元素以正常文档流呈现,保留元素的空间不被其余元素占用外,也容许元素经过修改位移属性来定位,以下所示:
<div>...</div> <div class="offset">...</div> <div>...</div>
div { height: 100px; width: 100px; } .offset { left: 20px; position: relative; top: 20px; }
例子中第二个<div>
元素设置了class属性为offset
,offset
选择器设置了position:relative
和两个位移属性left
和top
。这保留了元素原来的位置,不会被其余元素占用。另外位移属性从新定位了元素的位置,使它向右偏移20px
,向下偏移20px
。
使用相对定位有一个重要的点要知道:盒子位移属性是根据元素自己的位置来进行位移的。因此设置left:20px
就是将元素从左向右位移20px
。top:20px
就是元素至上向下位移20px
。
当使用position
对元素进位移时,该元素会与其余元素重叠,而不是将其余元素像使用了margin
和padding
同样移到下面。
position:absolute
为绝对定位,它与相对定位不一样,绝对定位脱离了文档流,而它原有的位置不会被保留。
另外,绝对定位的元素位移与离他最近的设置了相对定位的父级元素有关。若是没有相对定位的父级元素,那么绝对定位会根据<body>
来定位(译者:根据个人实践,浏览器在绝对定位的元素没有相对定位的父级元素时,并非根据<body>定位,而是经过视窗的位置定位,有兴趣的读者能够尝试一下)
。这里的信息量比较多,咱们经过例子来看一下:
HTML
<section> <div class="offset">...</div> </section>
section { position: relative; } div { position: absolute; right: 20px; top: 20px; }
在这个例子中,<section>
元素是不包含位移属性的相对定位的元素,因此它没有位移。div
元素设置了包含position: absolute
的class
属性offset
。因为<section>
是离它最近的设置了相对定位的父级元素,因此div
依赖<section>
元素的位置进行偏移
因为设置了right
和top
位移,<div>
根据<section>
元素从右向左位移20px
,从上向下位移20px
。
因为<div>
元素是绝对定位,它不在页面的正常文档流中,会与它周围的元素重叠。另外,<div>
元素原来的位置也没有被保留,其余元素能够占据这个位置。
一般状况下,大多数的定位都不须要经过定位和位移属性来处理,但在某些状况下它们确实很是有用。
学习如何经过HTML和CSS来定位内容是掌握这两门语言很是重要的一步。再加上盒子模型,咱们正走在成为前端开发者的路上。
回顾一下,在这节课中咱们所碰到的知识点:
inline-block
元素定位内容。inline-block
元素间的间隙。咱们每节课都在学习新的技能,因此让咱们继续。接下来,排版!