揭开CSS3盒模型的秘密

在CSS布局属性中,display属性是一个功能非常丰富的属性,它除了支持inline和block两种基本的盒模型之外,还可以通过指定display为none来隐藏HTML元素,也可以指定inline-block、inline-table、list-item、run-in等盒模型。通过display属性可以对HTML元素进行灵活布局,除了使用display属性控制盒模型之外,CSS3增加了box-shadow属性,允许我们为盒模型元素添加阴影,包括控制阴影的颜色、偏移和模糊度等。

1.盒模型和display属性

HTML元素的盒模型由内容区、内填充、边框、边距、边框和外边距组成。此外,HTML元素还可以包含其他元素,在这种情况下,父元素的内容区将作为子元素的容器(子元素通常只能出现在内容区,不会突破到内填充区),下图显示了父元素和子元素的关系。

HTML组件中呈现一片空白区域的组件都可当成盒模型(box model),比如<div>元素、<span>、<section>等元素。而CSS则提供了display属性来控制盒模型的外观。

1.1 两种最基本的盒类型

就最基本的盒模型组件来说,HTML组件的盒模型可分为两种。

类型描述
 block这种盒模型的组件默认占据一行,允许通过CSS设置宽度、高度。例如<div>、<p>元素。
inline这种盒模型的组件不会占据一行(默认允许在一行放置多个组件),即使通过CSS设置宽度、高度也不会起作用。例如<span>、<a>元素。

下面代码对比了<div>和<span>两个元素的区别。

<!DOCTYPE html>
<html>
<head>
	<meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" />
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title> 盒模型的基本类型 </title>
	<style type="text/css">
		div,span{
			width: 300px;
			height: 40px;
			border: 1px solid black;
		}
	</style>
</head>
<body>
<div>div元素一</div>
<div>div元素二</div>
<span>span元素一</span>
<span>span元素二</span>
</body>
</html>

上面代码中定义了两个<div>元素和两个<span>元素,页面的CSS代码设置了<div>、<span>元素的高度为40px,宽度为300px。但由于<span>元素默认是inline盒模型,因此设置的高度、宽度对它不起作用。使用浏览器浏览,将看到如下图1所示的效果。

CSS为display属性提供了block、inline两个属性值,用于改变HTML组件默认的盒模型。例如,将上面的CSS样式部分改为如下形式。

<!DOCTYPE html>
<html>
<head>
	<meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" />
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title> 盒模型的基本类型 </title>
	<style type="text/css">
		div,span{
			width: 300px;
			height: 40px;
			border: 1px solid black;
		}
		/* 将div元素改为inline盒模型 */
		body>div{
			display:inline;
		}
		/* 将span元素改为block盒模型 */
		body>span{
			display:block;
		}
	</style>
</head>
<body>
<div>div元素一</div>
<div>div元素二</div>
<span>span元素一</span>
<span>span元素二</span>
</body>
</html>

效果图:

1.2 none值和visibility属性

display属性可指定为none值,用于设置目标对象隐藏,一旦该对象隐藏,其占用的页面空间也会释放。与此类似的还有visibility属性,该属性也可用于设置目标对象是否显示。与display属性不同,当通过visibility隐藏某个HTML元素后,该元素占用的页面空间依然会被保留。visibility属性的两个常用值为visible和hidden,分别用于控制目标对象的显示和隐藏。

<!DOCTYPE html>
<html>
<head>
	<meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" />
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title> 隐藏元素 </title>
	<style type="text/css">
	/* 设置div元素的宽度、高度、背景色和边框 */
	div{
		width:300px;
		height:40px;
		background-color:#ddd;
		border:2px solid black;
	}
	</style>
</head>
<body>
<input type="button" value="隐藏" 
	onclick="document.getElementById('test1').style.display='none';"/>
<input type="button" value="显示" 
	onclick="document.getElementById('test1').style.display='';"/>
<div id = "test1">
使用display控制对象的显示和隐藏
</div>
<input type="button" value="隐藏"
	onclick="document.getElementById('test2').style.visibility ='hidden'"/>
<input type="button" value="显示"
	onclick="document.getElementById('test2').style.visibility ='visible'"/>
<div id = "test2">
使用visibility控制对象的显示和隐藏
</div>
<hr/>
</body>
</html>

依次单击页面中的两个隐藏按钮,将看到下方图片的效果。

1.3 inline-block类型的盒模型

CSS还提供了一种inline-block盒模型,通过为display属性设置inline-block即可实现这种盒模型,这种盒模型是inline模型和block模型的综合体:inlineblock盒模型的元素既不会占据一行,同时也支持通过width、height指定宽度及高度。通过使用inline-block盒模型可以非常方便地实现多个<div>元素的并列显示。也就是说,使用inline-block盒模型也可以实现前面介绍的多栏布局。在默认情况下,多个inline-block盒模型的组件将会采用底端对齐的方式,也就是它们的底部将会位于同一条水平线上,这可能不是多栏布局期望的结果。为了让多个inline-block盒模型的组件在顶端对齐,为它们增加vertical-align: top即可。

