CSS基本概念 四、可视化布局

尽管CSS包含非视觉媒体样式,但CSS的核心是一种视觉表现样式的语言。 因此,以后作者将花很多时间担忧他们样式的视觉效果,以了解如何将这些效果的构造和布局,它是至关重要的。

    在CSS中有两个基本的布局机制:盒模型和内联布局模型。虽然它们是相关的,但每个都有自己的规则和效果,所有的都不是直观的。 此外,这些特殊的规则都是来描述如何定位元素来布局,以及如何浮动元素放置和尺寸。这些规则是仿照盒模型,但也有一些重要的区别。

盒模型(The Box Model)

在CSS的视觉显示的基础是盒模型。熟悉盒模型的各个组成部分能使作者了解许多属性彼此之间如何相互影响,以及理解为什么它们会在页面上出现(或者找出为什么在浏览器出错)。

基本组成(Basic Components)

    盒模型基本组成图如下图所示。

布局具体规则(Specific Layout Rules)

    元素的背景(无论颜色、图像或一些组合)延伸到边框的外边缘,从而填满内容区域和填充区域。它也将通过在边界本身的任何“间隙”可见,例如那些边框值为圆点,虚线,双边框。

    下面的等式总是正确的:父元素宽度的值(也就是说,父元素的内容区域的宽度)=margin-left+border-left-width+padding-left+width+padding-right+border-right-width+margin-right(左外边距+左边框的宽度+左内边距+宽度+右内边距+右边框的宽度+右外边距)。有时必须设置左右的外边距为负值来达到目的。在这种情况下,元素仿佛将比它的父元素更宽,并将“伸出”其父元素的内容区域。然而,在数学上,负的外边距值满足上述方程,并且该元素可以与父元素的内容区域是完全一样宽的(例如:父元素width:200px;margin:-100px;子元素width:100px;)。由于视觉效果恰好是相反的,这似乎很虚伪,但在CSS这是允许的。

    只有外边距时,高度和宽度可以设置为auto(自动)。外边距可以赋予一个负值的长度,但高度和宽度不能。内边距和边框宽度默认为0(零),并不能设置为负值。

    在正常文档流中的元素的垂直相邻的外边距会被折叠。换言之,如果两个外边距是垂直的相邻的,那么两个元素之间的外边距的实际距离是相邻的外边距中的最大值。在外边距为负值的情况下,正值外边距的最大值减去负值外边距的绝对最大值。在浮动和定位的情况下垂直的外边距不会折叠。

    折叠外边距的机制可以想象成一个纸塑的模型,在这个模型中,每个元素的元素内容可以看做被写(或 画)在纸上。围绕该元素的任何边缘表示为一条条清晰的塑料连接到纸张的边缘。当一个元素跟随另一个元素接触时,它们被滑动到一起直到一个元素的塑料条的边缘接触到另一个元素的纸的边缘。因此,塑料将重叠,但纸片之间的距离永远不会比的塑料带的宽度更宽。如果多个元素相邻这是正确的,如一个列表结束和另一个列表开始。以四个相邻的外边距举例(两个ol或者ul),第一个列表的底部外边距和它最后一个列表项的底部外边距和第二个列表的顶部外边距和和它第一个列表项的顶部外边距。两个列表项的内容之间的距离将是四个外边距中最大的一个。

    回想起水平外边距不会折叠。因此,两个相邻的行内元素的水平外边距设置为10像素的话第一个元素的右边与第二个元素的左边相距20像素。当元素设置为浮动或者定位时无论水平或者垂直的外边距都不会折叠。

内联布局模型(The Inline Layout Model)
    一个元素内的设置文本的方式的几乎就像盒子模型一样。 虽然这可能看起来很简单,一旦放置细节,它很快就会变得复杂。

基本组成(Basic Components)

    基本的内联布局模型的图如下图所示:

