什么是响应式Web设计?怎样进行?
打造布局结构
当页面所需要适应的不同设备的屏幕尺寸差异过大时,除了图片方面,我们也应该考虑到整个布局结构的响应式调整;我们可以使用独立的样式表,或者更有效的,使用CSS media query。这不会引起多大的麻烦,多数样式设定不会被影响和改变,只有一些特定的元素会通过浮动、宽度和高度等的设置来改变位置。
我们可以使用一个默认主样式表来定义页面的主要结构元素,比如#wrapper、#content、#sidebar、#nav等的默认布局方式,以及一些全局性的配色和字体方案。
我们可以监测页面布局随着不同的浏览环境而产生的变化,如果它们变的过窄过短或是过宽过长,则通过一个子级样式表来继承主样式表的设定,并专门针对某些布局结构进行样式覆写。我们来看下代码示例:
下面的代码可以放在默认主样式表style.css中:
- /* Default styles that will carry to the child style sheet */
- html,body{
- background...
- font...
- color...
- }
- h1,h2,h3{}
- p, blockquote, pre, code, ol, ul{}
- /* Structural elements */
- #wrapper{
- width: 80%;
- margin: 0 auto;
- background: #fff;
- padding: 20px;
- }
- #content{
- width: 54%;
- float: left;
- margin-right: 3%;
- }
- #sidebar-left{
- width: 20%;
- float: left;
- margin-right: 3%;
- } #sidebar-right{
- width: 20%;
- float: left;
- }
下面的代码可以放在子级样式表mobile.css中,专门针对移动设备进行样式覆写:
- #wrapper{
- width: 90%;
- }
- #content{
- width: 100%;
- }
- #sidebar-left{
- width: 100%;
- clear: both;
- /* Additional styling for our new layout */
- border-top: 1px solid #ccc;
- margin-top: 20px;
- }
- #sidebar-right{
- width: 100%;
- clear: both;
- /* Additional styling for our new layout */
- border-top: 1px solid #ccc;
- margin-top: 20px;
- }
大致的视觉效果如下图所示:
Media Queries
CSS3支持CSS2.1所支持的所有媒体类型,例如screen、print、handheld等,同时添加了很多涉及媒体类型的功能属性,包括max-width(最大宽度)、device-width(设备宽度)、orientation(屏幕定向,横屏或竖屏)和color。在CSS3发布之后出现的新玩具,如iPad或Android相关设备,都可以完美的支持这些属性。所以我们可以通过media query为新设备设置独特的样式,而忽略那些不支持CSS3的台式机中的旧浏览器。
在Ethan的文章中,我们能看到一段media query使用实例:
- <link rel="stylesheet" type="text/css" media="screen and (max-device-width: 480px)" href="shetland.css" />
代码本身可以很好的说明工作机制:如果页面通过屏幕呈现(非打印一类),并且屏幕宽度不超过480px,则加载shetland.css样式表。要了解更多关于CSS3媒体新属性的信息,可以参考"The Orientation Media Query"一文。
我们可以创建多个样式表,以适应不同设备类型的宽度范围。Ethan的文章中的"Meet the media query"部分有更多的范例及解释。更有效率的做法是,将多个media queries整合在一个样式表文件中:
- /* Smartphones (portrait and landscape) ----------- */
- @media only screen
- and (min-device-width : 320px)
- and (max-device-width : 480px) {
- /* Styles */
- }
- /* Smartphones (landscape) ----------- */
- @media only screen
- and (min-width : 321px) {
- /* Styles */
- }
- /* Smartphones (portrait) ----------- */
- @media only screen
- and (max-width : 320px) {
- /* Styles */
- }
上面的代码来自于Andy Clark创建的可以兼容各种主流设备的免费模板。这样整合多个media queries于一个样式表文件的方式,与通过media queries调用不同样式表的方式之间的区别与联系,可以参考"Hardboiled CSS3 Media Queries"一文。
CSS3 Media Queries
上面演示的一些代码范例是CSS2.1与CSS3通吃的。现在让我们来看看怎样使用CSS3专有的media queries功能来创建响应式Web设计。其中某些方法在当前就有切实的使用价值,不久的将来则一定会全部派上用场。
min-width和max-width这两个属性很靠谱。通过min-width的设置,我们可以在浏览器窗口或设备屏幕宽度高于这个值的情况下,为页面指定一个特定的样式表;max-width则反之。
下面的几个示例中,我们使用的是将多个media queries整合在单一样式表中进行编码的句法。如前文所述,这样做更加高效,减少请求数量。
- @media screen and (min-width: 600px) {
- .hereIsMyClass {
- width: 30%;
- float: right;
- }
- }
上面代码中定义的类(hereIsMyClass)只有在浏览器或屏幕宽度超过600px时才会有效。
- @media screen and (max-width: 600px) {
- .aClassforSmallScreens {
- clear: both;
- font-size: 1.3em;
- }
- }
而这段代码的作用则相反:aClassforSmallScreens类只有在浏览器或屏幕宽度小于600px时才会有效。
可以看出min-width和max-width可以同时判断设备屏幕尺寸与浏览器实际宽度。有些时候,我们希望通过media queries作用于某种特定的设备,而忽略其上运行的浏览器是否由于没有最大化而在尺寸上与设备屏幕尺寸产生不一致的情况。这时,我们需要使用min-device-width与max-device-width,用来判断设备本身的屏幕尺寸。
- @media screen and (max-device-width: 480px) {
- .classForiPhoneDisplay {
- font-size: 1.2em;
- }
- }
- @media screen and (min-device-width: 768px) {
- .minimumiPadWidth {
- clear: both;
- margin-bottom: 2px solid #ccc;
- }
- }
还有一些其他方法,可以帮我们有效的使用media queries锁定某些指定的设备。可以参考下面两篇出自Thomas Maier的文章:
CSS for iPhone 4 (Retina display)(http://thomasmaier.me/2010/06/css-for-iphone-4-retina-display/)
How To: CSS for the iPad(http://thomasmaier.me/2010/03/howto-css-for-the-ipad/)
对于iPad来说,orientation属性尤其有用。它的值可以是landscape(横屏)或portrait(竖屏)。
- @media screen and (orientation: landscape) {
- .iPadLandscape {
- width: 30%;
- float: right;
- }
- }
- @media screen and (orientation: portrait) {
- .iPadPortrait {
- clear: both;
- }
- }
不幸的是,这个属性目前确实只在iPad上有效。对于其他可以转屏的设备,譬如iPhone,可以使用min-device-width和max-device-width来变通实现;详情可以参考"Determine iPhone orientation using CSS"一文。
我们还可以将上述属性组合使用,来锁定某个屏幕尺寸范围:
- @media screen and (min-width: 800px) and (max-width: 1200px) {
- .classForaMediumScreen {
- background: #cc0000;
- width: 30%;
- float: right;
- }
- }
上面的代码可以作用于浏览器窗口或屏幕宽度在800px至1200px之间的所有设备。
其实,很多设计师和开发者仍会选择使用多个样式表的方式来实现media queries。如果从资源的组织和维护的角度出发,其益处确实高于效率的损耗的话,那么这样做也完全不坏:
- <link rel="stylesheet" media="screen and (max-width: 600px)" href="small.css" />
- <link rel="stylesheet" media="screen and (min-width: 600px)" href="large.css" />
- <link rel="stylesheet" media="print" href="print.css" />
所以呐,凡事没有绝对,最好根据实际情况决定使用media queries的方式。比如,对于iPad,我们可以将多个media queries直接写在一个样式表中。因为iPad用户随时有可能切换屏幕定向,这种情况下,要保证页面在极短的时间内响应屏幕尺寸的调整,我们必须选择效率最高的方式。
JavaScript
JavaScript也是我们的武器之一,特别是当某些旧设备无法完美支持CSS3的media query时,它可以作为后备支援。幸运的是,已经有专门的JS库来帮助旧浏览器(IE 5+,Firefox 1+,Safari 2等)支持CSS3的media queries。使用方法很简单,下载css3-mediaqueries.js并在你的页面中调用它。
而下面的代码则演示了怎样使用简单的几行jQuery代码来检测浏览器宽度,并为不同的情况调用不同的样式表:
- <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
- <script type="text/javascript">
- $(document).ready(function(){
- $(window).bind("resize", resizeWindow);
- function resizeWindow(e){
- var newWindowWidth = $(window).width();
- // If width width is below 600px, switch to the mobile stylesheet
- if(newWindowWidth < 600){
- $("link[rel=stylesheet]").attr({href : "mobile.css"});
- } // Else if width is above 600px, switch to the large stylesheet
- else if(newWindowWidth > 600){
- $("link[rel=stylesheet]").attr({href : "style.css"});
- }
- }
- });
- </script>
类似这样的解决方案还有很多。所以我们要清楚,media queries不是一个绝对唯一的答案,它只是一个以纯CSS方式实现响应式Web设计思路的手段。借助JavaScript,我们则可以实现更多的变化。这篇"Combining Media Queries and JavaScript"向我们展示了JavaScript配合media queries的更多细节信息。
显示或隐藏内容
通过前文的学习,我们已经了解到,对于响应式Web设计,同比例缩减元素尺寸以及调整页面结构布局,是两个重要的方式方法。但是对于页面中的文字内容信息来说,则不能简单的只从"同比缩小"和"调整布局结构"这两方面去处理。对于手机等移动设备来说,在文字内容方面,已经有了很多最佳实践方式和指导原则:简化的导航、更易聚焦的内容、以信息列表代替传统的多行文案内容等。
响应式Web设计的思想,一方面要保证页面元素及布局具有足够的弹性,来兼容各类设备平台和屏幕尺寸;另一方面,则是增强可读性和易用性,帮助用户在任何设备环境中都能更容易的获取最重要的内容信息。
有一条样式代码,我们已经使用了多年:
display: none;
我们可以在一个针对某类小屏幕设备的样式表中使用它来隐藏掉页面中的某些块级元素,也可以使用前文的方法,通过JS判断当前硬件屏幕规格,在小屏幕设备的情况下直接为需要隐藏的元素添加工具类class。比如,对于手机类设备,我们可以隐藏掉大块的文字内容区,而只显示一个简单的导航结构,其中的导航元素可以指向详细内容页面。
注意,不要使用visibility: hidden的方式,因为这只能使元素在视觉上不做呈现;display属性则可帮助我们设置整块内容是否需要被输出。对于移动设备来说,避免这些不必要的资源浪费还是很重要的。我们来看一个简单的示例:
图中上半部分是大屏幕设备所显示的完整页面,下面的则是该页面在小屏幕设备的呈现方式。页面HTML代码如下:
- <p class="sidebar-nav"><a href="#">Left Sidebar Content</a> | <a href="#">Right Sidebar Content</a></p>
- <div id="content">
- <h2>Main Content</h2>
- </div>
- <div id="sidebar-left">
- <h2>A Left Sidebar</h2>
- </div>
- <div id="sidebar-right">
- <h2>A Right Sidebar</h2>
- </div>
下面是默认的主样式表,其中,我们要隐藏掉链接导航部分(sidebar-nav),因为默认样式适用的设备屏幕会足够大,足够显示包括两个侧边栏在内的所有内容。
- #content{
- width: 54%;
- float: left;
- margin-right: 3%;
- }
- #sidebar-left{
- width: 20%;
- float: left;
- margin-right: 3%;
- }
- #sidebar-right{
- width: 20%;
- float: left;
- }
- .sidebar-nav{display: none;}
下面是用于小屏幕移动设备的样式表代码。现在,我们要隐藏掉两个侧边栏,并使sidebar-nav显示出来。借助JavaScript,当用户点击sidebar-nav中的链接时,对应的侧边栏可以恢复显示。当然,触发恢复显示的方式有很多种,即可以通过JS改变侧边栏的display属性值,也可以为其添加额外的布局样式。
- #content{
- width: 100%;
- }
- #sidebar-left{
- display: none;
- }
- #sidebar-right{
- display: none;
- }
- .sidebar-nav{display: inline;}
现在,我们的页面已经可以随着设备和屏幕规格的变更,响应式的做到元素的同比缩放、布局结构的改变、内容的优化调整。特别是对于手机设备,我们还要在实践过程中注意一些该类设备共有的设计指导原则。比如,针对手机设备,使用一个特定的样式,将页面原有的文字导航元素变为更易操作的图标形式。下面的一些文章资源可作参考阅读:
Mobile Web Design Trends For 2009(http://www.smashingmagazine.com/2009/01/13/mobile-web-design-trends-2009/)
7 Usability Guidelines for Websites on Mobile Devices(http://www.webcredible.co.uk/user-friendly-resources/web-usability/mobile-guidelines.shtml)
触屏与鼠标
触屏设备已经成为主流。虽然目前多数触屏设备还是小屏幕类型的产品,比如手机,但是市场上越来越多的大屏幕设备也开始使用触屏技术;且不说iPad一类的平板电脑,就连一些笔记本和台式机也加入了这一行列。比如HP Touchsmart tm2t,即使用传统的键鼠设备,同时也加入了触屏技术。
相比于传统的基于鼠标指针的互动,触屏技术显然带来了截然不同的交互方式与相应的设计规范;两者又有各自所适用的领域。所幸,要使我们的设计方案同时满足这两类设备的规范,并非一件难事,只是有些地方需要注意。比如,触屏设备无法反映CSS定义的hover行为及相应的样式,因为它没有鼠标指针的概念,手指点击就是click行为。所以不要让任何功能依赖于对hover状态的触发。
有兴趣的话,可以读读这篇"Designing for Touchscreen",这里提到的很多建议即有利于改进针对触屏设备的设计方式,同时也不会削弱传统键鼠设备上的用户体验。比如,放在页面右侧的导航列表可以对触屏设备的用户更加友好。因为多数人习惯用右手点击操作,而左手负责握住设备;这样,放在右侧的导航列表即方便右手的点击,又可以避免被握着设备的左手不小心触碰到。而这一点与键鼠设备用户的习惯完全不矛盾。