CSS2的诞生是为图文信息展示服务的。CSS3的设计则是为了更绚丽的视觉效果和更丰富的网页布局。
块级元素负责结构,内联元素负责内容!
一个水平流上只能单独显示一个元素,因此理论上都可以配合clear属性来清除浮动带来的影响。
.clear:after {
content: '';
display: table; /* block,list-item */
clear: both;
}
图片和文字就是典型的内联元素。在css世界中,内联元素极为重要,涉及的css属性也非常多,这些属性往往具有继承特性!
<span>
、<a>
和<em>
等)hello world<span>hello</span>world
<p>
标签幽灵空白节点:在HTML5文档声明中,内联元素的所有解析和渲染表现就如同每个行框盒子的前面有一个“空白节点”,同时具有该元素的字体和行高属性的0宽度的内联盒子。
Each line box starts with a zero-width inline box with the element's font and line height properties. We call that imaginary box a 'strut'.
<div style="line-height: 30px;"><span style="display: inline-block;"></span></div>
<div style="line-height: 30px;"><p></p></div>
<div style="line-height: 30px;"><span></span></div>
<div style="line-height: 30px;"><span>xxx</span></div>
说明:在Chrome下,第一、四个div的高度为30px(由于inline-block
形成了一个行框盒子,从而出现了幽灵空白节点,其受到字体行高属性影响),第二、三个div的高度为0;内联元素中遇到的很多奇怪的问题都是由“struct”引起的
vertical-align的默认值就是基线,基线通常是指 x 的下边缘。vertical-align: middle;
指的是基线往上 1/2 Height高度。注意,vertical-align
只对行内元素及table-cell有效有效!
ex是CSS中的一个相对单位,指的是小写字母x的高度,1ex指小写字母x的高度。
内联元素默认是基线对齐的,而基线通常指x的底部。如果图标高度为1ex,同时背景图片居中,则可以使图标和文字天然垂直居中。
.icon-arrow { display: inline-block; width: 20px; height: 1ex; background: url(./arrow.svg) no-repeat center; }
line-height
设置行间的距离,影响行框的布局,默认值为normal。
我们通常将line-height设置为1,使其文字上下不存在行间距,便于控制高度!
行高决定内联盒子高度;行间距墙头草,可大可小(设置负值),保证高度正好等同于行高。
当前font-size为14px
属性值 | 示例 | 计算 |
---|---|---|
数值 |
| 1.5 * 14 |
百分比值 |
| 150% * 14 |
长度值 |
| 1.5 * 14 |
区别:使用数值作为line-height的属性值,所有子元素继承的都是这个值【1.5】;使用百分比值和长度值作为属性值,所有子元素继承的是最终的计算值【21px】,即这里不再受子元素font-size影响!。
line-height
指定了元素内部行框盒子(line-boxes)的最小高度;line-height
用于计算行框盒子(line-boxes)的高度;内容区域高度(content area) + 行间距(vertical spacing) = 行高(line-height)
宋体下:字体大小(font-size) + 行间距(vertical spacing) = 行高(line-height)
em是相对于font-size大小的css单位,因此1em等用于当前一个font-size大小。
<style>
.box1 {line-height: 20px;}
.box1 span {line-height: 36px;}
.box2 {line-height: 36px;}
.box2 span {line-height: 20px;}
</style>
<div class="box1"><span>span</span></div>
<div class="box2"><span>span</span></div>
.box1
和.box2
的高度都为36px;span的高度均为22px。如果将.box1 span
设置为 display: inline-block;
形成行框盒子,则其span的高度为36px。
设置line-height大小和height高度一样可以让内联元素垂直居中,是因为css中“行间距的上下是等分机制”!
每个“行框盒子”都会附带一个产物—“幽灵空白节点”,即一个宽度为0,表现如同普通字符的看不见的“节点”。有了“幽灵空白节点”,`line-height` 就有了作用对象【 line-height影响行框的布局 】,从而相当于span前面撑起了一个高度为36px的宽度为0的内联元素。
vertical-align
起作用的前提是:只能应用于内联元素(inline、inline-block、inline-table)以及display值为table-cell的元素。浮动和绝对定位会让元素块状化,从而导致 vertical-align
不起作用。
内联元素默认都是沿着字母x的下边缘对齐的;对于图片等替换元素,往往使用元素本身的下边缘作为基线;inline-block元素,如果里面没有内联元素或者overflow不是visible其基线为margin下边缘,否则其基线就是元素里面最后一行内联元素的基线。
<style>
.box {
line-height: 32px;
}
.box > span {
font-size: 24px;
}
</style>
<body>
<div class="box">
<span>文本x</span>
</div>
</body>
上述,.box
的高度并不是32px,要大几像素(受不同字体影响)。之所以导致上述问题,是由于幽灵空白节点strut导致(<span>
元素前,字体大小为默认字体大小)。文字默认都是基线对齐,字号越大其基线位置也就越往下。
解决上述问题有两种方式:
<span>
一致。 .box {font-size: 24px;}
<span>
对齐方式,span {vertical-align: top;}
示例:inline-block对齐方式
<style>
.ib-baseline {
display: inline-block;
height: 100px;
width: 100px;
border: 1px solid red;
}
</style>
<body>
<div class="ib-baseline"></div>
<div class="ib-baseline">x-baseline</div>
</body>
同样是由于vertical导致,可以修改 vertical-align: top;
来解决上述问题!
类型 | 属性值 |
---|---|
线类 | baseline(默认值)、top、middle、bottom |
文本类 | text-top、text-bottom |
上标下标类 | sub、super |
数值百分比类 | 如 20px、2em、20% 等 |
css中凡是百分比,均是一个相对计算值。margin
和 padding
是相对于 width
计算的;line-height
是相对于 font-size
计算的;vertical-align
百分比是相对于 line-height
值计算的。
图片下边缘问题空隙问题
【原因】:内联元素默认都是沿着字母x的下边缘对齐的;对于图片等替换元素,往往使用元素本身的下边缘作为基线;字符本身具有高度(受 line-height 影响)
针对vertical-align图片块级化:
display: block; margin: auto;
修改图片对齐方式:vertical-align: bottom;
针对line-height容器line-height足够小:line-height: 0
容器font-size足够小:font-size: 0
【line-height由font-size决定】
参考地址:https://www.zhangxinxu.com/wordpress/2015/08/css-deep-understand-vertical-align-and-line-height/
前面提及了line-height
的百分比是由 font-size
计算而得,这里就一并简述一下。
字体单位 | 说明 |
---|---|
em | 1em等于当前元素所在font-size计算值(相对于当前元素) |
rem | 1em等于根元素所在font-size计算值(相对于根元素) |
h1 {
font-size: 2em;
margin: 0.5em;
}
如果根元素的 font-size
为16px,此时margin为16px,并不是8px。2 * 16 * 0.5
,当前元素的 font-size
为32px,然后再乘以0.5.
Chrome浏览器下允许字体最小为12px,小于12px统一被认为为12px,0除外!
仅对内联元素元素有效,且仅对第一行内联盒子内容有效。
<style>
.container {
width: 200px;
border: 1px solid red;
text-indent: -3em;
padding-left: 3em;
}
</style>
<body>
<div class="container">
<p>提问:who are you?</p>
<p>回答:爱谁谁,管你啥事,你是谁?</p>
<p>提问:我是我!</p>
<p>提问:...</p>
</div>
</body>
默认值为normal,作用于所有字符,具有继承性,可以支持负值。letter-spacing与字符动效实例
仅作用于空格字符。
word-break: break-all;
所有都换行。word-wrap: break-word;
如果存在可换行点(空格、中文)之类的,可换行(英文不换行)。white-space
声明如何处理元素内的空白字符(空格、回车、Tab),其可以决定图文内容是否一行显示。
属性 | 换行 | 空格和制表 | 文字环绕 |
---|---|---|---|
normal | 合并 | 合并 | 环绕 |
nowrap | 合并 | 合并 | 不环绕 |
pre | 保留 | 保留 | 不环绕 |
pre-wrap | 保留 | 保留 | 环绕 |
pre-line | 保留 | 合并 | 环绕 |
inline-block
元素的包裹性处理text-overflow: ellipsis; white-space: nowrap;
text-align:justify;
两端对齐,要满足一是有分隔点如空格;二是超过一行内容。
属性值 | 说明 |
---|---|
underline | 下划线 |
overline | 上划线 |
line-through | 中划线 |
下划线经常会和中文文字的下边缘粘连在一起,可以通过 border-bottom
解决该问题。
其专为英文字符设计,uppercase全部大写,lowercase全部小写。
示例:验证码输入,全部转为大写
input {
text-transform: uppercase;
}
伪元素:before和:after添加的内容默认是inline元素
box-sizing: border-box;
CSS2.1规范中描述:content box环绕着width和height给定的矩形!
默认值为auto,其有4种不同的表现:
<div>
的宽度默认是100%于父级容器的;table-layout
为auto的表格中。中文是随便断的,英文单词不能断;white-space: nowrap
;a {
display: block;
width: 100%;
}
块元素默认占据一行,无需设置width: 100%
,设置后反而会失去流动性(margin/border/padding和content内容区域自动分配水平空间的机制)。
position为absolute或fixed元素的宽度表现是包裹,宽度由内部尺寸决定。
对于非替换元素,当left: 0; right: 0; top: 0; bottom: 0;
同时存在的时候,元素的宽度表现为“格式化宽度”,宽度大小相对于最近的具有定位特性(position属性值不是static)的祖先元素计算。格式化宽度具有完全的流体性。
替换元素:内容可以被替换,
<img>、<object>、<video>、<iframe>、<textarea>、<input>
元素尺寸由内部元素决定,但永远小于“包含块”容器的尺寸。inline-block元素、浮动元素以及绝对定位元素都具有包裹性!
示例:文字少的时候居中显示;文字超过一行的时候居左显示。
<style>
.box {
width: 100px;
height: 100px;
border: 1px solid red;
text-align: center;
}
.content {
display: inline-block;
text-align: left;
}
</style>
<div class="box">
<div class="content">纸上得来终觉浅,绝知此事要躬行</div>
</div>
.box{text-align: center;}
决定了$('.content')
的水平对齐方式为居中对齐;.box{text-align: left;}
决定了文字的水平对齐方式为居左。利用inline-block
的包裹特性即可实现(内容过多会自动沾满整行,且分行展示(
水平对齐:内联元素使用
text-align
;块级元素使用margin
。
css世界中,图片和文字的权重远大于布局,因此width: auto
时宽度永远不会为0。
① 东亚文字最小宽度为每个汉字的宽度;
② 西方文字最小宽度为连续的英文字符,终止于空格、短横线、问号以及非英文字符;word-break: break-all;
③ 替换元素的最小宽度为该元素内容本身的宽度。
<style>
.ao, .to {
display: inline-block;
width: 0;
transform: rotate(-90deg);
margin: 45px;
}
.ao:before {
content: 'love 我 love';
outline: 1px solid red;
color: #fff;
}
.to:after {
content: '我 love 你';
outline: 1px solid red;
color: #fff;
}
</style>
<div class="ao"></div>
<div class="to"></div>
最大宽度实际等同于包裹性元素设置white-space:nowrap;
声明后的宽度。如果内部没有块级元素或者块级元素没有设置宽度,则“最大宽度”实际上是最大的连续内联盒子的宽度。
连续内联盒子:全部都是内联级别的一个或一堆元素,中间没有任何的换行标签
<br>
或其他的块级元素。
width独立占用一层标签,而padding、border、margin利用流动性在内部自适应呈现。
.father {
width: 102px;
}
.son {
border: 1px solid;
padding: 20px;
}
这样对于增加padding之类的无需修改内部值。box-sizing: border-box;
也可以达到类似的效果!需要注意的是,当元素有水平margin时,box-sizing不能完全做到无计算,而宽度分离可以!
替换元素(上述已提及)的特性之一就是尺寸由内部元素决定!且无论其display属性值时inline还是block。需要说明的是,对于非替换元素,如果其display为block,则会就有流动性,宽度由外部尺寸决定!所以对于替换元素来说,
box-sizing: border-box;
大有用武之地!input, textarea, img, video, object { box-sizing: border-box; width: 100%; }
对于width属性,就算父级元素width为auto,其百分比值也是支持的;对于height属性,如果父级元素为auto,只要子元素在文档流中,其百分比值完全被忽略掉!【PS:脱离文档流的方式:float浮动;absolute或fixed定位】
div {
height: 100%;
position: absolute;
}
注意:绝对定位的高度百分比计算是相对于padding-box的(即,padding的值也计算在内);非绝对定位元素则是相对于content-box计算的!
<div style="height: 100px; padding: 10px;">
<div style="height: 100%;"></div>
</div>
<div style="height: 100px; position: relative; padding: 10px;">
<div style="height: 100%; position: absolute;"></div>
</div>
内部div的高度分别为:100px和120px!
示例:点击图片两侧,分别获取上一张和下一张图片
<style>
.box {
position: relative;
display: inline-block;
}
.pre, .next {
position: absolute;
top: 0;
height: 100%; width: 50%;
opacity: 0.5;
}
.pre {
background-color: #cd0000;
left: 0;
}
.next {
background-color: #34538b;
right: 0;
}
</style>
<div class="box">
<a href=":;" class="pre">上一张</a>
<a href=":;" class="next">下一张</a>
<img src="../../../images/1.jpg" alt="风景">
</div>
利用inline-block的包裹性,覆盖整个图片区域!
min-width/min-height的初始值是auto,max-width/max-height的初始值是none。
示例:任意高度元素的展开收起动画技术
<style>
.element {
max-height: 0;
overflow: hidden;
transition: max-height 2s;
}
:checked ~ .element {
max-height: 666px;
}
</style>
<input id="check" type="checkbox">
<p>纸上得来终觉浅,绝知此事要躬行...</p>
<div class="element"><p>come on!</p></div>
<label for="check" class="check-in">更多↓</label>
<label for="check" class="check-out">收起↑</label>
利用checkbox来避免了事件触发,同时通过max-height来达到相应的效果,max-height值应尽量和最大值靠近,否则会有延迟的效果~~~
关于具体的height相关内容,可以参考:css-height
盒尺寸4个盒子 content box、padding box、border box、margin box对应CSS世界中的content、padding、border和margin属性,我们称之为“盒尺寸四大家族”。
替换元素:内容可以被替换,
<img>、<object>、<video>、<iframe>、<textarea>、<input>
vertical-align
的默认值为baseline(x下边缘),但对于替换元素而言往往不可能含有字符x,因此其基线被硬生生定义成了元素的下边缘,这就是图片、文字不能对齐的原因。
替换元素尺寸从内而外分为3类:固有尺寸(源本身的宽度和高度)、HTML尺寸(HTML标签的width和height属性)和CSS尺寸(CSS中的widht和height以及max-/min-)其优先级为:CSS尺寸 > HTML尺寸 > 固有尺寸
<style>img {display: block;}</style>
<img src="1.png">
上述img为block,但是其width不会100%容器!!!而是其内容固有尺寸!!!
设定width和height对影响图片尺寸并不是改变其固有尺寸,而是因为图片的content适配方式决定
属性值 | 说明 |
---|---|
| 默认值,填充作为适配HTML尺寸和CSS尺寸 |
| 完全不受控制 |
| 保持比例,尽可能利用HTML尺寸 |
需要注意的是,content生成的内容:(1)无法选中、无法复制;(2)不能左右:empty伪类;(3)生成值无法获取。
CSS属性quotes可以制定open-quote和close-quote字符
:lang(ch) > q {quotes: '”' '“';}
:lang(en) > q {quotes: '"' '"';}
q:before {content: open-quote;}
q:after {content: close-quote}
可以,通过其快速实现上述<text-indent 提问回答>的示例!
img::after {
content: attr(alt)
}
.icon:before {
content: attr(data-title)
}
box-sizing
默认值为 content-box,所以padding会增加元素尺寸。
内联元素的padding只会影响水平方向,不会影响垂直方向。
a {
padding: 50px;
backgroud-color: #cd0000;
}
尺寸空间确实受padding影响了,但对上下元素的原本布局没有任何影响,仅仅是垂直方向发生了层叠。
CSS中很多场景或属性会出现这种不影响其他元素布局而出现层叠效果的现象。如,relative定位元素、盒阴影box-shadow以及outline等。其分为两类:一类是纯视觉层叠,不影响外部尺寸(box-shadow、outline);另一类则会影响外部尺寸(inline)。
区别方式:父级容器添加
overflow: auto;
,层叠区域超出父级容器时,有滚动条则会影响尺寸,没有则纯视觉。
article a {
padding: .25em 0;
}
增加点击区域,且对现有任何无任何影响。这里不能设置为inline-block,否则会引发行间距等问题。
示例:登录 | 注册
a + a:before {
content: '';
font-size: 0;
padding: 10px 3px 1px;
margin-left: 6px;
border-left: 1px solid gray;
}
padding支持百分比值,其相对于宽度计算。
/* 正方形 */
div { padding: 50%; }
/* 5:1比例固定的头图效果 */
.box {
padding: 10% 50%;
position: relative;
}
.box > img {
position: absolute;
width: 100%; height: 100%;
left: 0; top: 0;
}
和margin属性不同,padding属性是不支持负值的。
内联元素的垂直padding会让“幽灵空白节点”显现,内联元素默认的高度受font-size控制,可以通过font-size: 0;
来解决。
.icon-menu {
height: 10px;
width: 100px;
background-color: #333;
background-clip: content-box;
padding: 30px 0;
border-top: 10px solid #333;
border-bottom: 10px solid #333;
}
.icon-dot {
height: 100px;
width: 100px;
background-color: currentColor;
background-clip: content-box;
border: 10px solid;
border-radius: 50%;
padding: 10px;
}
这里的重点是:background-clip: content-box;
和padding配合,将背景剪切到内容区域外沿!!!
类别 | 盒模型 | jQuery方法 | 原生DOM API |
---|---|---|---|
元素尺寸 | border-box | $.height()/width() | offsetHeight/offsetWidth |
元素内部尺寸 | padding-box | $.innerHeight()/innerWidth() | clientHeight/clientWidth |
元素外部尺寸 | margin-box | $.outerHeight(true)/innerHeight(true) | 无 |
只有元素是“充分利用可用空间”时,margin才可以改变元素的可视尺寸。
<div style="width: 300px;">
<div style="margin: 0 -20px;"></div>
</div>
内部div的宽度为340px。CSS中默认流方向为水平方向,margin只能改变元素水平方向(内部)尺寸;但对于绝对定位元素,则水平和垂直都可以!
margin
为块级元素左中右对齐而设计的!text-align
为内联元素左中右对齐而设计的!!!
只要元素具有块状特性,margin就可以影响其外部尺寸(无论是水平还是垂直方向,不受默认流影响)。
<div style="height: 100px; padding: 50px 0;">
<img src="xxx.png" height="300">
</div>
底部没有50px的padding间隙。原因:Chrome浏览器是子元素超过content box尺寸触发滚动条显示;而IE和Firefox浏览器是超过padding box尺寸触发滚动条显示
margin合并的意义:在页面中任何地方嵌套或直接放入任何裸<div>
,都不会影响原来的块状布局。
外部容器宽度为300px,内部元素宽度100px。剩余100px则由margin: auto
补充闲置尺寸:
margin 的初始值大小是0,下述可实现块级元素右对齐!
{
width: 200px;
margin-left: auto;
}
margin: auto;
会在文档流的方向上,使元素居中。可以通过下面方式实现垂直居中:
.son {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
width: 200px; height: 100px;
margin: auto;
}
<tr>
和 <td>
元素或者设置 display 计算值是 table-cell 或 table-row 的元素 margin无效(table-caption、table或者inline-table没有此问题,甚至::first-letter伪元素也可以解析)img {
top: 10%; left: 30%;
/* 非定位方向,无效 */
margin-right: 30px;
}
一个普通元素,在默认流下,其定位方向是左侧及上方,此时只用margin-left和margin-top可以影响元素的定位。
属性 | 默认值 | 说明 |
---|---|---|
border-width | Medium 3px | 不支持百分比 |
border-style | none | |
border-color | 默认为color的值 | border-color 没有指定时,会使用当前元素的 color计算值 |
场景一:距离右下方50px
background默认是相对于左上角,在宽度不固定的情况下,我们可以通过 transparent 边框实现
border-right: 50px solid transparent;
background-position: 100% 50%;
Background 背景是相对于padding box 定位的!
场景二:增加点击区域
.icon {
width: 16px;
height: 16px;
border: 11px solid transparent;
}
此时的点击区域为38 * 38
场景三:简单图形绘制
向下三角
width: 0;
border: 10px solid;
border-color: #f30 transparent transparent;
正常的流内容、流布局已足够强大,但整理来说比较规规矩矩,有时我们需要一些特殊的布局(文字环绕、元素固定在某个位置),从而诞生了一些破坏流的属性,与此同时也产生了一些保护流的属性。
浮动的本质就是为了实现文字环绕效果!!!少滥用float,需要更多的挖掘CSS世界本身的“流动性”和“自适应性”。
float最显著的表现就是让父元素的高度塌陷。之所以产生塌陷,和float诞生的本质(文字环绕)是区分不开的!
"高度塌陷"可以让跟随的内容和浮动元素在一个水平线上;行框盒子如果和浮动元素的垂直高度有重叠,则行框盒子在正常定位下只会跟随浮动元素,而不会产生重叠。这是实现文字环绕的重要两点!
注意:上述是“行框盒子”即每行内联元素所在的盒子,并不是外部的块状盒子(块状盒子会发生重叠)。
clear: none | left | right | both
元素盒子的边不能和前面的浮动元素相邻。即,设置了clear属性的元素自身如何如何,而不是让float元素如何如何。
li {
list-style: none;
width: 20px; height: 20px;
margin: 5px; float: left;
}
li:nth-of-type(3) {
clear: both;
}
只分2行展示,而非3行展示。原因在于:clear属性是让自身不能和前面的浮动元素相邻。
<div class="container">
<div class="float">
<img src="D:\ligang\Blog\图片\beautiful.jpg">
</div>
这个问题有点棘手,处理方式千万种,但是要懂得根源问题~~~
</div>
<div>
通过我来确认问题是否解决!
</div>
.container {
height: 64px;
border: 1px solid #444;
}
.float {
float: left;
}
.float img {
width: 60px;
height: 64px;
}
我们知道出现上面现象,是由于内联状态下图片底部有间隙使得浮动元素高度高于64px,从而产生了文字环绕!(这里通过修改img的vertical-align为bottom可以完美解决)。
.container:after {
content: '';
display: table
clear: both;
}
通过设置clear: both;
清除浮动,但依然错位,高度高于64px,产生文字环绕!
BFC(block formatting context),块级格式化上下文。BFC是Web页面 CSS 视觉渲染的一部分,用于决定块盒子的布局及浮动相互影响范围的一个区域。如果一个元素具有了BFC,内部子元素再怎么翻江倒海,都不会影响外部的元素。因此,BFC元素之间是不可能发生margin重叠的!
<html>
根元素;换言之,只要元素符合上面任意一个条件,就无须使用clear: both;
属性去清楚浮动的影响了。
将上述.container
元素设置满足上述任意条件(如,display: inline-block;
或者overflow: hidden;
等),都可以实现通过我来确认问题是否解决!都居左显示,但.container
元素高度依然高于64px。
作用:该部分参考自(可通过链接查看示例):CSS中重要的BFC
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。