具体的布局规则(Specific Layout Rules)

    用下列术语计算一行文本的高度:

    . 内容区  通过每一段文字的font-size定义的盒子(无论是否在一个元素)

    . 补白   由行高的值确定距离,那里的补白等于((font-size-line-height)/2)

    . 内联盒子 定义内联盒子减去顶部与底部的补白为内容区域(内联盒子=顶部补白区+内容区+底部补白区);对于任何给定的文本,内联盒子的高度将始终等于文本的行高的值

    . 行盒    实际盒子是堆放先前行盒的下面;它的界限位于行中的最高的内联盒子的顶部和最低的内联盒子的底部。

    这一切都是怎么做到的?对于每一个文本段,生成一个内联盒子,利用内容区域和补白决定它的最终高度。内容区将始终在内联盒子中垂直居中。内联盒子然后根据每个垂直对齐的值考虑。如果是基线值,则文本基线与该行的基线对齐。

    一旦内联盒子被垂直对齐,行盒的高度会被确定。 行盒的顶部与行内最高的内联盒子的顶部对齐,行盒的底部与行内最低的内联盒子的底部对齐。每个行盒的顶部放置在上一个相邻的行盒的底部,或者在元素中是第一个行盒的情况下与父元素的顶部内边线相邻。因此,行盒通过“堆叠”来形成一个块级元素的内容。

    事实上,每个字符生成它自己的内联盒子,但对于一个给定的元素生成的内联盒子都应该具有相同的高度,所以,通常,在内联盒子中讨论的元素级别。

    围在内联元素周围的所有边框位于定义的区域(在内容区加上所有声明的内边距)以外。这与行盒本身没有直接关系;行盒的边缘在同一个地方可以绘制边框,如果是这样那是巧合。内联元素的边框完全有可能“穿过”行中的文本,或穿过其他文本行。

    当涉及到边框、背景和其他盒属性时,如果它们是单行文本内联元素将被格式化。让我们打个简单的比方。图片是一个确定的内联元素:元素的内容写在一个单条纸上。任何背景、边框、填充和内联元素的应用等按照盒模型。在纸条中纸条中的字将被撕裂这样每个纸段将与块级元素内容区域右和左边缘相吻合。因此,任何行分段的边框将很可能不“结束”最后部分,除了第一行分段的左边缘和最后一行分段的右边缘。同样,任何右或左的内边距(或外边距)将分别只会出现在最后一个或第一个行分段上。

    这个比喻只是部分准确的。如果内联元素中的所有文本都是相同的大小和相同的垂直对齐方式,那么这个比喻是完全正确的。然而,如果不是这样的话,在前面介绍的这部分中每一个行高都会发生改变。换句话说,由于以行盒的方式构建,一些行分段可能比其他内联元素的更高一些。否则,可以类比;任何左或右内边距或外边距将分别仍只适用于第一或最后一个行分段。

    在不可替代的内联元素上设置顶部和底部的外边距(例如,前面的元素仅仅包含文本)在布局上将无效果,同样外边距不能影响行盒高度的计算。设置顶部和底部的内边距可以导致内联元素背景的增加,但是关于应该发生在这样的情况下的规范并不清楚。扩大的背景可能覆盖其他行中的文本,甚至覆盖其他的元素。甚至背景可能绘制在其他内联元素内容的“下方”。用户代理(浏览器)许可在内联元素中忽略顶部和底部的内边距。

    内联替代元素(例如,一行文本中的图片)在文本中的处理有些小差异。一个替代元素的内联盒子定义为元素加上所有的边框和外边距。因此,内联替代元素的顶部和底部的外边距会影响行盒的高度。

    

