使用CSS定位元素

网页设计 everyinch 5139℃ 0评论

学习盒模型,还有position 和display 属性,以及如何浮动(float)和清除(clear)元素。

一、理解盒子模型

每一个元素都会在页面上生成一个盒子。默认情况下,每个盒子的边框不可见,背景也是透明的,所以不能直接看到页面中盒子的结构。盒子属性包括:

  • 边框(border)。可以设置边框的宽窄、样式和颜色。
  • 内边距(padding)。可以设置盒子内容区与边框的间距。
  • 外边距(margin)。可以设置盒子与相邻元素的间距。

ch3_box

1. 盒子边框

边框(border)有3 个相关属性。

  • 宽度(border-width)。可以使用thin、medium 和thick 等文本值,也可以使用除百分比和负值之外的任何绝对值
  • 样式(border-style)。有none、hidden、dotted、dashed、solid、double、groove、ridge、inset 和outset 等文本值
  • 颜色(border-color)。可以使用任意颜色值,包括RGB、HSL、十六进制颜色值和颜色关键字

2. 盒子内边距

内边距是盒子内容区与盒子边框之间的距离。

p {font:16px helvetica, arial, sans-serif; width:220px; border:2px solid red; background-color: #caebff;}

ch3_padding1

p {font:16px helvetica, arial, sans-serif; width:220px;border:2px solid red; background-color: #caebff; padding:10px;}

ch3_padding2

3. 盒子外边距

有三组标题和段落。第一组标题和两个段落使用默认样式。第二组与第一组唯一的区别就是多了边框,但因此也可以看清标题与段落间的外边距有多大。第三组展示了把外边距设置为零之后的效果,该组的标题和段落全都紧挨在一起了。

ch3_margin1

垂直方向上的外边距会叠加。

p {height:50px; border:1px solid #000; backgroundcolor:#fff; margin-top:50px; margin-bottom:30px;}

ch3_margin2

第二段与第一段和第三段的垂直外边距是50像素,而不是80像素。因为像这样上下外边距相遇时,它们就会相互重叠,直至一个外边距碰到另一个元素的边框。就上面的例子而言,第二段较宽的上外边距会碰到第一段的边框。也就是说,较宽的外边距决定两个元素最终离多远。

二、盒子有多大?

首先,谈一谈设定盒子的宽度,因为控制元素的宽度是创建多栏布局的头等大事。一开始我们会看到给没有宽度的元素添加边框、内边距和外边距的效果,然后再看看通过CSS 给它设置了宽度之后,它的行为有什么不一样。

1. 没有宽度的盒子

所谓“没有宽度”就是指没有显式地设置元素的width 属性。如果不设置块级元素的width 属性,那么这个属性的默认值是auto,结果会让元素的宽度扩展到与父元素同宽。

<body>
<p>This element's width property is not set…</p>
</body>

配合以下的CSS:

body {font-family:helvetica, arial, sans-serif; font-size:1em; margin:0px;
background-color:#caebff;}
p {margin:0; background-color:#fff;}

在没有边框、内边距,也没有外边距的情况下,段落的文本扩展到了与body 元素同宽。

ch3_noWidthBox1

接下来用内边距给文本两侧添加一些空白,

p {margin:0; background-color:#fff; padding:0 20px;}

添加了内边距后,文本块的宽度变成了360 像素

ch3_noWidthBox2

接下来,我们再给段落左右两边各添加6 像素宽的边框。为两边各添加6 像素的边框和20 像素的内边距后,内容区变成了348 像素。

p {margin:0; background-color:#fff; padding:0 20px; border:solid red; border-width:0 6px 0 6px;}

ch3_noWidthBox3

最后,再给左右两边各加一些外边距

p {margin:0 30px; background-color:#fff; padding:0 20px; border:solid red; border-width:0 6px 0 6px;}

外边距在元素盒子与窗口之间创造了空白,此时内容宽度变成了288 像素(400 – ( (20 + 6 + 30)× 2))。

ch3_noWidthBox4

盒子模型结论一:没有(就是没有设置width 的)宽度的元素始终会扩展到填满其父元素的宽度为止。添加水平边框、内边距和外边距,会导致内容宽度减少,减少量等于水平边框、内边距和外边距的和。

2. 有宽度的盒子

但这一次先用CSS 声明元素的宽度。这一次,段落有了固定的宽度400 像素。在没有内边距的情况下,内容区也是声明的宽度,因此文本与盒子接触。

p {width:400px; background-color:#fff; margin:0;}

ch3_hasWidthBox1

下面给这个元素添加20 像素的内边距:

p {width:400px; background-color:#fff; margin:0; padding:0 20px;}

在给盒子设定宽度后,添加内边距会导致元素比原来宽了40 像素:

ch3_hasWidthBox2

再给盒子两边各添加6 像素的边框

p {width:400px; background-color:#fff; margin:0;padding:0 20px; border:solid red; border-width:0 6px 0 6px;}

盒子比刚才又宽了12 像素。现在,原来400 像素宽的盒子变成了452 像素(6 + 20 + 400 + 20 + 6 = 452)。

ch3_hasWidthBox3

最后,再给元素左、右两边添加一些外边距

p {width:400px; background-color:#fff; margin:0 30px; padding:0 20px; border:solid red; border-width:0 6px 0 6px;}

ch3_hasWidthBox4

添加的这30 像素外边距,进一步增大了元素占据的空间,目前总宽度已达到512 像素(30 + 6 + 20 + 400 + 20 + 6 + 30 = 512)。

盒模型结论二:为设定了宽度的盒子添加边框、内边距和外边距,会导致盒子扩展得更宽。实际上,盒子的width 属性设定的只是盒子内容区的宽度,而非盒子要占据的水平宽度。

三、浮动与清除

浮动就是使元素脱离常规文档流。作用:一是可以实现传统出版物上那种文字绕排图片的效果,二是可以让原来上下堆叠的块级元素,变成左右并列,从而实现布局中的分栏。

浮动元素脱离了常规文档流之后,原来紧跟其后的元素就会在空间允许的情况下,向上提升到与浮动元素平起平坐。

如果浮动元素后面有两个段落,而你只想让第一段与浮动元素并列,怎么办?用clear 属性来“清除”第二段,然后它就乖乖地呆在浮动元素下面了。

1. 浮动

(1)文本绕排图片

为了实现文本绕排图片的浮动效果,必须在标记中先写图片,然后再写环绕它的文本。

<img …… />
<p>…the paragraph text…</p>

CSS 规则如下。

p {margin:0; border:1px solid red;}
img {float:left; margin:0 4px 4px 0;}

ch3_float1

(2)创建分栏

在此基础上创建多栏,只要再用一次float属性。

p {float:left; margin:0; width:200px; border:1px solid red;}
img {float:left; margin:0 4px 4px 0;}

ch3_float2

2. 围住浮动元素的三种方法

为了演示浮动元素的行为,这种行为对布局会产生什么影响,以及解决这个问题的三种方法,我们首先要从一张带标题的图片开始。图片和标签包含在一个section元素中,而section 元素后面跟着一个footer 元素。

<section>
	<img src="images/rubber_duck2.jpg">
	<p>It's fun to float.</p>
</section>
<footer> Here is the footer element that runs across the bottom of the page.</footer>

相应的CSS如下:

section {border:1px solid blue; margin:0 0 10px 0;}
p {margin 0;}
footer {border:1px solid red;}

ch3_enclose1

假设想让图片标题位于图片右侧,而不是像现在这样位于下方。运用刚刚学到的知识,实现这个目标最简单的方式就是浮动图片。

section {border:1px solid blue; margin:0 0 10px 0;}
img {float:left;}
footer {border:1px solid red;}

浮动图片后标题跑到了右边,但父元素section 也收缩到只包含文本的高度。于是,footer 被提了上来,紧挨着前一个块级元素——section。

ch3_enclose2

方法一:为父元素添加overflow:hidden

section {border:1px solid blue; margin:0 0 10px 0; overflow:hidden;}
img {float:left;}
p {border:1px solid red;}

overflow:hidden 的主要作用是隐藏超出范围的内容;它还有另一个作用,即它能可靠地迫使父元素包含其浮动的子元素。

ch3_enclose3

方法二:同时浮动父元素

第二种促使父元素包围其浮动子元素的方法,是也让父元素浮动起来。

section {border:1px solid blue; float:left; width:100%;}
img {float:left;}
footer {border:1px solid red; clear:left;}

浮动section 以后,不管其子元素是否浮动,它都会紧紧地包围(也称收缩包裹)住它的子元素。

方法三:添加非浮动的清除元素

第三种强制父元素包含其浮动子元素的方法,就是给父元素的最后添加一个非浮动的子元素,然后清除该子元素。由于包含元素一定会包围非浮动的子元素,而且清除会让这个子元素位于(清除一侧)浮动元素的下方,因此包含元素一定会包含这个子元素——以及前面的浮动元素。在包含元素最后添加子元素作为清除元素的方式有两种。

第一种方式不太理想,也就是简单地在HTML 标记中添加一个子元素,并给它应用clear 属性。由于没有默认的样式,不会引入多余空间,div 元素很适合这个目的。

<section>
	<img src="images/rubber_duck.jpg">
	<p>It's fun to float.</p>
	<div class="clear_me"></div>
</section>
<footer> Here is the footer element…</footer>

在此,为div 添加了一个类,以便于在CSS 中添加它。

section {border:1px solid blue;}
img {float:left;}
.clear_me {clear:left;}
footer {border:1px solid red;}

第二种方式是如果不想添加这个纯表现性元素,可以用CSS来添加这个清除元素。首先,要给section 添加一个类。

<section class="clearfix">
	<img src="images/rubber_duck.jpg">
	<p>It's fun to float.</p>
</section>
<footer> Here is the footer element…</footer>

然后添加如下的CSs:

.clearfix:after {
	content:".";
	display:block;
	height:0;
	visibility:hidden;
	clear:both;
}

做个总结,要想强迫父元素包围其浮动的子元素有三种方式:

  • 为父元素应用overflow:hidden
  • 浮动父元素
  • 在父元素内容的末尾添加非浮动元素,可以直接在标记中加,也可以通过给父元素添加clearfix 类来加(当然,样式表中得需要相应的clearfix 规则)

3. 没有父元素时如何清除

下图展示了一个页面,其中包含6 个元素:3 张图片和介绍它们的3 个文本段落。这个页面布局是通过浮动图片实现的,因此在标记中跟在图片后面的文本会向上走,停靠在浮动图片的右侧。

ch3_withoutContainer1

对应的HTML:

<section>
	<img src="images/rubber_duck3.jpg">
	<p>This text sits next to the image and because the…</p>
	<img src="images/beach_ball.jpg">
	<p>This text is short, so the next image can float up…</p>
	<img src="images/yellow_float.jpg">
	<p>Because the previous image’s text does not…</p>
</section>

相应的CSS 如下:

section {width:300px; border:1px solid red;}
img {float:left; margin:0 4px 4px 0;}
p {margin:0 0 5px 0;}

这里,第二段文字太短了,都没有够到第二张浮动图片的下沿。这就给下一对儿图片/段落向上浮动留出了空间。

这里可以使用clearfix 规则来解决这个问题:

.clearfix:after {
	content:".";
	display:block;
	height:0;
	visibility:hidden;
	clear:both;
}

像这样给每个段落都加上clearfix 类:

<section>
	<img src="images/rubber_duck3.jpg">
	<p class="clearfix">This text sits next to the image and because the…</p>
	<img src="images/beach_ball.jpg">
	<p class="clearfix">This text is short, so the next image can float up…</p>
	<img src="images/yellow_float.jpg">
	<p class="clearfix">Because the previous image's text does not…</p>.
</section>

ch3_withoutContainer2

四、定位

CSS 布局的核心是position 属性,对元素盒子应用这个属性,可以相对于它在常规文档流中的位置重新定位。position 属性有4 个值:static、relative、absolute、fixed,默认值为static。

<p>First Paragraph</p>
<p>Second Paragraph</p>
<p id="specialpara">Third Paragraph (with ID)</p>
<p>Fourth Paragraph</p>

1. 静态定位

在静态定位的情况下,每个元素在处在常规文档流中。它们都是块级元素,所以就会在页面中自上而下地堆叠起来。

ch3_position1

2. 相对定位

设置了它的定位方式是“相对定位”。到底相对哪里定位呢?相对的是它原来在文档流中的位置(或者默认位置)。

p#specialpara {position:relative; top:25px; left:30px;}

ch3_position2

3. 绝对定位

绝对定位会把元素彻底从文档流中拿出来。把relative 改成absolute。

p#specialpara {position:absolute; top:25px; left:30px;}

ch3_position3

4. 固定定位

固定定位元素的定位上下文是视口(浏览器窗口或手持设备的屏幕),因此它不会随页面滚动而移动。

ch3_position4 ch3_position5

5. 定位上下文

把元素的position 属性设定为relative、absolute 或fixed 后,继而可以使用top、right、bottom 和left 属性,相对于另一个元素移动该元素的位置。这里的“另一个元素”,就是该元素的定位上下文。

<body>
	<div id="outer">
		<div id="inner">This is text…</div>
	</div>
</body>

搭配下面的CSS

div#outer {width:250px; margin:50px 40px; border-top:3px solid red;}
div#inner {top:10px; left:20px; background:#ccc;}

ch3_positionContext1

只有将元素的position 属性设定为relative、absolute 或fixed,这个元素的top、right、bottom 和left 属性才会起作用。

div#outer {width:250px; margin:50px 40px; border-top:3px solid red;}
div#inner {position:absolute; top:10px; left:20px; background:#ccc;}

ch3_positionContext2

如果我现在把外部div 的position 属性设定为relative:

div#outer {position:relative; width:250px; margin:50px 40px; border-top:3px solid red;}
div#inner {position:absolute; top:10px; left:20px; background:#ccc;}

这样,绝对定位的内部div 的定位上下文就变成了外部div,此时内部div 的top 和left 属性参照的就是外部div 了。

ch3_positionContext3

五、显示属性

所有元素也都有display 属性。大多数元素display 属性的默认值不是block,就是inline。

  • 块级元素,比如段落、标题、列表等,在浏览器中上下堆叠显示。
  • 行内元素,比如a、span 和img,在浏览器中左右并排显示,只有前一行没有空间时才会显示到下一行。

把块级元素变成行内元素(或者相反)的魔法如下。

/*默认为block*/
p {display:inline;}
/*默认为inline*/
a {display:block;}

display 属性还有一个值有必要提一下,就是none。把元素的display 设定为none,该元素及所有包含在其中的元素,都不会在页面中显示。它们原先占据的所有空间也都会被“回收”,就好像相关的标记根本不存在一样。

六、背景

ch3_background

CSS 规定以下与背景相关属性。

  • background-color
  • background-image
  • background-repeat
  • background-position
  • background-size
  • background-attachment
  • background(简写属性)
  • background-clip、background-origin、background-break(目前尚未得到广泛支持)

背景渐变

渐变分两种,一种线性渐变,一种放射性渐变。线性渐变从元素的一端延伸到另一端,放射性渐变则从元素内一点向四周发散。

下面来看一个简单的线性渐变的例子,HTML 标记如下。

<div class='gradient1'></div>
<div class='gradient2'></div>
<div class='gradient3'></div>
CSS 规则如下。
/*为元素盒子添加样式*/
div {
	height:150px;
	width:200px;
	border:1px solid #ccc;
	float:left;
	margin:16px;
}
/*例1:默认为从上到下*/
.gradient1 {
	background:linear-gradient(#e86a43, #fff);
}
/*例2:从左到右*/
.gradient2 {
	background:linear-gradient(left, #64d1dd, #fff);
}
/*例3:左上到右下*/
.gradient3 {
	background:linear-gradient(-45deg, #e86a43, #fff);
}

例3 声明了-45deg(deg 是“度”),等于把起点从默认的中上设定到了左上。

bg_gradient1

1. 渐变点

渐变点就是渐变方向上的点,可以在这些点上设定颜色和不透明度。通过设定下一个渐变点的颜色值,就可以控制渐变的效果。可以添加任意多个渐变点。渐变点的位置一般使用整个渐变宽度的百分比来表示。

/*例1:50%处有一个渐变点*/
.gradient1 {
	background:linear-gradient(#64d1dd, #fff 50%, #64d1dd);
}
/*例2:20%和80%处有两个渐变点*/
.gradient2 {
	background:linear-gradient(#e86a43 20%, #fff 50%, #e86a43 80%);
}
/*例3:25%、50%、75%处有三个渐变点*/
.gradient3 {
	background:linear-gradient(#64d1dd, #fff 25%, #64d1dd 50%, #fff 75%, #64d1dd);
}
/*例4:为同一个渐变点设定两种颜色可以得到突变效果*/
.gradient4 {
	background:linear-gradient(#e86a43, #fff 25%, #64d1dd 25%, #64d1dd 75%, #fff 75%, #e86a43);
}

bg_gradient2

2. 放射性渐变

.gradient1 {
	background: -webkit-radial-gradient(#fff, #64d1dd, #70aa25);
}
.gradient2 {
	background: -webkit-radial-gradient(circle, #fff, #64d1dd, #e86a43);
}
.gradient3 {
	background: -webkit-radial-gradient(50px 30px, circle, #fff, #64d1dd,#4947ba);
}

bg_gradient3

分享&收藏

转载请注明:陈童的博客 » 使用CSS定位元素

喜欢 (0)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
'; } if( dopt('d_footcode_b') ) echo dopt('d_footcode'); ?>