给设计师们的代码指南(二)—— 代码里的图层

献给那些被代码折磨的设计师们的第二弹~设计师一直觉得代码很难搞,一点都不直观,但其实网页代码与 PS 文件是有相似之处的,这篇文章就会从这份相似性入手,来谈谈 HTML 中一个最基础的概念——内联元素与块级元素,而与之对应的 CSS 当中的概念便是行框与盒模型。

BTW:在网上看到有人说到 HTML 4 + CSS 2.1 与 HTML 5.0 + CSS3 的问题,我会根据需求和实际情况具体说明,而文章整体上是趋向于 HTML 5.0 + CSS3 的,而HTML 5.1 在语义化中所作的努力,我也会尽量写进来(但是因为个人了解实在有限,所以如果出现错误还请不吝赐教)。

简单来说,如果你的老板/客户要求你兼容IE6、7、8,那就几乎无法使用 HTML 5,普通的 HTML 也会出现各种奇怪的问题,作为一个设计师的你也可以直接义正言辞地说,臣妾做不到啊~~(IE6 兼容在世界各地的前端工程师眼里都是眼中钉肉中刺上辈子的仇敌这辈子的冤家)

在正文开始之前,我想先让你看一眼最上面那张图,你是不是觉得这种展示方式仿佛在哪里见过?如果你曾经做过应用的banner或者是手机主题,那你甚至有可能用过类似的方式来展现你们的产品。Google前段时间推出的Material Design也提到了布局的纵深感,在其中有这样一张示意图:

网页内的每一个元素,其实就好像是你 PS 文件中的一个图层,通过 CSS 的手段来定位图层,就好像你在PS里移动、缩放、旋转图层那样,本质上没有太多区别。我们都知道 PS 的图层面板中,越靠上的图层,在图片中显示越“往前”,而在 HTML 中,后出现的元素则会叠在先出现的元素上面。如果说图层就是一张张纸片,PS 中的图层管理是把一张张纸片叠起来,那么 HTML 中每出现一个新元素,就好像是新拿来一张纸,叠在原本的纸片堆上。

以上面那张 Google Material Design 的示意图为例,其 HTML 代码简单写下来大概是下面这样(我用div的id属性值来表示上面图中的部件名称,实际使用中请不要这么做):

1
2
3
4
5
6
7
8
9
10
11
<div id="background">
<div id="system-status-bar">
系统状态
</div>
<div id="content-card">
<button>Floating Button</button>
<div id="system-navigation-bar">
底部导航
</div>
</div>
</div>

我写这段代码的用意是展示 HTML 代码中的元素与实际页面上的的关系。在 PS 中,只要图层之间的上下位置正确就可以,如果两个部分没有互相重叠,那么这两个部分的图层谁在上谁在下都可以。但是在 HTML 中,除了遵循最基本的“后出现在上面”的原则,通常还需要注意,如果两个部分属于同级,那么位置靠上的内容要先写(加粗“通常”两个字真意味深长啊哈哈)。

在 CSS 的世界中,这种一个个表现得如同图层一般的 HTML 元素就被称为块级元素(Block Element)

块级元素与盒模型

块级元素有两个默认的表现:

  • 在没有规定宽度的情况下,它的宽度会自动撑满所能占据的宽度。
  • 这些块会一个接一个的上下放置。

这是我觉得 HTML 元素为数不多的与 PS 图层不同的地方。PS 的图层更随意,HTML 元素受到的约束更多。

块级元素本身,则遵循着被称作盒模型(Box Model,也被称作框模型)的布局方法,你可能已经听说过paddingmargin这两大基友了,也许还看过不少示意图,如果你仍然不懂…我也不想丢你一个抽象得只有线的图,请看:


图片来自SCAD

诶嘿嘿 =v= 我希望这种表述方式你们可以懂~

最中央位于“画”的部分的,是为Content(内容),你的文字、图片或者其他子元素都会放在这里。画框与画之间的绿色区域(蓝色箭头所示长度分别表示上下左右距离),就是所谓的padding(内边距),画框自然就是border(边框),再往外一层的空白(被染红了,箭头所示长度分别表示上下左右距离),就是margin(外边距),在这里我用深浅不同的红色表示每一个“元素”的外边距,其实。在我的理解里,margin就好像元素伸出来的一只手,拟人之后大概是这样:

…当然了paddingbordermargin的宽度、颜色乃至样式(仅限border)都可以分别设置,家庭的一些无框装饰画或者像是莫奈的睡莲那种三幅一联这样的,都是比较典型的三无(左右无内外边距、无边框)元素。

元素之所以又是内又是外,里里外外跟洋葱似的套那么多层,是因为 HTML 元素需要一个定位的基准。在 PS 中,所有的图层都是以该图层的左上角的像素点,相对于整个画布的位置来决定的(你打开窗口 –> 信息 面板,并移动图层的时候,就能看到这个图层的位置信息)。然而这种定位方式对于网页来说,并不现实,而说到定位与布局,那就是 CSS 的另一个非常重要且庞大的部分了,所以我们留到之后再说……

行内元素与行框

我们都知道,PS 里除了普通图层,文字也会自成一个图层,当我们想把一段文字中的某两个字换个颜色,改改字号或者字体,只要选中这两个字,然后去用文字工具修改就可以了。但是在 HTML 中,这样不行。你需要告诉浏览器,从哪个字开始,到哪个字结束,它们的字号、字体、颜色需要发生变化。