浮动规则(Float Rules)

    当元素浮动时,它的视觉布局受十条规则支配。事实上,这些规则说明了“放置浮动元素的高度,和一面有多远,尽可能”。然而,重要的细节:

    1.左浮动盒子的左外边缘可能不在它的包含块左边缘的左侧。右浮动元素的规则也相似。

    2.如果当前的盒子左浮动,并且在源文档中预定义为左浮动盒子的一个元素,那么对于每个早期的盒子,任何一个当前盒子的左外边缘必须是在早期盒子的右外边缘的右侧,或者它的顶部低于早期盒子的底部。右浮动盒子的规则也相似。

    3.一个左浮动盒子的右外边缘可能不在一个右浮动盒子左外边缘的右侧这是正确的。右浮动元素的规则也相似。

    4.一个浮动盒子的外面的顶部可能不高于它的包含块的顶部。

    5.一个浮动盒子的外面的顶部可能不高于一个块的顶部或在源文档中预定义为浮动盒子的元素。

    6.一个浮动盒子元素的外面的顶部可能不高于包含一个在源文档中预定义盒子的元素的一个行盒。

    7.一个左浮动盒子它的左边有另外一个左浮动盒子它右外边缘可能不在它的包含块的右边缘的右侧(大意:左浮动可能不伸出右边缘,除非它是向左尽可能的远)。右浮动元素的规则也相似。

    8.浮动盒子必须放置的尽可能的高。

    9.左浮动盒子必须尽可能的放在左边,右浮动盒子必须尽可能的放在右边。一个高位置是首选更进一步的是左/右。

    10.(在clear:left的情况下)一个浮动的顶部外边缘必须在任何早期左浮动盒子的底部外边缘的下面,或(在clear:right的情况下)在任何早期右浮动盒子的底部外边缘的下面,或是(clear:both)在以上两者的底部外边缘的下面。

    浮动元素的外边距永远不会折叠。因此,尽管一个元素可能浮动到它父元素的左上角,它的外边距将会把它推出角落,也会把任何属于浮动元素的内容推出。

    即使被禁止的浮动元素比包含块的顶部高,但仍有一个围绕着这个浮动元素。通过设置一个负的外边距,这个元素可能“拉起来”超过它的包含块的顶部。与元素的某些功能类似通过设置一个负的左右外边距可以实现超出包含块。还有,浮动元素可以通过设置左或右外边距超出一个元素。然而,用户代理(浏览器)不需要文档流来解释这种情况。建议作者非常谨慎的使用这种技术。
    尽管浮动元素脱离了正常的文档流。依然会影响文档中内容的布局。通过增加浮动元素周围沿着基线的元素的内边距来实现这一效果。不管怎样,这意味着任何元素的背景和边框将在浮动元素的“下面”延伸,并且可能越过其他浮动元素的侧面。这种行为确保了所有的元素盒子将保持矩形,但是它可能导致不必要的影响。

定位规则

虽然CSS开始元素样式以正常的文档流的方法,很显然作者想做更多的自己的布局。以此方法来抵消自己正常的元素布局,用CSS的方法替代框架有一些要求,等等。作为答复,CSS2添加了定位规则。其实仅有三种定位:static(静态的),relative(相对的)和absolute(绝对的)。静态定位是正常状态的——换句话说,静态定位实际上是“不定位”。相对定位元素替换了他们正常文档位置的方式,然而绝对定位元素在固定的一些点上放置,并且永远不会改变他们的位置。
每个被定位元素放在它的包含块里。这个块可以看作是被定位元素的父元素。每个被定位的元素拥有独一无二的包含块。在下面的部分定义这个块需要说明。
相对定位
相对定位在它执行时是相当简单的。一个相对定位元素通常将从正常的文档流中占据的位置偏移,并且保持它离开后原来的空间。这个定位元素很可能在操作中覆盖其他元素(或元素的内容),或者被其他的元素覆盖,可以依靠z-index属性的值来解决以上问题。有必要的话,在作者创立的样式时能够避免这种情况。
包含块
一个相对定位元素的包含块盒子将不脱离正常的文档流(就像,它没有定位一样)。
偏移量
它的距离包含了相对定位元素top,right,bottom和left属性的集合。正值将推动元素靠近它包含块的内容区,负值将推动它离开。因此,一个正的top值将推动元素向下,当一个正的bottom值将向上移动。负值将向相反的方向移动。同样的,一个正的left值,将元素向右推动,一个正的right值,将元素向它的左边移动,用负值将有相反的效果。在一些情况下属性的值会相互冲突。例如,在元素中设置top和bottom两者方法都为10px应该两者都被向上和向下移动10像素,哪一个不合理。因此,使用下面的规则:
1.如果给予top和bottom两个属性一个明确的值,那么bottom的值将被忽略。
2.如果给予left和right两个属性一个明确的值,按照从left到right的顺序right的值将被忽略。按照从right到left的顺序left的值将被忽略。

绝对定位
绝对定位在position属性中实际上包含两个值。这些值分别是absolute和fixed。在任何情况下它们两个唯一的不同地方在于包含块;此外,定义包含块的规则是相同的。
上述两个情况,定位元素彻底的脱离了正常的文档流。这个定位元素很可能在操作中覆盖其他元素(或元素的内容),或者被其他的元素覆盖,可以依靠z-index属性的值来解决以上问题。有必要的话,在作者创立的样式时能够避免这种情况。

包含块

