本系列文章的绝大多数内容都来自 w3cschool, 再次感谢。
CSS定位的基本思想很简单,它允许定义元素框相对于其正常位置应该出现的位置,或者相对于父元素、另一个元素甚至浏览器窗口本身的位置。
块级元素和行内元素
块级元素就像是一个四方块,它可以放在页面的任意位置,它类似于一个段落,前后各有一个换行符(非显示添加的)。像<h1>,<p>,<div>,<table>,<ul>等都是块级元素,如果不加特殊定义,它们前后的内容和它们都不在同一行。行内元素也叫内联元素,只能出现在行内,除非在他们后面人为加上换行符,否则它们后面的内容和它们仍然是在同一行里。像<a>,<strong>,<span>,<img>等都是行内元素。
可以通过display属性改变一个元素的显示属性,它有多个备选值:
- none, 该元素不会显示,在页面上也不占有空间
- block,让元素以块级元素形式显示
- inline,默认值,让元素以行内元素的形式显示
- 其他
但是当把一些文本添加到一个块级元素(比如div)的开头,即使没有进行显式定义,也会创建块级元素:
<div>
some text
<p>Some more text.</p>
</div>
上述代码中的"some text"因为出现在<div>元素的开头,又没有其他定义,所以它就是一个块级元素,只是它不与任何专门定义的元素关联,也就没有办法对其单独使用样式。块级元素的文本行也会发生类似的情况,它的每行文本形成一个无名框(是行框,但不是行内框)。无法直接对无名块或行框应用样式,因为没有可以应用样式的地方。
CSS定位机制
- CSS 有三种基本的定位机制:普通流、浮动和绝对定位
- 除非专门指定,否则所有框都在普通流中定位。也就是说,普通流中的元素的位置由元素在 (X)HTML 中的位置决定
- 块级框从上到下一个接一个地排列,框之间的垂直距离是由框的垂直外边距计算出来,有可能会合并
- 行内框在一行中水平布置。可以使用水平内边距、边框和外边距调整它们的间距。但是,垂直内边距、边框和外边距不影响行内框的高度
- 由一行形成的水平框称为行框(和行内框不同),行框的高度总是足以容纳它包含的所有行内框。不过,设置行高可以增加这个框的高度
CSS的position属性
- position有五个备选值:static,absolute,fixed,relative,inherit
- static设置元素框正常生成,元素出现在文档流中,忽略top,left,z-index等声明
- relative设置元素相对定位,元素会以它原本的位置为基点,偏移指定的距离。元素仍保持原来的形状,它原本所占的空间仍保留。移动后的元素有可能会和其他元素重叠。
#box_relative {
position: relative;
left: 30px;
top: 20px;
}
- absolute设置元素的绝对定位,元素框从文档流完全删除,并相对于其包含块定位。元素原先在正常文档流中所占的空间会关闭,就好像该元素原来不存在一样。元素定位后生成一个块级框(而不论原来它是何种类型的框)。绝对定位的元素的位置相对于最近的已定位祖先元素,如果元素没有已定位的祖先元素,那么它的位置相对于最初的包含块。
#box_relative {
position: absolute;
left: 30px;
top: 20px;
}
- fixed设置元素的绝对定位,和absolute类似,只是参照的标准时浏览器
- 上述几种定位方式,都有可能引起元素的重叠。z-index可以设置哪个元素在前,哪个在后,这个值越大,离用户的眼睛越近
CSS浮动
浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样。
下图中,左侧三个框是块级框,从上往下依次排列。框1浮动到右侧后,框2和框3位置提升:
当框1又向左浮动时,普通文档流中已经没有它的位置了,它只能和框2重叠。当三个框都向左浮动时,会从左到右依次排列,并不会重叠,因为它们都是浮动框:
当一行容纳不了全部的框时,就会自动换到新行中。但是如果框1高度比框2高,框3会被卡住:
下图显示的是一个普通图片和两段文本。当图片向左浮动时,文本就会环绕在图片的右侧和下方,而且为了给图片流出空间,不至于图片和文本重叠,文本的行框还自行缩短:
要避免这种情况发生,就要用clear属性指定一个框的哪一边不应该靠近浮动框。clear有四个值,分别是left,right, both,none:
这个clear属性可以为被应用的元素(例子中的文本段落)增加上外边距,给浮动元素(图像)流出足够的垂直空间。
因为浮动元素会从正常的文档流中剥离,所以没有容器能框住浮动元素。可以找一个和浮动元素同在一个容器内的元素,对其使用clear,就可以了。如果没有现成的元素可用,就写一个空的<div>, 应用上clear :
.news {
background-color: gray;
border: solid 1px black;
}
.news img { float: left; }
.news p { float: right; }
.clear { clear: both; }
<div class="news">
<img src="news-pic.jpg" />
<p>some text</p>
<div class="clear"></div>
</div>