<!DOCTYPE html>
<html>
<head>
	<meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" />
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title> 多栏布局 </title>
	<style type="text/css">
		div#container {
			width: 960px;
		}
		div>div {
			border: 1px solid #aaf;
			display: inline-block;
			/* 设置HTML元素的width属性包括边框 */
			box-sizing: border-box;
			vertical-align: top;
			padding:5px;
		}
	</style>
</head>
<body>
<div id="container">
<div style="width:220px">
<h2>java</h2>
<ul>
	<li>2019年2月11日&nbsp;1</li>
	<li>2019年2月12日&nbsp;2</li>
	<li>2019年2月13日&nbsp;3</li>
</ul>
</div><div style="width:500px;">
<h2>java语言</h2>
&nbsp;&nbsp;&nbsp;&nbsp; 语法规则和C++相似,但从某种意义上讲,它是由C和C++演变而来,所以C程序设计人员能很容易的掌握java语言的语法。<br/> 
&nbsp;&nbsp;&nbsp;&nbsp; 对C++来说进行了简化和一定的提高,如:使用接口代替了复杂的多重继承以及取消了指针,还通过实现垃圾自动回收机制,大大简化了程序员的资源释放管理工作。
</div><div style="width:240px">
<h2>java的用法</h2>
<ul>
	<li>1.第一步</li>
	<li>2.第二步</li>
	<li>3.第三步</li>
	<li>4.第四步</li>
</ul>
</div>
</div>
</body>
</html>

从上面代码可以看出,如果设置<div>元素采用inline-block盒模型显示,接下来无须使用float属性即可让它们显示在同一行,从而实现多栏布局。

效果图:


除此之外,使用inline-block盒模型也可以非常方便地实现水平菜单。下面代码无须使用JavaScript脚本就实现了一个横向排列的导航菜单。

<!DOCTYPE html>
<html>
<head>
	<meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" />
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title> 导航菜单 </title>
	<style type="text/css">
		body>div{
			text-align: center;
		}
		div>div{
			/* 设置为inline-block盒模型,保证一行显示 */
			display: inline-block;
			border: 1px solid black;
		}
		a {
			text-decoration:none;
			/* 设置为block盒模型,允许设置高度、宽度 */
			display: block;
			width: 120px;
			padding: 10px;
			/* 设置默认背景色 */
			background-color: #eee;
		}
		a:hover {
			/* 设置鼠标悬停时的背景色 */
			background-color: #aaa;
			font-weight: bold;
		}
	</style>
</head>
<body>
<div>
	<div><a href="http://www.baidu.com">百度</a></div>
	<div><a href="http://news.baidu.com">百度新闻</a></div>
	<div><a href="https://map.baidu.com/">百度地图</a></div>
    <div><a href="http://tieba.baidu.com/">百度贴吧</a></div>
</div>
</body>
</html>

上面代码设置了4个子<div>元素显示为inline-block盒模型,这样即可保证这4个子<div>元素在同一行内显示。每个子<div>元素内包含一个超链接,这些超链接以block盒模型显示,它们会占满整个父容器,而且CSS为这些超链接设置了背景色,我们会看到整个<div>都会显示它所包含的超链接的背景色。

效果图:

 

1.4 inline-table类型的盒模型

在默认情况下,<table>元素属于block盒模型,也就是说,该元素默认占据一行:它的左边不允许出现其他内容,它的右边也不允许出现其他内容;该元素也可以通过width、height设置宽度和高度。CSS为<table>元素提供了一个inline-table盒模型,这个盒模型允许表格通过width、height设置宽度和高度,而且允许它的左边、右边出现其他内容。

为了控制表格与前、后内容垂直对齐,可以通过添加vertical-align属性来实现,设置该属性为top,这表明让该表格与前、后内容顶端对齐;设置该属性为bottom,这表明让该表格与前、后内容底端对齐。

<!DOCTYPE html>
<html>
<head>
	<meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" />
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title> inline-table盒模型 </title>
	<style type="text/css">
		td {
			border: 1px solid black;
		}
		table{
			width: 360px;
			border-collapse: collapse;
			/* 设置表格显示为inline-table盒模型 */
			display: inline-table;
			/* 设置顶端对齐 */
			vertical-align: top;
		}
	</style>
</head>
<body>
前面内容
<table style="">
	<tr><td>java</td><td>android</td></tr>
	<tr><td>html</td><td>css</td></tr>
</table>
后面内容
</body>
</html>