在position:absolute的情况下,被定位元素的包含块靠近的父元素除了stacic还可以加入position属性的值。如果没有父元素,这时包含块把文档作为父元素。在HTML和XHTML中,这个父元素实际是HTML元素,不是BODY元素。这个包含块将从文档的左上角出发,设在BODY元素的外边距上。绝对定位元素会随着剩余文档发生滚动,就像它们已经被完全的固定在文档自身上。

在position:fixed的情况下,包含块是视野窗口。在浏览网页时,视野窗口是浏览器的显示窗口,固定定位元素将不随文档滚动并且与框架的方法类似。在像打印的分页媒体中,每一页都建立自己的视野窗口,所以固定定位的元素将出现在每一页同样位置的视野窗口上。

水平尺寸
一个绝对定位元素的水平尺寸包含了left,margin-left,border-left-width,padding-left,width,padding-right,border-right-width,margin-right和right属性。这些属性的值,同时相加,可能等于包含块的宽度。负的外边距可能使元素超出包含块。

有一些规则支配调节它们的属性值,对于不可替代元素(例如,段落)的规则如下所述:
1.在从左到右的顺序中如果left属性被设置为auto,这个值会被在正常文档流中元素左边缘的同一位置重置(就像是,它没有被定位)。如果想要包含块的左边缘指向左边,那么将要把left设置为负值。按照从右到左的顺序,right属性的规则被应用,而不是left。
2.如果width属性被设置为auto,那么auto值把left和right属性的值重置为0。它将标记元素并且它的外边距和包含块是等宽的。
3.如果left,right或width被设置为auto,那么auto值把margin-left和margin-righ的值重置为0,元素将会移动左或右的外边距。
4.如果把margin-left和margin-right两者都设置为auto,那么相当于它们设置为相等的宽度。如果明确的设置元素的宽度,那么元素在它的包含块之内将实现“居中”的效果。(如果没有明确的设置元素的宽度,那么它应当设为auto的规则将生效,并且设置两者的margin为0。)
5.如果只有一个值为auto属性(例如,设置为上述的属性规则),那么它的长度被重置为必须满足计算的水平尺寸等式。
6.如果所有的尺寸都被设置为明确的长度,并且它们的长度没有增加包含块的宽度,那么按照从左到右的顺序left属性的值被设置为与水平尺寸等式相等是它们将重合。按照从右到左的顺序,对它的右属性进行设置。
对于已经被绝对定位的替代元素(例如,images),它的规则与上述的两种方法不一样。一,如果width属性的值设置auto,用来替代元素原有的宽度。二,由于它的width属性的值从来不会是auto,(上述列表)第三条规则是无效的。

此外,用min-width和max-width属性设置元素宽度的界限。它的使用有下述规则:
1.它的宽度是正常计算的(理解以前的规则)
2.如果给予min-width属性的值大于max-width属性的值,max-width属性的值被重置为min-width属性的值。
3.如果元素计算的宽度大于max-width,或者小于min-width,那么width属性的值被适当的调整来与之(max-width或min-width)相匹配。
每个用户代理对于自己min-width的值有不同的定义,因此用户代理可以在内部值下自由的设置min-width的值。
垂直尺寸
一个绝对定位元素的垂直尺寸包含了top,margin-top,border-top-width,padding-top,height,padding-bottom,border-bottom-width,margin-bottom和bottom属性。这些属性的值,同时相加,可能等于包含块的高度。负的外边距可能使元素超出包含块。
有一些规则支配调节它们的属性值,对于不可替代元素(例如,段落)的规则从先前的CSS2开始:
1.如果top属性被设置为auto,这个值会被在正常文档流中元素顶部边缘的同一位置重置(就像是,它没有被定位)。如果想要包含块的顶部边缘指向顶部,那么将要把top设置为负值。
2.如果height和bottom属性两者被设置为auto,那么bottom属性的值被重置为0。
3.如果bottom或height属性中两者任意一个被设置为auto,那么任意一个auto值把margin-top和margin-bottom重置为0。在元素中它将移动任意的top或bottom的外边距。
4.如果margin-top和margin-bottom属性两者被设置为auto,那么它们被设置为与高度相等。如果元素的高度被设置为一个明确的长度,那么元素在它的包含块之内将实现“居中”的效果。(如果没有明确的设置元素的高度,那么它应当设为auto的规则将生效,并且设置两者的margin为0。)
5.如果只有一个值为auto属性(例如,设置为上述的属性规则),那么它的长度被重置为必须满足计算的水平尺寸等式。
6.如果所有的尺寸都被设置为明确的长度,并且它们的长度没有增加包含块的高度,那么bottom属性的值被设置为与水平尺寸等式相等是它们将重合。
对于已经被绝对定位的替代元素(例如,images),它的规则与上述的两种方法不一样。一,如果height属性的值设置auto,用来替代元素原有的宽度。二,由于它的height属性的值从来不会是auto,(上述列表)第三条规则是无效的。

