使用CSS进行页面布局的方法

网页设计 everyinch 6872℃ 0评论

一、布局的基本概念

多栏布局有三种基本的实现方案:固定宽度、流动、弹性。

  •  固定宽度布局的大小不会随用户调整浏览器窗口大小而变化,一般是900 到1100像素宽。其中960 像素是最常见的,因为能够被16、12、10、8、6、5、4 和3 整除,不仅容易计算等宽分栏的数量,而且计算结果也能得到没有小数的像素数。流行的CSS 布局框架960 Grid(http://www.960.gs),就是基于960 像素宽的网格创建的
  •  流动布局的大小会随用户调整浏览器窗口大小而变化。这种布局能够更好地适应大屏幕,但同时也意味着放弃对页面某些方面的控制,比如随着页面宽度变化,文本行的长度和页面元素之间的位置关系都可能变化。今天,越来越多的浏览器都支持CSS 媒体查询了。这就让基于浏览器窗口宽度提供不同的CSS 样式成为可能。在这种形势下,适应各种屏幕宽度的可变固定布局,正逐步取代流动布局。这种可变的固定布局能够适应最大和最小的屏幕,业界称之为响应式设计
  •  弹性布局与流动布局类似,在浏览器窗口变宽时,不仅布局变宽,而且所有内容元素的大小也会变化,让人产生一种所有东西都变大了的感觉。到目前为止,还没见过设计得非常好的弹性布局,主要是因为它太过复杂了

布局高度与布局宽度:多数情况下,布局中结构化元素(乃至任何元素)的高度是不必设定的。与高度不同,需要精细地控制布局宽度。

二、三栏——固定宽度的布局

从一个简单的居中的单栏固定布局开始。

<div id="wrapper">
	<article>
		<! -- 这里是一些文本元素 -->
	</article>
</div>

布局相关的CSS 如下:

#wrapper {width:960px; margin:0 auto; border:1px solid;}
article {background:#ffed53;}

ch5_layout1

下面,再向外包装里添加一个导航元素,让它作为第二栏:

<div id="wrapper">
	<nav>
		<!-- 无序列表 -->
	</nav>
	<article>
		<! -- 文本 -->
	</article>
</div>
#wrapper {width:960px; margin:0 auto; border:1px solid;}
nav {
	width:150px;
	float:left;
}
nav li {
	/*去掉列表项目符号*/
	list-style-type:none;
}
article {
	width:810px;
	float:left;
	background:#ffed53;
}

ch5_layout2

采用同样的方法,可以添加第三栏(或任意多个栏)。

<div id="wrapper">
	<nav>
		<!-- 无序列表 -->
	</nav>
	<article>
		<! -- 文本 -->
	</article>
	<aside>
		<! -- 文本 -->
	</aside>
</div>
#wrapper {width:960px; margin:0 auto; border:1px solid;}
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;
}

ch5_layout3

接下来添加页眉和页脚:

<div id="wrapper">
	<header>
		<!-- 标题 -->
	</header>
	<nav>
		<!-- 无序列表 -->
	</nav>
	<article>
		<! -- 文本 -->
	</article>
	<aside>
		<! -- 文本 -->
	</aside>
	<footer>
		<!-- 文本 -->
	</footer>
</div>

我们希望页眉和页脚与布局同宽,而且它们默认就与布局同宽,在此只简单地为它们设定了背景色,以便能看到它们在哪儿。

header {background:#f00;}
footer {background:#000;}

ch5_layout4

到目前为止,为HTML 标记应用的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;}

目前布局中的两个主要问题。首先,内容与各栏边界紧挨在一起,太拥挤;其次,每栏高度由文本多少决定,而如果每栏都与布局一样高则更好。

为栏设定内边距和边框

只要一调整各栏中的内容,布局就可能超过容器宽度,而右边的栏就可能滑到左边的栏下方。一般来说,两种情况下可能会发生这种问题。

  • 为了让内容与栏边界空开距离,为栏添加水平外边距和内边距,或者为了增加栏间距,为栏添加外边距,导致布局宽度增大,进而浮动栏下滑。
  • 在栏中添加大图片,或者没有空格的长字符串(如长URL),也会导致栏宽超过布局宽度。同样,这种情况下右边的栏也会滑到左边的栏下方。

下面就来试试添加内边距,增大内容与栏边界的距离。从中间一栏开始。

article {
	width:600px;
	float:left;
	background:#ffed53;
	padding:10px 20px;
}

ch5_layout5

解决的方法有以下三种:

  • 从设定的元素宽度中减去添加的水平外边距、边框和内边距的宽度和。
  • 在容器内部的元素上添加内边距或外边距。
  • 使用CSS3 的box-sizing 属性切换盒子缩放方式,比如section {box-sizing:border-box;}。 应用box-sizing 属性后,给section 添加边框和内边距都不会增大盒子,相反会导致内容变窄。

1. 重设宽度以抵消内边距和边框

比如给600 像素宽的栏又添加了20 像素的内边距,为了抵消增加的内边距,可以把栏宽减少40 像素而设定为560 像素。这样,右边的栏就能归位。问题在于,每次只要调整内、外边距就要重设布局宽度,有点烦人。

ch5_layout6

2. 给容器内部的元素应用内边距和边框

没有宽度的元素在水平方向上会适应其父元素,其内容会随着外边距、边框和内边距的增加而减少。与其为容器中的元素添加边距,不如在栏中再添加一个没有宽度的div,让它包含所有内容元素,然后再给这个div 应用边框和内边距。

<article>
	<div class="inner">
		<!-- 文本 -->
	</div>
</article>
接下来不仅能给内部div 应用内边距,还能给它应用外边距和边框。
article {
	width:6oopx;
	float:left;
	padding:10px 20px;
	background:#ffed53;
}
article .inner {
	margin:10px;
	border:2px solid red;
	padding:20px;
}

ch5_layout7

总之,由此可以得出一个结论:如果布局中的栏是浮动的,而且都设定了宽度,你就根本不要去动它!要动,就把内容放在内部div 里,动这个div。

接下来我们去掉中间栏的外边距、边框和内边距,给其他两栏也添加内部div,然后只给这三栏加上内边距。

<div id="wrapper">
	<header>
		<!-- header text -->
	</header>
	<nav>
		<div class="inner">
			<ul>
				<!-- 链接 -->
			</ul>
		</div>
	</nav>
	<article>
		<div class="inner">
			<!-- 文本 -->
		</div>
	</article>
	<aside>
		<div class="inner">
			<!-- 文本 -->
		</div>
	</aside>
	<footer>
		<!-- 文本 -->
	</footer>
</div>

接下来我们就利用这个div 为三个栏中的内容创造间距。此外,还居中了页脚中的内容。

nav .inner {padding:10px;}
article .inner {padding:10px 20px;}
aside .inner {padding:10px;}
footer {text-align:center}

ch5_layout8

3. 使用box-sizing:border-box

这是最简单的一个办法。只要在三个浮动的栏的CSS 规则中分别加上box-sizing:border-box 声明,再给栏添加内边距(和边框)就不会导致盒子的宽度变化了。此时,既不用调整栏宽去抵消增加的内边距,也不用使用内部div。添加内边距的结果就是内容收缩。以下就是简洁清晰的没有内部div 的标记。

<div id="wrapper">
	<header>
		<!-- 标题 -->
	</header>
	<nav>
		<ul>
			<!-- 链接 -->
		</ul>
	</nav>
	<article>
		<!-- 文本 -->
	</article>
	<aside>
		<!-- 文本 -->
	</aside>
	<footer>
		<!-- 文本 -->
	</footer>
</div>
而以下就是CSS 规则。
* {margin:0; padding:0;}
#wrapper {width:960px; margin:0 auto; border:1px solid #000;overflow:hidden;}
header {background:#f00;}
nav {
	box-sizing:border-box;
	width:150px;
	float:left;
	background:#dcd9c0;
	padding:10px 10px;
}
/*去掉列表项目符号*/
nav li {list-style-type:none;}
article {
	box-sizing:border-box;
	width:600px;
	float:left;
	background:#ffed53;
	padding:10px 20px;
}
aside {
	box-sizing:border-box;
	width:210px;
	float:left;
	background:#3f7ccf;
	padding:10px 10px;
}
footer {clear:both; background:#000;}

ch5_layout9

三、三栏——固定宽度的布局

实现中栏流动布局有两种方法。一种是在中栏改变大小时使用负外边距定位右栏,另一种是使用CSS3 让栏容器具有类似表格单元的行为。

1. 用负外边距实现

实现三栏布局且让中栏内容区流动(不固定)的核心问题,就是处理右栏的定位,并在中栏内容区大小改变时控制右栏与布局的关系。

Web 开发人员Ryan Brill 给出的解决方案是控制两个外包装(通过ID 值为wrapper)容器的外边距。其中一个wrapper包围所有三栏,另一个wrapper只包围左栏和中栏。

<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;
}

ch5_fluidCenter1

ch5_fluidCenter2

三栏中的右栏是210像素宽。为了给右栏腾出空间,中栏article 元素有一个210 像素的右外边距。包围左栏和中栏的两栏wrapper上有210 像素的负右外边距,会把右栏拉回article 元素右外边距创造的空间内。中栏aticle 元素的宽度是auto,因此它仍然会力求占据浮动左栏剩余的所有空间。一方面中栏article 元素的右外边距在两栏wrapper内为右栏腾出了空间,另一方面两栏wrapper的负右外边距又把右栏拉到了该空间内。

人造栏技术

左栏的背景图片加在了div#main_wrapper 上。右栏的背景图片加在了div#threecolwrap 上,而且让它沿该div 的右侧垂直拼接。中栏的背景色也加在了div#main_wrapper 上,这个背景色实际上是整个布局的背景色。

2. 用CSS单元格实现

表格由三个元素构成。一个表格外包装<table>,包含着表格行

<tr>和表格数据<td>,比如下面这个例子。

<table>
	<tr>
		<td>Cell 1</td>
		<td>Cell 2</td>
		<td>Cell 3</td> </tr>
	<tr>
		<td>Cell 1</td>
		<td>Cell 2</td>
		<td>Cell 3</td> </tr>
</table>

CSS 可以把一个HTML 元素的display 属性设定为table、table-row 和table-cell。通过这种方法可以模拟相应HTML 元素的行为。而通过CSS 把布局中的栏设定为table-cell 有三个好处。

  • 单元格(table-cell)不需要浮动就可以并排显示,而且直接为它们应用内边距也不会破坏布局。
  • 默认情况下,一行中的所有单元格高度相同,因而也不需要人造的等高栏效果了。
  • 任何没有明确设定宽度的栏都是流动的。

 

因此,要实现一个三栏流动中栏布局,只需要以下标记:

<nav><!-- 内容 --></nav>
<article><!-- 内容 --></article>
<aside><!-- 内容 --></aside>

和以下CSS:

nav {display:table-cell; width:150px; padding:10px; background:#dcd9c0;}
article {display:table-cell; padding:10px 20px; background:#ffed53;}
aside {display:table-cell; width:210px; padding:10px; background:#3f7ccf;}

四、多行多栏布局

ch5_fullWidth

这个布局的标记如下。

<div id="container">
	<header>
		<h1>Full-width content</h1>
	</header>
	<nav>
		<p>Navigation menus go here</p>
	</nav>
	<section id="branding">
		<img src="images/grand_canyon.jpg" alt="Grand Canyon" />
	</section><!-- branding 结束 -->
	<section id="feature_area">
		<article>
			<div class="inner">
				<p>Lorem Ipsum text</p>
			</div>
		</article>
		<!-- 省略另外两个 article 元素 -->
	</section><!-- feature_area 结束-->
	<section id="promo_area">
		<article>
			<div class="inner">
				<p>Lorem Ipsum text</p>
			</div>
		</article>
		<!-- 省略另外三个 article 元素 -->
	</section><!-- promo_area 结束-->
	<footer>
		<p>This is the footer.Visit <a href="http://www.everyinch.net">Everyinch.net</a> for more CSS information and updates.</p>
	</footer>
</div>
分享&收藏

转载请注明:陈童的博客 » 使用CSS进行页面布局的方法

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

表情

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

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