前言铺垫
网页是HTML的集合,对于一个具有DOM(Document Object Model,文档对象模型)思想的前端“攻城湿”来说,对于HTML标签应该会有更深层次的体会。
DOM文档对象模型这些标签的组合排列及嵌套就组成了平常看到的多姿多彩的网页,要从事前端工程师的工作就必须从学习HTML标签开始。一开始我觉得这玩意儿真的没啥可学习的。不就是一堆英文字符么,随便记忆一下就万事OK了,这还是个事么?
估计和我有一样想法的人应该还不少。回想那个时候我还很年轻,不知道天高地厚。朋友的公司需要有一个网站来展示自身的产品和文化,于是找到了一个打着计算机专业人才标签的我。我想到都没想直接就答应了,当时的我掌握了那么一点点HTML基础和DEDECMS的模板制作技术,就觉得分分钟可以完工的事。做到一半才发现,我……太天真了!
那是一个大雪纷飞的周末,披着被子坐在电脑前的我完全不理会女朋友不能出去玩雪的抱怨,一心一意要把朋友的网站给搞定,开始的时候无比顺畅,随着雪花越来越大越来越密,我的心也开始越来越兴奋——于是我进入了心理学中所谓的“心流”状态(不知道什么意思的百度去)。
悲剧的时刻到来了,当我想要给一个<span>
标签设置margin-top
的时候怎么都不生效。怎么都搞不定,被堵住不能前进的感觉让我都快疯了,直接把抱怨牢骚不断的女朋友给吼了一顿,她是安静了,我还是不能前进半步,无奈之下只能简单粗暴的给含有文本的<span>
设置line-height
才算撑开了一点距离,虽然很丑但是勉强达到了效果。
上图的示例也能看出来,这货已经开始罢工了,没有任何效果。找了很多资料之后我才知道是什么情况导致的这种原因;从此开始我觉得,学习这件事啊还是打好基础的好。
“框”的分类及区别
为什么会出现我遇到的问题呢?这就要说下HTML标签所生成“框”的类型了。类型一共分为三种:
- 行内元素(内联元素 inline-level)
- 块级元素 (block-level)
- 过渡元素 (Replaced Elements)
三者有什么区别呢?本来想要写文字来表述下,但是大片大片的文字实在是影响阅读的兴趣。而且我的文字驾驭能力实在是让人汗颜,所以我列出表格让数据更加直观的呈现出来。
说明 | 块级元素 | 行内元素 |
---|---|---|
常见元素 | div、p、form、ul、ol、li等等 | span、strong、em等等 |
width、height属性 | 可以设置,设置了宽度还是独占一行 | 无效。 |
margin和padding属性 | 可以设置。 | 水平方向的padding-left、padding-right、margin-left、margin-right都产生边距效果,但竖直方向的padding-top、padding-bottom、margin-top、margin-bottom却不会产生边距效果。 |
对应的相关display属性 | block | inline |
切换 | display:inline变成行内元素 | display:block变成块级元素 |
text-indent属性 | 有效 | 忽略 |
嵌套 | 块级元素可以包含内联元素和某些块级元素,特殊块级元素如h1-h6、p、dt只能包含行内元素而不能包含块级元素。 | 内联元素不能包含块级元素。 |
浮动 (float) | 保持为块级元素。 | 自动变为块级元素,并且拥有块级元素的所有属性。 |
定位(position) | 保持为块级元素。 | 相对定位(relative)保持行内元素不变,据对定位(absolute)的时候变为块级元素。 |
以上就是块级元素和行内元素的区别,行内元素设置边距在垂直方向上是会失效的,只有水平方向才生效,我错误的根源终于找到了。
嘚瑟一下!需要说明的是HTML5中有些标签被重新定义了,如果不知道一个标签到底是什么元素的话,可以查看官方文档,如果看不懂英文的话可以利用浏览器的开发者模式来查看标签的默认属性。大多数的浏览器都是按F12来调出开发者模式。还拿那个无知的span
标签举例吧。可以看到红色文字区域,被修改之后的属性是以亮红色显示的,没有修改的默认属性是粉红色现实的,一目了然。
需要特别强调下的是浮动float
和定位position
属性对元素显示属性display
的影响,只要行内元素设置浮动float
或者设置定位position:absolute
行内元素的默认属性display:inline
就会变成display:block
。而定位属性设置为position:relative
的行内元素属性还是保持为display:inline
。下面我写了一点小代码,可以清晰的看到它们的区别。先放实现结果图后上代码。
//定位(position)和浮动(float)对display的影响
//CSS代码
body{
margin: 0;
background-color: #F4F4F4;
}
.position-absolute-span {
margin: 10px;
padding: 10px;
position: absolute;
}
.position-relative-span {
margin: 10px;
padding: 10px;
position: relative;
}
.float-span {
margin: 10px;
padding: 10px;
float: left;
}
//定位(position)和浮动(float)对display的影响
//html代码
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link href="test.css" rel="stylesheet" type="text/css" />
<title>Document</title>
</head>
<body>
<span class="position-absolute-span">行内元素绝对定位时候的样子</span>
<span class="position-relative-span">行内元素相对对定位时候的样子</span>
<span class="float-span">行内元素浮动时候的样子</span>
<span >什么都没设置时候的样子</span>
</body>
</html>
写了这么多基本上也交代的差不多了,那么说完行内元素和块级元素之后就要说说过渡元素了,说实话这货我掌握的不是很好,就说说个人理解吧。过渡元素基本上就是那些既有块级元素特点同时也有行内元素特点的标签,比如<li>
,它在IE8之前默认属性是display:block;
,但是在IE8+/ Webkit / Firefox / Opera上面显示的是display:list-item;
。一般来说我们还是把它归纳到块级元素的里面。过渡元素里面还有可以根据上下文语境来自动决定自己是否应该是块级元素或者行内元素。例如最常用的<button>
和<del>
。
误解
很多文章都说行内元素在垂直方向上设置填充padding
是无效的,本人亲自做实验得到的结果却是行内元素在垂直方向是可以生效的。如下图,到底是神马原因呢?这个问题真的是让我百思不得其解啊,抓破头皮都想不通为什么,后来我注意到我实验中的一个小BUG,看到span.line
的显示效果确实是填充已经生效,注意到在padding-bottom
方向与padding-top
方向的样式和我设置的数值有些许不一样,也就是看着不等距了。到底是什么原因导致的呢?是不是就是这个原因让我的实验得出了错误的结论?
看来要重新设计实验了,必须要搞清楚是毛线原因导致的我得出相悖的结论。想到就下手去做,我先设置两个类span.inline
和span.block
,之后输入两段长长的文本,在两段文本中随机选择几个字并分别设置class。来看看结果如何吧。
span.inline{
display:inline;
padding:20px;
margin:20px;
border:thin soild red;
}
span.block{
display:block;
padding:20px;
}
行内元素垂直方向的边距和填充实验
从图中可以看到,行内元素确实具有盒模型,这点从浏览器的显示就可以看出来,边距margin
就是黄色部分,绿色就是填充padding
,在水平方向上也确实符合我们总结的知识。
为了更容易分辨效果,我在demo-2上面去掉了边距margin
并且使它成为一个块级元素。很是直观的就能看出来,虽然行内元素在垂直方向上具有盒模型的渲染效果,实际上垂直方向的margin
和padding
并不会对周围的元素产生影响。
而demo-2在没有margin
只有padding
的情况下依然把周围的元素给“撑”开了。这就更能说明在垂直方向上行内元素的虽然具有盒模型效果,但是margin
和padding
依然是无效的观点是正确的。
我的实验中那个让我起疑的奇怪的padding
不等距问题,也是因为行内元素的padding
对周围元素不会影响的结果,为毛还会有一定padding
效果被渲染了呢?因为我的body
标签没有重写,是默认的样式margin:8px;
所以上面会有有padding
被渲染了一点的假象。
牛×的Display
说到display
不得不点个赞给它。这货太凶残了,当发现一个标签在垂直方向上设置margin
或者padding
失效的的时候。直接简单粗暴的写上display:block;
,直接设置成块级元素,分分钟让它乖乖的听话。当然把一个标签从从块级元素变成行内元素就需要display:inline;
。
这些都是小CASE,主要想要说的就是display:inline-block;
了,这货简直是要逆天了。由于元素浮动有的时候控制的不是很好,但是又想让块级元素在一行显示;或者是由于元素浮动了就自动变为块级元素,但是还要元素一些行内元素的属性。那么这货就可以大展身手了。
这样就可以避免使用浮动之后忘记清除浮动而会产生未知问题了.不过这里面产生了个小小的问题,由于display:inline-block;
替换了默认属性display:list-item;
,所以li
的list-style-type
就会失效,就是说前面没有小点点或者数字了,这点需要注意。如果想要前面的小点点或者数字出现的话,只能使用float
让li
浮动了了。我自己的博客空间到期,不想在续费了,所以把文章全部转到了简书,所以DEMO页面和代码也看不到了,真相看代码的自己按照我的图打出来就行了~
(报告完毕!)
网友评论