此外,用min-height和max-height属性设置元素宽度的界限。它的使用有下述规则:
1.它的高度是正常计算的(理解以前的规则)
2.如果给予min-width属性的值大于max-height属性的值,max-height属性的值被重置为min-width属性的值。
3.如果元素计算的宽度大于max-height,或者小于min-height,那么height属性的值被适当的调整来与之(max-height或min-height)相匹配。
每个用户代理对于自己min-height的值有不同的定义,因此用户代理可以在内部值下自由的设置min-height的值。
在这些规则下的标签,它能够设置一个复合属性将影响一个元素正好包含它自己内容的足够的高度,并且不会更高(或短)。它有时产生“收紧包装”的效果,并且在CSS2中这个严重的缺陷经常被忽略。为了纠正它的情况,有人已经提议通过把height值改为auto使得"元素拥有足够的高度包含它自己的内容"。虽然这个建议没有被W3C正式的采用,但是我们所知道的已经兼容的用户代理(浏览器)都支持绝对定位。

作为一个基本的例子,假设一个绝对定位元素的margin和padding两者的宽度都被设置为10px,它的border宽度为0,并且定位元素中的height值为auto。进一步假设top被设置为0,bottom被设置为100px。现在,进一步假设它的内容高只有260px。事实上它将设置height为260px。为了满足等于垂直尺寸的计算这个方法定位元素的内容将被精确为400px高。如果定位元素内容实际上为475px高,那么bottom将被重置为175px。

字体规则:
当浏览器渲染文本时,它一定选择一种字体使用。然而,几乎不存在一种字体包含了所有可能在文档中需要出现的字符。因此,事实是文本中每次字符被渲染时,浏览器在它有用的字体表中找出最合适的字符。它不用决定某个字符的存在,请求程序按照CSS文档规则使它的样式,粗细,变形体都可用。
在这些规则中,一个字形组实际上集成了一些公有字体的名字。例如,Times New Roman
(新罗马字体)实际上是一些字体的集合。每个字体是一个基本字体的变体;这个集合可能包含Times New Roman Italic(新罗马字体斜体),Times New Roman Bold(新罗马字体粗体),等等。因此,默认的字体将有点像Times New Roman Regular(正常的新罗马字体)。
作者实际上不用设置这些字体的名字,但是更换字体的种类明确的表示他们想要用各种font-related(相关字体)属性。在第四章有更多关于字体的属性和它相关属性的细节。
字形组选择
作者(或用户)假如在被用的字体表选拔字体的过程受到的影响,按首选项的顺序,渲染元素。浏览器利用列表上的一些规则挑选字形组中使用到的给定字符渲染。
字体匹配的有关步骤如下:
1.在文本中渲染字符,浏览器构造一个可应用字符的字体属性表。浏览器在那时识别字形组中包含的将要被显示的字符特性,和必需的字符一样。
2.如果字形组包含了必需的字体,浏览器尝试提前处理(以后讲解)。
3.如果步骤1和2失败,那么浏览器将从它的字体列表中的下一个字形组继续进行。这个字体匹配的过程在下一部分讲解。
4.如果必需的字体在字形组中,但是必需的字符不存在,那么浏览器将从他的字体列表中的下一个字形组继续进行。
5.如果必需的字体包含了必需的字符,那么浏览器将在显示器上显示合适的字符(例如,整个空间充满“缺失字符”开放的正方形)。

