文档流与页面布局

页面中的每一种元素都有默认的显示方式,它们共同形成了页面的文档流,而页面的版面和布局方法是丰富多样的;本文将讨论关于元素显示、定位和布局相关CSS样式属性。

display属性

display属性定义元素在文档流中的显示方式,如基本的内联和块元素。display属性常用的值包括:

  • none,不显示,就好像元素不存在一样。
  • inline,内联方式,如普通文本和span元素的显示方式,元素会显示在一行,达到容器的宽度时换行显示,但实际并没有换行符。
  • block,块元素。元素总是会从新的一“行”开始,对齐容器的左边界,如p元素、div元素等。
  • inline-block,内联块,与内联方式相似,但又和块元素特点相结合,可以指定水平和垂直方向的样式。

此外,如果需要将表插入到内联的文本流中,可以将表的display属性设置为inline-table;此外,表行(tr)的显示方式是table-row,单元格(th或td)的显示方式是table-cell,一列(col)的显示方式是table-column,列组(colgroup)的显示方式是table-column-group,列表项的显示方式是list-item等等;使用JavaScript代码操作页面元素时,了解元素的实际显示方式是非常重要的。

下面的代码,来看一个内联样式示例。

HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    常规文本
    <span style="width:200px;height:3em;vertical-align:bottom;">格式化文本</span>
    常规文本
</body>
</html>

本例,在两个“常规文本”之间定义了span元素,并设置了宽度、高度和垂直对齐的方式,实际打开页面会发现,这些样式根本不起作用,如下图所示。

内联元素

下面的代码,我们修改span元素的display属性值。

HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    常规文本
    <span style="display:inline-block;width:200px;height:3em;vertical-align:bottom;">格式化文本</span>
    常规文本
</body>
</html>

本例,将span元素的显示方式设置为内联块(inline-block),页面效果如下图所示。

内联块元素

visibility属性

visibility属性设置元素的可见方式,常用属性值包括:

  • visible,可见。
  • hidden,隐藏元素,但保留元素的位置。
  • collapse,用于表格元素中折叠行或列。

下面的代码显示了visibility属性的应用。

HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <style>
        div {
            width:200px;
            height:50px;
            border:1px solid black;
        }
    </style>
</head>
<body>
    <div>div1</div>
    <div style="visibility:hidden;">div2</div>
    <div>div3</div>
</body>
</html>

本例,div2设置为隐藏,但其位置会被保留,页面显示效果如下图所示。

visibility属性应用

如果元素隐藏并且不保留其位置,应将display属性设置为none。

float属性和clear属性

float属性用于指定元素向左或向右浮动的效果,其属性值包括:

  • none,元素默认值,显示为正常文本流。
  • left,向左浮动。
  • right,向右浮动。

clear属性用于清除浮动对当前元素的影响,其属性值包括:

  • both,清除向左和向右浮动影响。
  • left,清除向左浮动影响。
  • right,清除向右浮动影响。

下在的代码演示了页面包含页眉、页脚、内容分为三栏的布局效果。

HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <style>
        header {
            height: 80px;
        }
        footer {
            clear: both;
            text-align: center;
        }
        #content_left{
            float:left;
            width:25%;
            min-width:200px;
            min-height:300px;
            background-color:lightyellow;
        }
        #content_main {
            float:left;
            width:50%;
            min-width:300px;
            min-height:300px;
            background-color:lightblue;
        }
        #content_right {
            float: right;
            width: 25%;
            min-width: 200px;
            min-height: 300px;
            background-color:lightpink;
        }
    </style>
</head>
<body>
    <header><h1>浮动与页面布局</h1></header>
    <div id="content_left">左栏</div>
    <div id="content_main">主要内容</div>
    <div id="content_right">右栏</div>
    <footer>版权所有©</footer>
</body>
</html>

页面显示效果如下图所示。

使用浮动布局

如果页面够宽,如本例达到700像素以上,则显示页面如图中所示,如果页面宽度过小,三栏内容还是会“换行”显示,如下图所示。

页面宽度过小时的浮动布局

如果需要保证三栏内容总是保持在一“行”呢?一个方法是将三栏的宽度按百分比设置,但这个方法在页面宽度过小的情况下会影响浏览效果,而且,如果栏目中的元素宽度过大,还是可以出现“换行”的情况。另一个简单粗暴的方法就是使用表格来布局,如下面的代码。

HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <style>
        header {
            height: 80px;
        }
        footer {
            text-align: center;
        }
        .table_layer{
            width:100%;
            min-height:300px;
        }
        .table_layer tr td{
            vertical-align:top;
        }
        .content_left {
            min-width: 200px;
            background-color: lightyellow;
        }
        .content_main {
            min-width:300px;
            background-color:lightblue;
        }
        .content_right {
            min-width: 200px;
            background-color:lightpink;
        }
    </style>
</head>
<body>
    <header><h1>表格与页面布局</h1></header>
    <table class="table_layer">
        <tr>
            <td class="content_left">左栏</td>
            <td class="content_main">主要内容</td>
            <td class="content_right">右栏</td>
        </tr>
    </table>
    <footer>版权所有©</footer>
</body>
</html>

页面显示效果如下图所示。

使用表格布局

本例,无论如何缩放页面,三栏内容都在在一“行”显示,如果浏览器宽度过小,会显示水平方向的滚动条;对用户操作来讲,可以保持浏览布局的直观性和连续性。

工作中,页面效果可以综合考虑技术特点和实际需要来实现。

position属性

position属性设置元素的定位方式,其常用属性值包括:

  • static,静态定位,元素的默认定位方式。
  • relative,相对定位。可以使用top、bottom、left和right属性指定元素相对于它本身原始位置的相对距离。
  • absolute,绝对定位。可以使用top、left属性确定元素左上角相对于其容器左上角的偏移位置。此外,使用绝对定位的元素的容器元素不能是static定位。
  • fixed,固定定位。以浏览器或标签可见区域作为容器,可以使用top、bottom、left和right属性设置相对于容器边界的距离。

下面的代码,我们修改前例中header元素和布局表格(table_layer)的样式定义。

HTML
        header {
            height: 80px;
            position:fixed;
            left:0px;
            top:0px;
        }
        .table_layer{
            margin-top:80px;
            width:100%;
            min-height:300px;
        }

此时,header元素会保持在body元素中的固定位置,通过垂直滚动条移动页面内容时,header元素会一直显示在顶部,而不会向上滚动,效果如下图所示。

固定定位

修改元素的定位操作,除了页眉设置,其它常见应用还包括广告、弹出的公告和通知等。如下面的代码演示了在页面打开时会显示一个通知窗口。

HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <style>
        header {
            height: 80px;
            position:fixed;
            left:0px;
            top:0px;
        }
        .table_layer{
            margin-top:80px;
            width:100%;
            min-height:300px;
        }
        footer {
            text-align: center;
        }        .table_layer tr td{
            vertical-align:top;
        }
        .content_left {
            min-width: 200px;
            background-color: lightyellow;
        }
        .content_main {
            min-width:300px;
            background-color:lightblue;
        }
        .content_right {
            min-width: 200px;
            background-color:lightpink;
        }
        #notice {
            width: 400px;
            padding:1em;
            border-radius: 30px;
            text-align: center;
            background-color: lightgrey;
            display: block;
            position:fixed;
            left:100px;
            top:100px;
            z-index:999999;
        }
    </style>
</head>
<body>
    <header><h1>表格与页面布局</h1></header>
    <table class="table_layer">
        <tr>
            <td class="content_left">左栏</td>
            <td class="content_main">主要内容</td>
            <td class="content_right">右栏</td>
        </tr>
    </table>
    <footer>版权所有©</footer>
    <div id="notice">
        <div id="message">
            <p>下午15点,全体人员A会议室开会!</p>
        </div>
        <div id="bar">
            <input type="button" value="关闭" onclick="notice.style.display='none';" />
        </div>
    </div>
</body>
</html>

代码中可以着重关注元素notice的样式设置,其中z-index属性指定元素在重叠时的位置,数值越大越靠上。关闭按钮的onclick事件中使用JavaScript代码将notice元素的display属性设置为none,即实现元素的关闭功能。页面显示效果如下图所示。

通过定位显示通知

实际应用中,通知内容可以在服务器端动态管理和更新,在客户端则可以使用JavaScript代码实现更多功能和显示效果。

overflow属性

overflow属性可以指定当内容大于其容器时的处理方法,常用属性值包括:

  • visible,默认值,超出容器的内容会显示在容器元素的外面。
  • auto,自动处理。
  • scroll,显示滚动条。
  • hidden,隐藏溢出的内容。

下图显示了四个属性值的处理效果。

overflow属性设置效果

shape-outside属性