这么说可能有点抽象,那么我们来举个栗子:

我要告诉所有人这个鱼塘被我承包了

这句话的“所有人”三个字是红色,而“被我承包了”这段话上出现了删除线。其对应的 HTML 代码应该是(在实际写代码的时候,这种地方不用分行,我分成5行是为了便于解释):

1
2
3
4
5
6
7
<p>
我要告诉
<span style="color: red">所有人</span>
这个鱼塘
<s>被我承包了</s>

</p>

p元素是段落元素,它里面不能放置任何块级元素,而放置其中span元素及s元素,便被称为行内元素(Inline Element,也被称作内联元素)。另外“我要告诉”、“这个鱼塘”、“。”这三段被分割的文字(标点符号也算文字),浏览器会在分析显示的时候,创造出一个行内“匿名框”,因此这个p元素里实际上拥有5个行内框,这些“框”从左到右依次排列在一起,就变成行框

在我们学习英语的时候,老师会讲到所有的字都要位于某一条线的上方,只有像f\g\j\p\q\y这些字会把尾巴伸到那条线的下方,这条线就被称为基线(Baseline)。在默认情况下,行内元素及那些行内匿名框都是以基线对齐的( PS 中有且仅有基线对齐一种方式,所以基线就是我们在 PS 中编辑文字时总能看到的那条线了)。

另外一个困扰无数前端的大问题就是行高(line-height)…不过我觉得对于广大设计师来说这都不是事儿……对,PS 里也有一个叫做行高的值,如果前面说的框框框框让你难以理解,把 PS 中的行高直接带入理解也没有什么问题(当然具体问题具体分析,高度计算在整个 CSS 布局中都是一个比较令人困扰的问题)。

行框相对于盒模型来说鲜少被提到,因为那些“行内框”实际上也应用了盒模型,只是对于那些非自闭和标签所构成元素(这种元素被称为非替换元素(non-replaced elements),意思是说元素所显示的内容无法通过修改属性的方式替换)而言,paddingmargin乃至width(宽度)属性都会被无视,这点经常被人忽视而造成问题。

总结

在这篇文章中,我提到了三个非常重要的概念盒模型块级元素行内元素(这三个是一定需要理解和记住的,其它的嘛……不急于现在记住…)。这三个概念都是在 CSS 当中使用的,其中,盒模型是 CSS 当中,对 HTML 元素“图层化”的处理规范;块级元素和行内元素,则是 CSS 当中,对 HTML 元素的一种分类方式(HTML 对它的元素有自己的另一种分类方式)。

至于说哪些元素是块级的,哪些是行内的,哪些元素里面不能有哪些元素这种比较细节的问题,我在这里写一些常用的…肯定涵盖不到全部范畴,但是作为一个设计师的你来说,应该是完全够用了:

块级元素

  • 最常见的块级元素便是div,如同 PS 中的图层 1 或者图层 765,没有特殊含义,里面可以套各种各样的元素。
  • 有序列表ol、无序列表ul也是块级元素,而他们的子元素只能是列表项li元素,li元素是块级元素,但是li元素里只能放行内元素(和p元素一样)。
  • h1~6是标题专用的标签,还有引用blockquote,这两个是块级元素,而其里面只能放行内元素。
  • 表格table及其相关的行、列、单元格元素在表现上你可以当作它是一个块级元素,但它整体的样式解析方式非常特殊。本着样式追随内容的原则,在需要展现表格的地方使用表格元素,不要把表格当作样式或者布局的工具。
  • 表单form,语义化的块级元素,在 HTML 中表示这是个表单元素,而在 CSS 中,他跟div元素一样,里面放什么都行。
  • HTML 5 中新增了一批块级元素,主要是为了 HTML 语义化。包括header(页头)、footer(页脚)、nav(导航)、article(文章)、aside(侧边栏)、section(节选)。它们对其子元素都没有强制性的要求,只有articlesection需要内嵌一个标题元素,这同样是出于语义化的考虑。如果你不知道怎么用,可以不用理会它们,统统用div(除非你是个想转为前端的设计师)。

行内元素

  • 任何一段没有被标签包围的文本都会被视为一个行内元素。
  • 超链接a是一个典型的行内元素(但是实际应用中,经常会用超链接元素来做一个按钮(需要padding、margin),这在 CSS 当中也是可行的,以后再说)。
  • span元素在行内元素中的地位与div在块级元素中的地位相同,万金油的行内元素。
  • 看起来变粗的bstrong,以及看起来变斜体的iem。这两组元素在HTML 5中严格规定了语义,b表示无意义的加粗(比如产品名,或者仅仅是为了排版),i表示在文章中突出不同意见或语气(分类、术语、谚语等等),em表示一般的强调,strong表示超级强调的强调(……)。
  • 图片img、输入框input、下拉菜单select、文本框textarea。这几个元素作为行内元素,但却可以设置padding、margin(因为它们是替换元素)
  • 让字变小的small(让字变大的big元素虽然也是行内元素,但是 HTML 5 已经将其废止了)、上标sup、下标sub、短引用q、注音ruby、换行br等等都是行内元素。
本部落格采用DISQUS评论系统,如果您无法见到留言框,可前往我的GitHub微博提Issue(留言)。
为您带来了不便我也很尴尬╮(╯_╰)╭