该页面设置以inline-table盒模型显示表格,这意味着该表格前、后都可显示内容。在浏览器中浏览,将可以看到下方图片所显示的效果。

1.5 使用table类型的盒模型实现表格

CSS3还为display提供了如下属性值。

属性值描述
table将目标HTML组件显示为表格。
table-caption将目标HTML组件显示为表格标题。
table-cell将目标HTML组件显示为单元格。
table-column将目标HTML组件显示为表格列。
table-column-group将目标HTML组件显示为表格列组。
table-header-group将目标HTML组件显示为表格头部分。
table-footer-group将目标HTML组件显示为表格页脚部分。
table-row将目标HTML组件显示为表格行。
table-row-group将目标HTML组件显示为表格行组。

通过上面这些盒模型,可以使用<div>元素构建表格。

<!DOCTYPE html>
<html>
<head>
	<meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" />
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title> 表格相关的盒模型 </title>
	<style type="text/css">
		div>div {
			display: table-row;
			padding: 10px;
		}
		div>div>div{
			display: table-cell;
			border: 1px solid black;
		}
	</style>
</head>
<body>
<div style="display:table;width:400px;">
	<div style="display:table-caption;">软件开发</div>
	<div>
		<div>java</div>
		<div>android</div>
	</div>
	<div>
		<div>html</div>
		<div>css</div>
	</div>
<div>
</body>
</html>

虽然都是<div>元素,但由于将这些元素的display属性设置为表格相关的盒模型,因此各<div>元素将会组成一个表格。

效果图:

 1.6 list-item类型的盒模型

list-item模型可以将目标组件转换为类似于<ul>的列表元素,也可以同时在元素前面添加列表标志。如下页面将多个<div>元素的display设置为list-item。

<!DOCTYPE html>
<html>
<head>
	<meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" />
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title> list-item </title>
	<style type="text/css">
		/* 设置div以list-item的盒模型显示 */
		div{
			display: list-item;
			list-style-type: square;
			margin-left: 20px;
		}
	</style>
</head>
<body>
<div>java</div>
<div>android</div>
<div>html</div>
</body>
</html>

上面代码设置了3个<div>元素都以list-item盒模型显示,并设置在这些元素的前面添加实心方块。实际上,如果为不同元素添加不同的列表符号,并使用不同的marginleft,就可以通过list-item盒模型实现多级列表的效果。

<!DOCTYPE html>
<html>
<head>
	<meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" />
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title> 多级列表 </title>
	<style type="text/css">
		body>div{
			display: list-item;
			list-style-type: disc ;
			margin-left: 20px;
		}
		div>div{
			display: list-item;
			list-style-type: square;
			margin-left: 40px;
		}
	</style>
</head>
<body>
<div id="div1">
	软件开发
	<div>java</div>
	<div>android</div>
	<div>html</div>
</div>
<div id="div2">
	软件开发
	<div>java</div>
	<div>android</div>
	<div>html</div>
</div>
</body>
</html>

上面页面为<body>所包含的<div>指定使用list-item盒模型,并指定使用实心圆心;为<div>所包含的<div>指定使用list-item盒模型,并指定使用实心方块,并为父、子<div.../>元素设置了不同的margin-left属性,这样即可实现多级列表的效果,如下图所示。

 1.7 run-in类型的盒模型

run-in盒模型有点类似于inline盒模型,run-in盒模型的组件希望显示在它后面的元素内部;如果run-in盒模型的组件后面紧跟一个block盒模型元素,那么run-in盒模型元素将被放入后面的元素中显示。

<!DOCTYPE html>
<html>
<head>
	<meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" />
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title> run-in </title>
	<style type="text/css">
		p, span{
			padding:6px;
		}
	</style>
</head>
<body>
	<span style="display: run-in;border:1px solid black;">display: run-in</span>
	<p style="border:2px solid red;">display:block</p>
	<span style="display: run-in;border:1px solid black;">display: run-in</span>
	<p style="border:2px solid red;display:inline">display:inline</p>	
</body>
</html>

上面代码中定义了两个display为run-in的<span>元素,其中第一个<span>元素的后面紧跟一个display为block的<div>元素,那么第一个<span>将放入这个<div>中显示。

效果图:


可惜的是,到目前为止,Firefox还不支持run-in盒模型;除了Firefox之外,其他浏览器如Opera、Chrome,即使IE8都已经支持run-in盒模型。打开火狐浏览器访问,按Ctrl+Shift+I快捷键开发调式页面,然后开发调试页面的标签查看器。

效果图:

2.对盒添加阴影

CSS3增加了box-shadow属性为盒模型添加阴影,该属性可用于为整个盒模型添加阴影。

2.1 使用box-shadow属性

box-shadow属性可以为所有盒模型的元素整体增加阴影。这是一个复合属性。其语法如下:

box-shadow: h-shadow v-shadow blur spread color inset;

注意:box-shadow属性把一个或多个下拉阴影添加到框上。该属性是一个用逗号分隔阴影的列表,每个阴影由 2-4 个长度值、一个可选的颜色值和一个可选的 inset 关键字来规定。省略长度的值是 0。 

值 说明
h-shadow 必需的。水平阴影的位置。允许负值
v-shadow 必需的。垂直阴影的位置。允许负值
blur 可选。模糊距离
spread 可选。阴影的大小
color 可选。阴影的颜色。在CSS颜色值寻找颜色值的完整列表
inset 可选。从外层的阴影(开始时)改变阴影内侧阴影

实例: 

<!DOCTYPE html>
<html>
<head>
	<meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" />
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title> box-shadow属性 </title>
	<style type="text/css">
		div {
			width: 300px;
			height: 50px;
			border: 1px solid black;
			margin: 30px;
		}
	</style>
</head>
<body>
<div style="box-shadow: -10px -8px 6px #444;">
	box-shadow: -10px -8px 6px #444;(左上阴影)</div>
<div style="box-shadow: 10px -8px 6px #444;">
	box-shadow: -10px 8px 6px #444;(右上阴影)</div>
<div style="box-shadow: -10px 8px 6px #444;">
	box-shadow: -10px 8px 6px #444;(左下阴影)</div>
<div style="box-shadow: 10px 8px 6px #444;">
	box-shadow: 10px 8px 6px #444;(右下阴影)</div>
<div style="box-shadow: 10px 8px #444;">
	box-shadow: box-shadow: 10px 8px #444;(右下阴影,不指定模糊程度)</div>
<div style="box-shadow: 10px 8px 20px #444;">
	box-shadow: 10px 8px 20px #444;(右下阴影、增大模糊程度)</div>
<div style="box-shadow: 10px 8px 10px -10px red;">
	box-shadow: 10px 8px 10px -10px red;(右下阴影、缩小阴影区域)</div>
<div style="box-shadow: 10px 8px 20px 15px red;">
	box-shadow: 10px 8px 20px 15px red;(右下阴影、放大阴影区域)</div>
</body>
</html>

效果图:

box-shadow属性的insert属性值用于控制将阴影显示在元素内部。例如,将上面的代码改为如下代码。

<!DOCTYPE html>
<html>
<head>
	<meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" />
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title> box-shadow属性 </title>
	<style type="text/css">
		div {
			width: 300px;
			height: 50px;
			border: 1px solid black;
			margin: 30px;
		}
	</style>
</head>
<body>
<div style="box-shadow: -10px -8px 6px #444 inset;">
	box-shadow: -10px -8px 6px #444 inset;(左上阴影)</div>
<div style="box-shadow: 10px -8px 6px #444 inset;">
	box-shadow: -10px 8px 6px #444 inset;(右上阴影)</div>
<div style="box-shadow: -10px 8px 6px #444 inset;">
	box-shadow: -10px 8px 6px #444 inset;(左下阴影)</div>
<div style="box-shadow: 10px 8px 6px #444 inset;">
	box-shadow: 10px 8px 6px #444 inset;(右下阴影)</div>
<div style="box-shadow: 10px 8px #444 inset;">
	box-shadow: box-shadow: 10px 8px #444 inset;(右下阴影,不指定模糊程度)</div>
<div style="box-shadow: 10px 8px 20px #444 inset;">
	box-shadow: 10px 8px 20px #444 inset;(右下阴影、增大模糊程度)</div>
<div style="box-shadow: 10px 8px 10px -10px red inset;">
	box-shadow: 10px 8px 10px -10px red inset;(右下阴影、缩小阴影区域)</div>
<div style="box-shadow: 10px 8px 20px 15px red inset;">
	box-shadow: 10px 8px 20px 15px red inset;(右下阴影、放大阴影区域)</div>
</body>
</html>

效果图:

2.2 对表格及单元格添加阴影

通过box-shadow属性也可以为表格、单元格添加阴影,例如如下面的代码所示。

<!DOCTYPE html>
<html>
<head>
	<meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" />
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title> box-shadow属性 </title>
	<style type="text/css">
		table {
			width: 500px;
			border-spacing: 10px;
			box-shadow: 10px 10px 6px #444; 
		}
		td {
			box-shadow: 6px 6px 4px #444; 
			padding: 5px;
		}
	</style>
</head>
<body>
<table>
	<tr>
		<td>java</td>
		<td>android</td>
	</tr>
	<tr>
		<td>html</td>
		<td>css</td>
	</tr>
</table>
</html>

上面的代码使用box-shadow属性为表格、单元格指定了阴影。

效果图:

 

------------如果大家喜欢湮顾千古的博客,可以点击左上角的关注哦。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值