页面中,元素的基本形状是矩形,而通过shape-outside属性可以改变元素处理的形状,下面详细讨论。

如果在页面中使用包含透明度的图片,如PNG图片,可以使用url()函数指定图片位置,并使用图片非透明的内容作为处理元素的边界;此时,还可以通过shape-image-threshold属性设置一个透明度的阈值,取值从0(完全透明)到1(完全不透明)。下面的代码演示了如何使用图片的非透明部分作为元素处理的边界。

HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <p>
        <img src="circle.png" align="left" style="width:200px;shape-outside:url(circle.png);" />
        地球(Earth)是太阳系的第三颗行星,从内到外分别是地核(又分为外
        地核和内地核,其中外地核产生地磁场)、地幔、地壳,表面陆地面积约占29.2%
        为,海洋等面积占70.8%。地球大约诞生于45.4亿年前,42亿年前形成海洋,40亿
        年前形成稳定固态地壳。约35亿年前生命在深海出现,逐步扩散到浅海和陆地,当
        前已记录的物种约120万种。地球绕太阳公转一周需365.25天,自转轴倾斜产生季
        节变化。半径约6371千米。地球唯一的天然卫星是月球,两者的引力相互作用引起
        潮汐并稳定地球自转。
    </p>
</body>
</html>

本例使用的circle.png图片,除了蓝色的图形,其它部分为透明,应用效果如下图所示。

使用图片定义边界

除了使用包含透明度的图片定义元素的处理边界,还可以使用图形函数定义边界,如:

  • circle()函数,定义圆形的元素边界,参数格式为“<半径> at <圆心坐标>”。
  • ellipse()函数,定义椭圆形的元素边界,参数格式为“<X轴半径> <Y轴半径> at <中心坐标>”。
  • polygon()函数,定义多边形的元素边界,参数格式为“x1 y1,x2 y2,x3 y3,...”,即使用多组坐标定义多边形的顶点。

下面的代码演示了如何定义一个菱形边界。

HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <p>
        <img src="circle.png" align="left"
             style="width: 200px; shape-outside:polygon(0px 100px,100px 50px,200px 100px,100px 150px);" />
        地球(Earth)是太阳系的第三颗行星,从内到外分别是地核(又分为外
        地核和内地核,其中外地核产生地磁场)、地幔、地壳,表面陆地面积约占29.2%
        为,海洋等面积占70.8%。地球大约诞生于45.4亿年前,42亿年前形成海洋,40亿
        年前形成稳定固态地壳。约35亿年前生命在深海出现,逐步扩散到浅海和陆地,当
        前已记录的物种约120万种。地球绕太阳公转一周需365.25天,自转轴倾斜产生季
        节变化。半径约6371千米。地球唯一的天然卫星是月球,两者的引力相互作用引起
        潮汐并稳定地球自转。
    </p>
</body>
</html>

页面显示效果如下图所示。

使用图形边界

inset()函数设置图形内部的矩形区域,参数的第一部分为四个方向距离图形原始边界的距离,类似padding属性的设置。设置方式包括:

  • 四个参数,分别设置上、右、下、左方向的距离。
  • 三个参数,分别设置上、右、下方向距离,左边与右边距离相同。
  • 两个参数,分别设置上、右方向距离,左边与右边距离相同,下边与上边距离相同。
  • 一个参数,同时设置四个方向的距离。

在距离设置后,还可以使用round关键字指定四个角的圆角半径。下面的代码演示了相关应用。

HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <p>
        <img src="circle.png" align="left"
             style="width: 200px; shape-outside:inset(50px round 50px);" />
        地球(Earth)是太阳系的第三颗行星,从内到外分别是地核(又分为外
        地核和内地核,其中外地核产生地磁场)、地幔、地壳,表面陆地面积约占29.2%
        为,海洋等面积占70.8%。地球大约诞生于45.4亿年前,42亿年前形成海洋,40亿
        年前形成稳定固态地壳。约35亿年前生命在深海出现,逐步扩散到浅海和陆地,当
        前已记录的物种约120万种。地球绕太阳公转一周需365.25天,自转轴倾斜产生季
        节变化。半径约6371千米。地球唯一的天然卫星是月球,两者的引力相互作用引起
        潮汐并稳定地球自转。
    </p>
</body>
</html>

本例,最终应用的边界是图片中心为圆心,半径为50像素的圆形,显示效果如下图所示。

使用inset()函数定义边界