例如,假定作者声明一个H2元素应当使用Helvetica(经典字体)渲染,并且在文本内部的元素应当为加粗的和倾斜的。浏览器必须首先找出Helvetica字形组并且确定它是否包含一个同时具备加粗的和倾斜的两个属性的字体。如果这样的字体存在,那么浏览器确定在字体中需要的字符是否存在。如果存在,那么它就使用字符渲染,并且浏览器从下一个字符出发直到处理结束。如果字体中不存在需要的字符,浏览器必须观察其他的字体中合适的字体中必需的字符。如果浏览器不能提出合适的匹配,它必须使用一个“缺失字符”显示符号不足。
CSS2规定的(同前面列表中的提到的第二项)更多字体选择的先进处理规则。
1.智能的字体选择。浏览器使用的字体描述符在字形组中轮流选择诸如象形文字宽度和x-height(字母'x'的高度)一样。如果判定相配者存在,那么字体就被用来字符的渲染。这个字形组的属性值不会发生改变。
2.字体下载。浏览器试图和能被下载和使用的字体资源一致。浏览器决定将要被使用的给定字体,假如这样的话,将等到字体下载结束。
3.字体综合。浏览器尝试构造一个它自己特有的字体,基础的字体说明例如

和x-height值。事实上,所有的字体说明必须以为字体综合的位置为条件。
浏览器不需要支持所有前面的这些方法。

字体外观选择
在字形组选择的过程期间,浏览器必须判定字体中的必须的字体外观有用。例如,如果作者明确指定一个元素应该为倾斜的,浏览器必须找到一个正在使用字体中的一个斜体外观。外观的选择如下:
1.浏览器首先尝试在font-style(字体的样式)中选择外观公告,如果它的值指定为italic,那么所有的外观标记将选择为Italic(斜体字)或Oblique(倾斜的)。如果给定的值为Oblique(倾斜的),那么将选择只有Oblique(倾斜的)的外观。
2.浏览器下一步尝试在font-variant(字体的变体)中选择外观公告,如果它的值指定为small-caps(小型大写字母),那么所有的外观标记将选择为small-caps(小型大写字母)。如果没有这样的外观存在,那么浏览器从一个必须的正常外观中产生一个缩写的大写字母的替代者。作为最后一招,没有缩写的浏览器使用正常的大写字母。如果它的值给定为normal,那么所有的外观将选择不被标记为small-caps(小型大写字母)。
3.浏览器选择的值属于font-weight(字体的粗细)。字体粗细的选择在下一部分描述,这个选择永不失败。
4.最后,字体的大小被选择。从最大的字体缩写所有必须的字体,它的脚步应该永不失败。
例如,假定作者指定一个元素将具备小型大写字母和斜体的两个外观。如果有可能浏览器必须确定外观同时具备小型大写字母和斜体的。否则,它保持寻找选择前面部分给定的使用规则。

字体宽度选择

font-weight属性接受数字的值,包含从100到900九个数字值和normal、bold值。数字值得核心属于字体宽度选择;人性化的标注其他的值(例如,bold)被像在数字尺度上
清晰的磅一样处理。字体宽度的选择如下:
*normal值同数字中400值的效果一样;bold值同数字中700值的效果一样;。
*假设字体已经有九级的宽度尺寸,字体的样式像OpenType(字体OpenType也叫Type 2字体)一样,尺度映射了从100到900的数值。
*如果字体的外观标注媒体像标注成书,正常体,罗马字体,标准体,那么媒体与500的值一样。
*如果字体的外观标记成加粗,那么外观媒体与700值相等。

如果字体包含较少的九粗细,那么“间隙”的填充如下:
*如果值500未赋值,它符合同使用的400的值一样。
*如果值600,700,800或者900中任意一个未被赋值,那么他们有下一个较粗的粗细可用。如果没有较粗的粗细可用,那么他们有下一个的粗细可用。

大多数字体将已经在最后两个外观:正常和加粗,地图的值从400和700,在这种情况下,从100到500的值将产生一个正常的外观,600到900的值将产生加深的外观。

允许选择更过的复杂的例子。假设一个字体包含了下面的字体外观:Meyer Regular,Meyer Bold,Meyer Light,Meyer Dark。它的下一个加深与“加粗”相等。给定他们的外观,粗细的值将如下给定:
Meyer Light:100,200,300
Meyer Regular:400,500
Meyer Bold:600,700
Meyer Dark:800,900

如果Meyer Light在字形组中部分没有用,那么Meyer Regular中值为100到500将被作为外观使用。工作的最后部分将永不改变。

猜你喜欢

转载自www.cnblogs.com/lidongming/p/9225735.html