标记语言——CSS布局

作者:佚名     字体:[增加 减小]    类型:转载
点击这里返回泡泡脚本 HTML教程 栏目.想浏览CSS教程请点这里。 上文:标记语言——打印样式。 Chapter 12 CSS布局 本书到此为止,讨论的主要是页面内部元素,也就是内容,但是大结构怎么办?长久以来,设计者都依赖表格进行分栏
点击这里返回泡泡脚本 HTML教程 栏目.想浏览CSS教程请点这里。 上文:标记语言——打印样式。 Chapter 12 CSS布局 本书到此为止,讨论的主要是页面内部元素,也就是内容,但是大结构怎么办?长久以来,设计者都依赖表格进行分栏布局,常常在表格之内嵌套其他表格以便达成恰巧正确的间隔,视觉效果.这些庞大的排版内容不仅下载很慢,维护起来也很费心力,更别提文字浏览器,屏幕阅读器,小屏幕设备根本无法正确读取了. 在这一章内,将使用四种常见的做法,结合CSS于结构化标记语法制作两栏布局.很快地就会发现,不用嵌套表格,间隔用的GIF也能做出分栏版面布局. 稍后在"技巧延伸"中,将会讨论Windows版Internet Explorer 5.0盒模型的问题,以及绕过它的方法.也将分享一个以CSS达成等宽栏位的简单秘密. 要如何以CSS作出两栏版面布局? 答案是有好几种方法,为了带领你起步,同时帮助你了解两种常见方法的差异(浮动与定位),因此先把焦点放在四种不同的方法上,在此每一种方法都能做出两栏布局,同时具备页首和页尾. 我的愿望是:你能以本章作为指引开始构建一个网站,并发挥本书其他章节之内的方法制作内容. 我们将讨论的四种方法都应用在文档的<body>与</body>标签之间,同时我会在开始讨论每种方法之前介绍将会使用的标记语法结构. 为了让你了解围绕着每种方法的页面结构,让我们大致看一下还需要加入些什么:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> <head> <title>CSS Layouts</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> ...方法示范... </body> </html>
为了让你可以了解要达成的版面配置,请看图12-1:这就是我们想要完成的分栏版面布局. 图12-1 两栏布局的框线图 让我们开始吧!首先介绍第一种方法,它使用float属性. 方法A:浮动侧边栏
div id="header"> ...页头部分... </div> <div id="sidebar"> ...侧边栏部分... </div> <div id="content"> ...主体部分... </div> <div id="footer"> ...页脚部分... </div>
上面就是我们要以CSS的float属性制作成分栏布局的标记源代码,使用<div>标签把页面元素分成几个逻辑段落,每个都设定了唯一的id: #header: 包含标题图片,导航栏等 #sidebar: 包含额外的内容链接与相关资讯 #content: 包含主要的文字内容,也是页面的焦点所在. #footer: 包含版权信息,作者,辅助链接等 把这些页面段落拆开,能让我们能完全控制版面布局,只要指定几条CSS规则,就可以马上完成两栏布局. 为页首与页尾指定样式 要把内容结构转化成分栏布局的第一步,是为页首,页尾加上一点背景颜色以及一点内补丁,这样能使内容更容易凸显出来.
#header { padding: 20px; background: #ccc; } #footer { padding: 20px; background: #eee; }
为方法A的结构加上前面这段CSS会使它显示成图12-2这样,我为各个段落加了一些假象的内容. 图12-2 为页首,页尾指定样式 当然,在#header与#footer里,可以继续为这些段落指定适当的样式,像是font-family,color,链接色彩等等.现在让我们把两栏版面制造出来. 浮动侧边栏 方法A的精华,在于它以float属性把#sidebar放到主要内容<div>的任一边去.以这个例子来说,将它放到内容的右侧,但是放到另一侧当然也行. 浮动#sidebar的关键在于,在标记源代码中,必须出现在主内容<div>之前,这样一来,侧边栏的顶部就会与主内容的顶部排齐. 接着,为#sidebar加上float属性,同时把它的宽度设为30%,指定背景颜色:
#header { padding: 20px; background: #ccc; } #sidebar { float: right; width: 30%; background: #999; } #footer { padding: 20px; background: #eee; }
图12-3是加上这段CSS之后的显示效果,能看到侧边栏跑到右边去了,而主要内容在侧边栏范围之内流动. 图12-3 把#sidebar浮动到主要内容的右侧 真正的栏位 看看图12-3,我们还没有真正完成两栏布局,为了完成这个效果还必须取#content这个<div>,指定与忧侧边栏宽度相同的右外补丁,因此产生放置#sidebar的空间. 需要加上的CSS就是这么简单:
#header { padding: 20px; background: #ccc; } #sidebar { float: right; width: 30%; background: #999; } #content { margin-right: 34%; } #footer { clear: right; padding: 20px; background: #eee; }
我们会发现,我们给content设定的右外补丁大小比#sidebar还大4%,如此能在两栏之间留下一点空位.图12-4是以浏览器查看的效果,你可以发现只要为<div>设定右外补丁,就能造出第二栏的假象. 图12-4 两栏布局 同时要留意的是对#footer所加上的clear:right规则,这个规则很重要,能确保页尾一定会出现在侧边栏和内容区之后,而不受两栏的长度变动影响,页尾会避开任何先前出现的float内容. 现在有了能使用的两栏布局,可以继续为现在的CSS声明加上更多边界,背景,边框与其他元素,使外观更吸引人. 至今为止我们都以百分比设定宽度,以便造出灵活的布局(栏宽会自动随着使用者的视窗宽度缩放).我们也能以像素单位造出定宽布局,但是以像素指定内外补丁大小时,必须注意IE for Windows错误解析CSS盒模型的问题,你能在本章的"盒模型问题"找到更多信息以及能用的解决方法. 方法B:双重浮动
<div id="header"> ...header content here... </div> <div id="content"> ...main content here... </div> <div id="sidebar"> ...sidebar content here... </div> <div id="footer"> ...footer content here... </div>
方法A的缺点之一是:为了浮动侧边栏,则必须在标记源代码之内把侧边栏放到主内容<div>的前面,关闭CSS的浏览器,文字浏览器,屏幕阅读器与其他不支持CSS的设备将会在页面主要内容之前显示(或念出)侧边栏的内容.这样实在不严谨. 我们可以利用float做法,并避开这个问题,只要交换标记源代码里的主内容,侧边栏<div>的位置(如上所示),然后以CSS将两者浮动到不同边即可.
#header { padding: 20px; background: #ccc; } #content { float: left; width: 66%; } #sidebar { float: right; width: 30%; background: #999; } #footer { clear: both; padding: 20px; background: #eee; }
通过把两个<div>浮动到不同方向,就能以最恰当的方式排列源代码(主内容放在侧边栏前面),同时仍能得到图12-4这样的效果. 避开两边 同样重要的是,你必须将#footerdeclear属性设为both,如此一来不管两栏的长度多长,页尾总是显示在最后,而标签源代码的内容顺序也改善了. 方法C:浮动主内容
<div id="header"> ...页头内容... </div> <div id="content"> ...主内容... </div> <div id="sidebar"> ...侧边栏... </div> <div id="footer"> ...页尾内容... </div>
还有个值得一提的方法,只需要用一个float属性,同时标记源代码仍然可以将主内容的<div>放在侧边栏之前. 只要将主内容的<div>浮动到左侧,并且为它设定小于100%的宽度,如此一来就能在右侧留下足够空间摆放侧边栏. CSS内容 方法C需要的CSS内容再简单不过了,"一个float属性",内容区希望使用的宽度,以及两栏之间留下的小边界.
#header { padding: 20px; background: #ccc; } #content { float: left; width: 66%; } #sidebar { background: #999; } #footer { clear: left; padding: 20px; background: #eee; }
请注意我们并不需要定义侧边栏的宽度,因为它会自动填满主内容<div>用剩下的空间(在这个例子中是34%). 悲惨的背景 图12-5就是以浏览器查看的成果,哦喔!在某些常用浏览器里,侧边栏的背景颜色会出现在主内容区底下,由于侧边栏并未制定宽度,因此它想扩到与浏览器视窗一样宽. 图12-5 浮动内容,但是侧边栏的背景颜色透了出来 这个部分只要我们能在侧边栏左边加上宽度与内容区相同的外边界便可以避开这个问题.实际上我们会把外补丁设的稍微大一点,以便在两栏之间留下一点空白.
#header { padding: 20px; background: #ccc; } #content { float: left; width: 66%; } #sidebar { margin-left: 70%; background: #999; } #footer { clear: left; padding: 20px; background: #eee; }
简单朴素 或者是,如果涉及不需要用到背景色的话,那就不必设定边界了,图12-6是去掉整个#sidebar声明,在为主内容<div>加上一点右外补丁之后的结果.此时两栏会共用页面预设的背景色. 图12-6 不使用背景色的浮动内容 CSS则能缩减成:
#header { padding: 20px; background: #ccc; } #content { float: left; width: 66%; margin-right: 6%; } #footer { clear: left; padding: 20px; background: #eee; }
除了加上左外补丁(或是省去背景色)之外,还有个使用背景图片的替代做法能让分栏具备背景色彩,我稍后会在本章的"技巧延伸 "单元里提示这个小秘密. 除了使用float属性之外,也能用定位制造出分栏布局,让我们看看最后一个选择,方法D. 方法D:定位
<div id="header"> ...页首内容... </div> <div id="content"> ...主内容... </div> <div id="sidebar"> ...侧边栏... </div> <div id="footer"> ...页脚内容... </div>
方法D是使用相同的标记源代码结构,然后以最有效率的方式排列<div>:把主内容放在侧边栏之前,关闭样式的浏览器,屏幕阅读器会先收到主内容部分,再收到侧边栏,在定位时,标记源代码内的顺序与页面元素出现的位置没有关系. 能够预测的高度 CSS内容与前三个方法有点类似,第一个差异是对页首指定的像素高度,我们需要能够预测的高度以便稍后为侧边栏定位. 在这里随机选了一个数字,而这需要根据页首使用的内容调整,像是标志,导航栏,搜索表单等.
#header { height: 40px; background: #ccc; } #footer { padding: 20px; background: #eee; }
为各栏留下空间 接着,要为#content这个<div>设定右外补丁,就像前几个方法一样,这能为右侧边栏留下空间,稍后会使用绝对定位法(不是浮动)把右侧边栏放进去.
#header { height: 40px; background: #ccc; } #content { margin-right: 34%; } #footer { padding: 20px; background: #eee; }
放进侧边栏 最后,要使用绝对定位法把#sidebar这个<div>放到#content的边界里,也必须去掉浏览器在页面周围加上的预设边界,如此一来定位座标在所有浏览器之内就会一致了.
body { margin: 0; padding: 0; } #header { height: 40px; background: #ccc; } #content { margin-right: 34%; } #sidebar { position: absolute; top: 40px; right: 0; width: 30%; background: #999; } #footer { padding: 20px; background: #eee; }
在指定position:absolute之后,就能以top与right坐标把#sidebar准确的放到所想的位置(图12-7). 图12-7 以定位做出的两栏布局效果 我们叙述了 "把 #sidebar这个<div>放到距离浏览器视窗上边缘40像素,右边缘0像素的位置",除此之外,也能用bottom和left指定坐标. 页尾问题 以先前的方法浮动分栏时,可以用clear属性确保页尾横跨整个浏览器视窗的宽度,而不受主内容,侧边栏的长度影响. 在定位时,侧边栏的文档流独立于整个页面之外,所以只要侧边栏比内容还长,它就会盖住页尾部分.(图12-8) 图12-8 侧边栏与页尾重叠 面对这个问题我常用的解决方法之一,是为页尾指定与主内容一样的右外补丁,让侧边栏能够延伸超过页尾. 使用这个方法的话,CSS需要调整成这样:
body { margin: 0; padding: 0; } #header { height: 40px; background: #ccc; } #content { margin-right: 34%; } #sidebar { position: absolute; top: 40px; right: 0; width: 30%; background: #999; } #footer { margin-right: 34%; padding: 20px; background: #eee; }
这个解决方案在内容很短,侧边栏很长的页面上看起来有点怪,但是它的确有效,结果可参照图12-9,示范了侧边栏避开页尾的情况. 图12-9 外补丁和主内容相同的页尾 三人行 如果想做三栏布局的话该怎么办?没问题,而且在使用绝对定位时很容易加入.只需要为主内容,也为加上左外补丁,大小足够容纳第三栏即可. 另一个侧边栏能够放在标记源代码之内任何地方,因为会需要再度使用绝对定位进行布局. 假设加了第二个侧栏,并将它取名# sidecolumn,接着以下面这段CSS为它空出位置,再把它放进去.
body { margin: 0; padding: 0; } #header { height: 40px; background: #ccc; } #content { margin-right: 24%; margin-left: 24%; } #sidecolumn { position: absolute; top: 40px; left: 0; width: 20%; background: #999; } #sidebar { position: absolute; top: 40px; right: 0; width: 20%; background: #999; } #footer { margin-right: 24%; margin-left: 24%; padding: 20px; background: #eee; }
刚才完成的部分是在主内容,页尾区空出左外补丁(避免重叠),与之前做右侧边栏一样,接着以绝对定位法放进新的#sidecolumn ,将它放在距离上边缘40像素,距离左边缘0像素的位置. 你有留意我们稍微修正了宽度以容纳第三栏吗?由于我们使用百分比,因此这个布局会随着浏览器的宽度缩放,或者也可以为任何一栏指定像素宽度,以便使布局宽度固定下来. 图12-10是用浏览器查看这个示例的效果,一份以CSS绝对定位完成的灵活三栏布局. 图12-10 以定位法作出的灵活三栏布局 归纳 我们在这章稍微研究了以CSS规划版面布局是能够达成的效果.本章的目的是提供你发挥的基础,因此示范了两种主要的做法: 浮动和定位. 我希望你能继续深入尝试CSS布局技巧,去掉页面内的嵌套表格,并且换上更多浏览器与设备能读取的灵活的结构化的标记语法. 如果你想知道更多关于CSS版面布局的资讯,那么一定要看看这些资源: "The Layout Reservoir" (http://www.bluerobot.com/web/layouts):这是个使用绝对定位制作多栏排版的绝佳示例. "From Table Hacks to CSS Layout: A Web Designer's Journey" (http://www.alistapart.com/articles/journey/): Jeffrey Zeldman撰写的绝佳教学,记录了建立双栏布局所需的步骤. "CSS Layout Technoques: For Fun and Profit"(http://www.glish.com/css/): Eric Costello的各种CSS布局资源. "Little Boxes" (http://www.thenoodleincident.com/tutorials/box_lesson/boxes/html): Owen Briggs编写的许多CSS布局示例的漂亮界面. "CSS Zen Garden"(http://www.csszengarden.com/): "示范以CSS为基础的设计能达成什么视觉效果". Dave Shea培养的"花园"以单一XHTML文档展示读者投稿的最新CSS设计(当然也包含布局).这是个能看到CSS布局能力极致的神奇网站. 技巧延伸 现在我们经过了建立基本CSS布局的基础,该是讨论Windows版Internet Explorer 5与5.5版,以及它们错误解析CSS盒模型这个不幸问题的时候了.稍后也会分享一个通过平铺背景图片达成等高栏位布局的秘密技巧. 盒模型问题 本章开始的时候我们讨论了建立多栏CSS布局的方法,只用width属性定义每栏的宽度,当你开始为这些栏位加上补丁,边框的时候,事情就变得有些复杂了.为什么? 不幸的是,Internet Explorer 5for Windows在加上内外补丁,边框的时候,无法正确计算外包元素的宽度. 举例来说,除了IE5 for Windows之外,所有支持CSS1的浏览器都会将外包元素的宽度计算为宽度,内补丁,边框三者相加,这是W3C希望所有浏览器处理CSS盒模型的方式. 但是IE5 for Windows会将边框和内补丁算在指定的宽度之内,搞混淆了?不用担心,直接看看问题会对你有所帮助. 眼见为实 比较一下图12-11和12-12,图12-11是个200像素宽的元素,两侧各有10像素的内补丁,以及5像素的边框,把水平部分的数值全加起来,就能知道实际宽度为230像素. 图12-11 盒模型的正确计算结果 图12-12 IE5 for Windows 错误的内补丁,边框,宽度计算结果 这是符合设计的盒模型:width属性总是定义元素的内容范围,而内补丁,边框则会加到这个数值上. 因此,如果将侧边栏的宽度定义成200像素然后加上内补丁和边框,CSS的声明如下:
#sidebar { width: 200px; padding: 10px; border: 5px solid black; }
把宽度设定为200像素,但是侧边栏实际需要230像素的空间,除了IE5 for Windows以外. IE5 for Windows 里侧边栏总共会占用200像素,把内补丁和边框都算在里面. 图12-12 显示的是当width属性指定为200像素时,边框和内补丁会占用内容空间,而不是内容空间之外.