一、序
CSS平时在项目中太不喜欢写了,尤其是类名,以至于一直写行内样式,导致的结果就是生疏、了解的少,平时写一个效果直接人麻了,没办法,学叭!!!
CSS版本:CSS2.1
二、元素与基本尺寸
(1)块级元素
特点: 一个块级元素会占据一行的空间,多个块级元素会换行展示
说明: 常见的块级元素有<div>、<li>、<table>,不过块级元素与 dispaly:block 的元素不是同一个概念,比如下面这两个,虽然它们的display的取值不同,但是它们都符合上面所说的特点,正由于存在这个特点,因此可以搭配伪元素来清除浮动
<li>:display:list-item<table>:display:table
<div class="box clear">
<img src="D:\1.jpg" />
</div>
.box {
width: 30%;
padding: 10px;
background-color: #cd0000;
}
.box > img {
width: 200px;
float: left;
}
.clear:after {
content: "";
display: table;
clear: both;
}
能够清除浮动的原因: 块级元素有自己的布局规则,当块级元素的高度被浮动元素撑开的时候,它们会自适应浮动元素的高度,从而达到清除浮动的效果
注意:实际开发过程中,不要使用list-item这个来清除浮动,主要原因是兼容性问题,以前IE浏览器不支持伪元素的 display属性取list-item
==> list-item元素的符号 <==
理解: 最开始CSS里面只有块级盒子和内联盒子,就像男人和女人分工明确一样,块级盒子负责结构,内联盒子就负责内容,本以为块级元素只用一个块级盒子就能够使用了,没想到存在 list-ltem 这样的元素,它默认是需要展示一个项目符号的,那这样一个盒子解决不了问题,于是就像JS遇到新功能增加API一样,给 list-item 这样的元素再增加一个盒子,叫做附加盒子,它是用来放置那些项目符号的,本以为这样就结束了,没想到遇到一个BOSS,就是 inline-block 这样的元素,它既有块级盒子的特点,又有内联盒子的特点,现在所创建的三个盒子解决不了问题,因此继续照葫芦画瓢,给CSS世界中的每个元素都增加一个盒子,然后每个元素都有外在盒子和容器盒子两部分组成,外在盒子控制元素是否换行还是一行展示,内在盒子就负责元素的宽高、内容呈现什么的;这样下面这些元素实际由这些盒子组成的(下面这些可以这样理解,但是没有这样的写法哈):
display:block<==> display:block - blockdisplay:table<==> display:block - table
(2)width 和 height
注意: 按照上面的理解,宽高都是设置在容器盒子上面的
==> 了解 width: auto <==
说明: width 的默认值是 auto,它表示元素的宽度根据内容自动的调整
<== 常见表现 ==>
充分利用可用空间: 比如<div>、<p>这些元素的宽度默认是父级容器的100%,它也叫做fill-available
<div class="currentWidth">
<div class="divColor">这是一个div标签</div>
<p class="pColor">这是一个p标签</p>
</div>
.currentWidth {
width: 200px;
height: 100px;
background-color: black;
}
.divColor {
background-color: red;
}
.pColor {
background-color: yellow;
}
收缩和包裹: 也就是元素的宽度和高度会根据内容的大小自动调整,比如上面说的 inline-block 元素
<span class="spanColor">
这是一个 inline-block 元素
</span>
.spanColor {
background-color: black;
color: white;
}
收缩到最小: 也就是其自动调整大小的时候,是存在一个最小值的,比如下面这个由于元素规定的宽度只能够放下一个文字,因此它就从一行收缩成一列了,这种特效叫做min-content
<table>
<tr>
<td>就1列就1列就1列就1列就1列</td>
</tr>
</table>
table {
width: 280px;
margin: 0 auto;
}
超出容器限制: 一般情况元素的宽度是不会超过父级容器的,除非有相关的设置,比如下面这样的;它也有一个专门的属性值叫做max-content
<div class="father">
<span class="child">
恰如一江春水向东流,流到断崖也不回头
</span>
</div>
.father {
width: 150px;
padding: 10px;
background-color: #cd0000;
white-space: nowrap;
}
.child {
display: inline-block;
padding: 5px;
background-color: #f0f3f9;
}
注意: 由于盒子分为里面的和外面的,那这应该是一个CSS中的一个常态,而不是特例,因此尺寸也分为内部尺寸和外部尺寸,也就是分别对应尺寸由内部元素决定和尺寸由外部元素决定这两种情况
区分方式:假设某个元素没有内容,如果其宽度是0,那么它就是应用的内部尺寸,否则就是外部尺寸
<== 外部尺寸 ==>
说明: 其代表是<div>元素,这种外部尺寸的块级元素有一个特点,就是如果没有设置宽度,其margin、border、padding和content内容区域会自动分配水平空间,一旦设置宽度后,这个特点就失效了
<div style="width: 200px">
<h4>无宽度</h4>
<div class="nav">
<a href="" class="nav-a">导航1</a>
<a href="" class="nav-a">导航2</a>
<a href="" class="nav-a">导航3</a>
</div>
<h4>width:100%</h4>
<div class="nav">
<a href="" class="nav-a width">导航1</a>
<a href="" class="nav-a width">导航2</a>
<a href="" class="nav-a width">导航3</a>
</div>
</div>
.width {
width: 100%;
}
.nav {
background-color: #cd0000;
}
.nav-a {
display: block;
margin: 0 10px;
padding: 9px 10px;
border-bottom: 1px solid #b70000;
border-top: 1px solid #de3636;
color: #fff;
}
注意: 宽度这个属性慎用,从上面的例子可以看出来,毕竟少了代码、少了计算、少了维护,这样不好嘛
<== 内部尺寸 ==>
包裹性和自适应性: 假设元素应用的是内部尺寸,那么其元素的宽度会由里面的内容来决定,就是包裹性,但是,如果不对内部元素的宽度进行任何设置的话,那么其容器的宽度,这也就是自适应性,这两个特点对应的是 inline-block 元素,其代表是按钮;
按钮的特点:按钮文字越多会越宽,如果文字足够多,那么会在容器的宽度处自动换行
<div class="width">
<button>按钮</button>
<button>文字超级多啊!!!!!!!!!!!</button>
</div>
.width {
width: 100px;
}
包裹性的应用:假设某个模块中的内容不固定,文字少的时候居中显示,多的时候居左显示
<div class="box">
<p class="content">
文字内容
</p>
<p class="content">
文字内容、文字内容、文字内容
</p>
</div>
/* 由于居中显示这段文字,它最开始文字少,宽度不够占满盒子的宽度 */
/* 因此会呈现居中展示,当文字多之后,p元素的宽度会占满div,之后 */
/* 超过的部分换行,由于p设置左对齐,因此超出部分会左对齐显示 */
.box {
width: 200px;
padding: 10px;
background-color: #cd0000;
text-align: center;
}
.content {
display: inline-block;
text-align: left;
}
最小宽度: 指的是元素最合适的最小宽度,常呈现在图片和文字上,比如在一个宽度为0的容器中,其里面文字内容的宽度是0嘛,其实并不是,因为其图片和文字在css中的权重是要大于布局的,其特点如下:
中文的最小宽度是每个汉字的宽度
英文的最小宽度由几个连续的英文字符组成,一般会终止于非英文字符,比如 display:inline-block,它会因为 - 而分成 display:inline 和 block 两个部分,由于 - 在英文的后面,因此其内容的最小宽度就是 display:inline- 这几个字符的宽度了
对于音视频和图片这种替换元素,其最小宽度就是元素内容本身的宽度
<div style="width: 0">
<p>display:inline-block</p>
</div>
最大宽度: 表示元素可以有的最大宽度,然后可以想下面这样简单的理解:
如果它只是一个 inline-block 这样的元素,那么它的最大宽度就是它设置 white-space: nowrap 后的宽度
如果是一个嵌套的情况,但是嵌套的元素中没有块级元素或者给定宽度的元素,那么它的最大宽度就是一个或者一些 inline 或者 inline- 的元素所组成的宽度,以换行符表示结束
<!-- 那么这里最大宽度就是换行符前面元素组合在一起时的宽度 -->
<div>
'内容'
<span>内容</span>
<button>内容</button>
<br />
'下一行'
<p>一段文字</p>
</div>
==> 宽度分离原则 <==
引入: 当给一个元素设置 width: 100px 的时候,根据前面所说的,这个会设置在内在盒子上面,而这个盒子又分为四个部分,分别是margin(背景透明)、border、padding和content,具体作用在哪一部分上面呢,答案是content,这是CSS2.1的规定,这里存在一个问题就是当我设置边框border和内边距padding的时候,设置的值会计算到元素content上面,如果不注意,可能就会出现空间不足导致页面的布局有问题,怎么解决呢,一般可以使用书写方式约束比如宽度分离原则的方法,不过想用好这个原则很难
做法: 宽度分离原则就是CSS中的width属性不能够与 padding/border 属性共存,具体做法就是width独占一层标签,然后 padding/border 利用 width:auto 的特性让其自动计算,从而避免每次都需要去更改计算值
<div style="width: 200px">
<p class="current">这是一段文本</p>
</div>
.current {
padding: 20px;
border: 1px solid red;
}
思考: 有什么办法不需要自己计算尺寸或者嵌套标签,也能够实现上面的规定呢,答案是使用box-sizing
==> box-sizing <==
说明: 简单理解就是改变了width作用的部分,上面说过宽度默认是作用在content上面的,所以box-sizing的默认值是content-box,那是不是这四部分都可以作用上去呢,很遗憾,只有border-box和content-box两种,当你设置box-sizing:border-box之后,所设置的宽度直接设置在border上面,这样content + padding + border = width,因此下面这些写法宽度是不变的;一般替换元素使用这个属性比较多。
.box1 {
width: 100px;
box-sizing: border-box;
}
.box2 {
width: 100px;
box-sizing: border-box;
border: 1px solid red;
}
.box3 {
width: 100px;
box-sizing: border-box;
border: 1px solid red;
padding: 2px;
}
==> height: 100% <==
说明: 对于HTML中的元素来说,如果想要它的百分比高度能够生效,那么其父级需要有一个可以生效的值才可以,不然是没有效果的,写上去也是多余的
html,
body {
/* 没有这个你会发现你的图片出不来 */
height: 100%;
}
div {
height: 100%;
background: url("D:/1.jpg");
}
<div />
问题:那么为什么会导致设置的高度失效呢
解释: 在规定中是这样说的,如果元素没有显式指定高度,让高度由其内容来决定,并且该元素没有使用绝对定位,则高度的计算值默认为auto,所以这个值在进行百分比计算的时候肯定是算不出来的,因此也就会失效了
(3)min/max 的 height/width
说明: 这里说的是 min-height、min-width、max-height和max-width 这四个属性,它们和 height / width有很多的共性,因此说一些和这两个值不一样的东西
==> 区别 <==
使用: min-width 和 max-width 出现的场景一定是自适应布局或者是流体布局,如果是常见的宽高定死的砖头式布局,它们就没法使用了,因为这两个是具有边界行为的属性,所以没有变化自然无法触发
初始值: min-width/min-height 的初始值是
auto,而max-width/max-height 的初始值是none覆盖规则: max-width 会
覆盖width,即使你是 width !important,也会被覆盖掉;其次,如果 min-width 和 max-width 之间存在冲突,min-width优先
==> max-heigth 做动画 <==
说明: 一般用于制作展开收起这种动画,常见做法是使用height + overflow,但是这样做存在一个问题,就是这种动画的内容是不固定的,因此高度不能定死,那么就需要使用 height:auto 来表示,但是从最开始没有高度的0到auto,这之间是无法进行计算的,因此使用过渡属性就会失效,那么动画就很生硬,因此可以使用max-height来替代,这样由于值是可以计算的,也就是过渡属性能够作用上去,比如下面这样的:
<input id="check" type="checkbox" />
<div class="element">
<p>display:table-cell其他...</p>
</div>
<label for="check" class="check-in">
更多↓
</label>
.element {
max-height: 0;
overflow: hidden;
transition: max-height 1s;
background: red;
}
/* 这个表示当有复选框被选中的时候,将后面的样式规则应用到 */
/* 具有类名 element 的元素上面去 */
:checked ~ .element {
max-height: 666px;
}
注意: 在使用的狮虎max-height设置的值不能过大,否则你会看见效果延迟,比如上面这个,在收起的时候会发现要过一会儿才看到动画的效果,因为这段时间是那些超出可见元素的高度的过渡,导致你看不见效果,所以最好使用足够安全的值,来避免这一情况的发生
(4)内联元素
理解: 内联元素的内联指的是外在盒子,也就是外在盒子需要表现为 inline 这样的,因此display属性为inline、inline-block、inline-table都是内联元素,而不是特指inline这一种
显示特点: 可以和文字在一行显示
==> 内联盒模型 <==
举例:
<p>这是一行普通的文字,这里有个<em>em</em>标签。</p>
<== 内容区域 ==>
说明: 这是指一种环绕文字的盒子,它是不可见的,盒子大小仅受字符本身特性控制,本质上是一个字符盒子,但是对于像图片这样的替换元素,由于内容不是文字,因此也不存在字符盒子,那么对于这些元素,其内容区域可以看成是元素本身
<== 内联盒子 ==>
说明: 这里的盒子指的是外在盒子,用于决定元素是内联还是块级,如果细分还可以分为内联盒子和匿名内联盒子,如果外部套头内联标签,则属于内联盒子(红色部分),如果只是光秃秃的文字,那么就是匿名内联盒子(黄色部分),注意,如果前后标签两侧是块级标签,则是匿名块级盒子
<== 行框盒子 ==>
说明: 每一行是一个行框盒子,每一个盒子由一个一个内联盒子组成
<== 包含盒子 ==>
说明: <p>标签就是一个包含盒子,盒子由一个一个行框盒子组成,在规范中这个盒子称为包含块
==> 幽灵空白节点 <==
说明: 就是在行框盒子前面存在一个空白节点,这个节点永远透明,不占据任何宽度,看不见也无法通过JS来获取,比如下面这个现象:明明<span>元素的高度为0,但是div还是存在高度,因此证明了这个节点的存在
<div>
<span></span>
</div>
div {
background-color: #abcdef;
}
span {
display: inline-block;
}
注意: 幽灵空白节点默认宽度为0,对于高度而言,如果没有显式的设置元素的 font-size 或者 line-height,则会以默认字体的 font-size 和 line-height 来初始化高度,也就是默认存在高度的
三、盒尺寸的三部分
说明: 这里所说的四部分分别指content、padding和margin,还有一个border,但是暂时没什么写的,后面再补
(1)content
==> content与替换元素 <==
<== 替换元素是啥 ==>
理解: 根据是否具有可替换的内容可以把元素分为替换元素和非替换元素,比如<img src='1.jpg'>,如果将 1.jpg 换成 2.jpg是不是内容就替换了,因此通过修改元素的某个属性能够使其呈现的内容可以被换成其它的内容的元素称为替换元素,常见的表单控件,音视频控件都是属于替换元素。
其它特点:
内容的外观
不受页面上CSS的影响,如果需要修改替换元素本身的外观,就需要使用浏览器自身暴露的样式接口才可以了替换元素在没有明确给定尺寸的情况下,自己的尺寸是存在
默认值的替换元素在很多CSS属性上面都会存在一套
自己的表现规则,比如 vertical-align,在非替换元素这里,表示字母 X 的下边缘作为基线,但是替换元素往往没有这个 X,因此就以元素的下边缘作为基线了
<== 替换元素的display ==>
说明: 所有替换元素都是内联水平元素,也就是替换元素和替换元素、替换元素和文字都可以在一行展示,不过在不同浏览器下其display的值会有所不同,下面列举常见的替换元素的值
| 元素 | Chrome | Firefox | IE |
|---|---|---|---|
| <img> | inline | inline | inline |
| <iframe> | inline | inline | inline |
| <video> | inline | inline | inline |
| <select> | inline-block | inline-block | inline-block |
| <input> | inline-block | inline | inline-block |
| <button> | inline-block | inline-block | inline-block |
| <textarea> | inline-block | inline | inline-block |
<== 替换元素尺寸理解 ==>
固有尺寸: 这个指的是替换元素原本的尺寸,比如图片不加任何修饰的放在页面上,它是有自己默认的高度和宽度的,这就是固有尺寸,对于表单类替换元素,固有尺寸可以理解为不加修饰的默认尺寸,比如input元素,你在页面上看到的大小就是它的固有尺寸。
HTML尺寸: 也就是替换元素的尺寸如果能够通过HTML原生属性来改变,那么这些属性就是HTML尺寸,比如下面这些:
<img width="300" height="100">
<input type="file" size="30">
CSS尺寸: 也就是通过CSS的宽度和高度相关的属性来设置元素的尺寸
使用规则: 这套规则对于内联替换元素和块级替换元素都适用
如果
没有CSS尺寸和HTMl尺寸,则使用固有尺寸作为最终的宽高如果
没有CSS尺寸,但是有HTML尺寸,则使用HTML尺寸作为最终的宽高如果
有CSS尺寸,则最终宽高由CSS属性决定如果元素
存在固定的宽高比例,那么只设置宽度或者高度,另一个属性会按照固定比例进行放大或者缩小如果元素
没有宽任何度,则元素的宽度为300,高度为200,宽高比为2:1的形式来占位
问题: 为什么初始化CSS的时候需要下面这样写
img {
display:inline-block
}
解释: 这是做兼容性处理的,比如一个<img>这样的标签,对于Firefox浏览器,它认为缺少src属性的不是替换元素,会将其作为一个普通的内联元素看待,因此使用的是内联元素的尺寸规则,自然设置宽高会无效的,但是在IE 和 Chrome中,设置宽高是会生效的,因此才有这样的兼容性处理
结论:替换元素的固有尺寸是无法改变的
理解: 以图片为例,图片中的content替换内容默认的适配方式是填充,也就是图片尺寸变化的本质是采用了填充作为适配HTML尺寸和CSS尺寸的方法,因此这也是为什么给图片设置值是生效的
<== 替/非替 换元素区别 ==>
替换元素是
不能使用伪元素的
src属性:
Firefox:如果<img>没有src属性,那么这个元素会当成内联元素看待,因此设置宽高不会生效
Chrome:如果需要Chrome跟上面有类似的行为,只需要存在一个不为空的alt属性就可以
IE:对于IE来说,它默认存在一个占位替换内容,当src属性缺失的时候,它会使用这个占位内容,也就是为什么没有src属性的时候它还是替换元素的表现,不过在高版本的IE浏览器中这个占位内容做了透明处理,你看不见而已
content属性: 替换元素之所以称为替换元素,是因为内容可替换,这里的内容指的是content属性所包含的内容,不过它改变的只是你看到的效果,比如我将图片一替换成图片二,但是右键保存的时候,保存的还是图片一;当然还可以将普通元素转换成替换元素,比如将一段文字通过content属性将其变成一张图片,因为引擎SEO抓取的还是之前的文字,因此对页面的可访问性没有任何的影响
<== content与替换元素 ==>
说明: content属性生成的对象称为匿名替换元素,其常用性质如下:
生成的文本是无法选中的、无法复制的,同时生成的文本也不能通过搜索引擎抓取,因此重要的信息不要使用content属性生成,这对其访问性和SEO不是很友好,一般只用来生成无关紧要的内容
content动态生成的值无法获取
==> content与内容生成 <==
说明: content属性大多数是用在::before和::after这两个伪元素中
<== 辅助元素生成 ==>
说明: 使用的时候重点在于伪元素本身,而不是content里面的内容,所以一般将其属性值设置为''就好,常见的应用一个是清除浮动带来的影响
/* 然后将这个class放到浮动元素的父元素上就可以了 */
.clear:after {
content: "";
display: table; /* 也可以是'block' */
clear: both;
}
<== 字符内容生成 ==>
说明: 就是直接写入字符内容,中英文都可以,常见的应用是配合@font-face来实现图标字体;当然除了常规字符之外,还可以插入Unicode字符,比如使用换行符\A来做一点点动画
举例: 动态加载页面的时候,可能会使用正在加载...这样的文字,如果只是一个静态的,那么时间久了就会带来一种不好的感觉,毕竟用户的耐心可能有限,因此可以让...动起来
正在加载中
<dot>...</dot>
dot {
display: inline-block;
height: 1em;
line-height: 1;
text-align: left;
vertical-align: -0.25em;
overflow: hidden;
}
dot::before {
display: block;
content: "...\A..\A.";
white-space: pre-wrap;
animation: dot 3s infinite step-start both;
}
@keyframes dot {
33% {
transform: translateY(-2em);
}
66% {
transform: translateY(-1em);
}
}
<== attr属性获取 ==>
说明: 可以通过attr函数来获取某个元素的属性,一般在生成内容的伪元素像::before和::after里面的content属性这里使用,然后就能将获取的内容生成在页面上,比如
<img alt="获取属性值" />
img::after {
content: attr(alt);
}
==> content计数器 <==
说明: 这个指的是使用CSS实现随着元素数目增多,数值也跟着变大的效果,对于计数器而言,首先需要知道它叫什么,不然怎么使用呢,这个对应计数器属性为counter-reset,其次需要知道计数的规则是怎样的,这个对应属性content-increment,这样就创建好了一个计数器,最后就是使用它了,这个则对应一个方法就是counter() / counters(),这两个方法主要是显示计数的值的
<== counter-reset ==>
作用: 其主要目的是给计数器起名字,当然也可以告诉计数器从那个数字开始计数,默认是从0开始
注意: 在每次计数的过程中,计数器具有唯一性,也就是中途如果换了计数器或者重新使用计数器,则会重新计数,并且如果计数器所在的标签里面嵌套多层,它的作用范围是没有这么广的,最多只在影响它的子元素,如果需要影响子元素里面的东西,那么子元素里面也需要设置计数器才可以,这个在counters()这里有体现
/* 表示计数器名称是demo,起始默认值是2 */
.container {
counter-reset: demo 2
}
/* 也可以同时命名2个计数器,中间用空格隔开 */
.container {
counter-reset: demo1 2 demo2 3
}
对于从那个数字开始计数所支持的数字,浏览器不同也会得到不同的情况,比如IE和Firefox遇到小数会将其作为
0来看待,而Chrome则会向下取整
<== content-increment ==>
说明: 它是用来让计数器递增的,它的值可以是一个或者两个计数器的名称,每个名称后面可以紧跟一个数字,表示每次计数变化的值,这个值可以为负数,如果一次使用多个计数器,则每个计数器之间用空格隔开,跟上面一样的,最后,默认递增的值为1
递增: 简单来说就是每次在样式中出现content-increment,那么计数器的值就会加1
/* 这样用counter()输出的时候值就是3了 */
.container {
counter-reset: demo 2
/* 没有写递增的数量,默认是1 */
content-increment: demo
}
<== counter() ==>
说明: 这是一个方法,用于显示当前计数器的值,它有两个参数,第一个参数是name,表示计数器的名字,第二个参数是style,表示递增递减的可以不是数字,还可以是英文或者罗马文字等,这个参数的值与list-style-type的值是一致的
注意: content属性支持使用多个counter()方法
.container {
counter-reset: demo 2
content-increment: demo
}
.container:: before {
content: counter(demo, lower-roman) counter(demo, lower-roman)
}
<== counters() ==>
说明: 可以这么里面,如果上面是用来生成1.、2.、3.这样的序号,那么这个就是用来生成1.1、1.2、1.3这样的序号的,这个方法有三个参数,第一个是name,是计数器的名字,第二个是string,表示子序号联系的字符串,如果是1.1这样的序号,那么字符串就是 '.' 了,这个参数是必传的,第三个参数是style,跟上面一样,看个例子
<div class="reset">
<div class="counter">
第一层
<div class="counter">
<!-- 这里面表示第二层 -->
<div class="counter">第三层</div>
<div class="counter">第三层</div>
</div>
</div>
</div>
.reset {
padding-left: 20px;
counter-reset: wangxiaoer;
}
.counter::before {
content: counters(wangxiaoer, "-") ". ";
counter-increment: wangxiaoer;
}
理解: 这就是之前说的,对于嵌套,如果计数器只使用了一次,那么是得不到你想要的效果的,由于一个计数器只能影响一层子元素,那么要生成1-1这样的序号,以上面为例,就需要第二层需要使用计数器,可以理解成在此处将之前计数器计数到此处的值保存起来,然后给它的子元素使用,按上面的例子来说,运行到第一层的时候,得到的序号是1,那么在第二层再使用同样的计数器就将其保存下来,在第三层开始计数的时候前面是存在一个1的,由于重新计数,那么第三次就是1-1了
<div class="reset">
<div class="counter">
第一层
<div class="reset">
<!-- 这里面表示第二层 -->
<div class="counter">第三层</div>
<div class="counter">第三层</div>
</div>
</div>
</div>
注意: 子元素中出现计数器,那么元素的嵌套结构就会改变,因此上面具有.reset的元素和具有.counter的元素只能是前者是父元素,后者是子元素,这样的嵌套关系,否则就会出现嵌套出错的问题,当然父元素或者是子元素它们之间作为兄弟是没关系的,这一点需要注意
(2)padding
说明: 这个是内间距,就是内容与边框之间的部分,它是透明的,可以将其理解成商品与包装盒之间那层起保护作用的海绵
==> padding 与元素尺寸 <==
<== 块级元素 ==>
注意: CSS默认使用的是content-box,所以使用padding会增加元素的尺寸,那是不是使用border-box元素尺寸就不会变化呢,答案是否定的,当padding值足够大的时候,width可能会失效,比如:
<p>这是一个块级元素</p>
p {
width: 80px;
padding: 20px 60px;
box-sizing: border-box;
background: red;
}
解释: padding值的和大于width,导致width失效,因此其宽度为120px,里面元素则表现首选最小宽度,这个前面提到过
<== 内联元素 ==>
说明: 内联元素没有可视高度和可视宽度的说法,其垂直方向上的行为表现完全受line-heigth和vertical-align的影响,不过垂直方向也受padding的影响,只不过是影响视觉表现,也就是不影响页面的布局,比如:
<a>这是一个内联元素</a>
<p>这是一个块级元素</p>
a {
padding: 60px;
background-color: #cd0000;
color: #fff;
}
p {
padding: 60px;
background: #abcdef;
color: #fff;
}
理解: 这种是纯视觉层叠,也就是不会影响外部尺寸,比如这里的垂直方向的padding;还有一种是非纯视觉层叠,它会影响外部的尺寸,比如box-shadow;区分很简单,就是给父容器设置overflow:auto,如果层叠区域超出父容器的时候,没有出现滚动条,就是前者,否则就是后者
举例: 使用内联元素的padding实现高度可控的分割线
<a href="">登录</a><a href="">注册</a>
/* 选择在每个 a 元素之后的第一个 a 元素之前的元素 */
a + a:before {
content: "";
font-size: 0;
/* 然后通过margin和padding来控制它的位置 */
padding: 10px 3px 1px;
margin-left: 6px;
/* 通过边框来生成实线 */
border-left: 1px solid gray;
}
==> padding 的 % <==
<== 块级元素 ==>
与margin的差异:
- 不支持负值
- %是相对于宽度进行计算的
举例: 实现一个响应式图片展示的效果,也就是在不同屏幕下图片展示的比例是一定的
<div class="box">
<img src="D:\1.jpg" />
</div>
.box {
/* 由于都是使用%,那么这里就用padding来给父元素高度, */
/* 以此提供具体的值给图片使用 */
padding: 10% 50%;
/* 目的:为了图片在父容器内铺满,并且保持宽高比例 */
position: relative;
}
.box > img {
/* 让其参照父元素来设置 */
position: absolute;
/* 使图片铺满父容器 */
width: 100%;
height: 100%;
/* 将图片左上角与父容器右上角对齐,让图片能够铺满父容器 */
left: 0;
top: 0;
}
<== 内联元素 ==>
与margin的差异:
- % 相对于宽度进行计算
- 默认宽度和高度在细节上存在差异
- padding的值是会跟随行框盒子走的,也就是可能会出现换行的情况
现象一:
.box {
width: 300px;
border: 2px dashed #cd0000;
}
span {
padding: 50%;
background-color: gray;
}
<div class="box">
<span>有一些文字</span>
</div>
理解: 由于外部盒子的宽度是一定的,在使用padding的情况下,可能一行展示不完,内联元素开始换行,由于padding是跟着内联元素走的,因此就会出现这种五边形,也就理解为什么实际宽度与容器宽度不一致了;然后根据后来居上的层叠规则,有些字体可能就被覆盖掉了,因此出现看不见的情况;
现象二: 如果内联元素里面什么也没有会怎样呢,按理来说下面span的宽高应该是一致的,但是结果并不是这样,会发现它的高度多一点点,这是因为内联元素的垂直padding会让幽灵节点显现出来
.box {
border: 2px dashed #cd0000;
}
span {
padding: 50%;
background-color: gray;
}
<div class="box">
<span></span>
</div>
解决: 由于内联元素默认的高度由font-size的大小控制,因此将其设置为0,那么幽灵节点的高度自然也为0了,也就会出现正方形了
span {
padding: 50%;
font-size: 0;
background-color: gray;
}
(3)margin
==> 元素尺寸与相关布局 <==
<== 元素尺寸相关概念 ==>
元素尺寸:除了content以外还包含padding和border
内部尺寸:除了content以外还包含padding
外部尺寸:除了content以外还包含padding、border和margin
<== 内部尺寸 ==>
特点: 当元素设定了width或者保持包裹性的时候,margin对元素的尺寸没有影响,只有元素是充分利用可用空间的时候,才会有对尺寸影响,从下面的例子中可以看见margin的值可以为负数
<!-- 这里如果单是一个father的div,然后在这个上面设置margin -->
<!-- 那么它的宽度还是设定的300 -->
<div class="father">
<div class="son">111</div>
</div>
.father {
width: 300px;
}
.son {
margin: 0 -20px;
}
<== 外部尺寸 ==>
说明: 对于margin而言,无论元素有没有设置width或者height,在水平或者垂直方向上的元素尺寸都会有影响
兼容性问题的处理: 对于padding而言,如果容器可以滚动,那么在IE和Firefox浏览器下会忽略padding-bottom的值,而Chrome却不会,其原因如下;对于解决这个兼容性问题,就可以使用margin-bottom来解决
IE和Firefox:只有子元素超过padding box尺寸才会触发滚动条
Chrome:只有子元素超过content box尺寸才会触发滚动条
左右两列等高布局: 也就两侧的内容可以不同,但是高度一定相等,只不过下面这种做法只适合纯块级元素
<div class="column-box">
<div id="colLeft" class="column-left">
<h4>正方观点</h4>
<p>观点1</p>
<p>观点1</p>
<p>观点1</p>
<p>观点1</p>
<p>观点1</p>
<p>观点1</p>
<p>观点1</p>
<p>观点1</p>
</div>
<div id="colRight" class="column-right">
<h4>反方观点</h4>
<p>观点1</p>
</div>
</div>
.column-box {
display: flex;
/* 太高了,将不需要的部分隐藏起来 */
overflow: hidden;
}
.column-left,
.column-right {
width: 50%;
/* 这两句有一种先借9999px高度的空间,然后再还回去,±抵消掉, */
/* 也就不会影响页面的布局,但是获得了9999px高度的空间 */
margin-bottom: -9999px;
padding-bottom: 9999px;
}
.column-left {
background-color: #34538b;
}
.column-right {
background-color: #cd0000;
}
==> margin合并 <==
说明: 这个指的是块级元素垂直方向上的 margin-top 和 margin-bottom 有时会合并成一个外边距
<== 常见合并 ==>
相邻兄弟元素合并:
<p>第一行</p>
<p>第二行</p>
p {
margin: 10px 0;
}
父子元素之间的margin合并: 发生在父元素与第一个子元素或者最后一个子元素之间,此时设置的垂直方向上的margin好像设置到父元素上面一样
<div class="container">
<h2>这是一段文字</h2>
</div>
.container {
max-width: 1920px;
height: 384px;
background: url("D:/1.jpg") no-repeat;
}
.container > h2 {
font-size: 128px;
/* 设置完之后可以看到图片掉下来,也就是设置到父元素上面去了 */
margin-top: 100px;
color: white;
}
上外边距或者下外边距合并的处理方法:
- 常见做法是父元素设置成块级格式化上下文元素
- 父元素和发生合并边距元素之间使用内联元素进行分隔
- 或者给父元素设置高度
- 或者父元素设置 border-top/bottom,依据情况而定
- 或者父元素设置 padding-top/bottom,依据情况而定
空块级元素的margin合并: 也就是空的块级元素的 margin-top 和 margin-bottom 也会发生合并。
<div class="father">
<div class="son"></div>
</div>
.father {
overflow: hidden;
}
.son {
margin: 10px 0;
}
<== 计算规则 ==>
说明: 这里的合并规则不管是兄弟关系的合并还是父子关系的合并都是有效的
都是正值:间距取最大的一个margin值有正负值:将正负值进行相加,得到的结果就是间距都是负值:间距取最小的一个margin值
<== 合并的意义 ==>
margin存在的理解: HTML元素默认存在margin,这是为了使自己的文章、新闻啥的不会挤在一起,层次结构、段落就会清楚一些,阅读体验也就更好,所以如果你的网站是博客、新闻一类,尽量不要重置各种默认的margin值
合并意义:
兄弟元素margin合并:让图文信息的排版更加舒适自然
父子元素margin合并:在页面上任何地方插入或者直接放入任何<div>元素,都不会影响原来的块状布局
自身margin合并:避免不小心添加或者遗落的空标签影响页面的排版和布局
<== 理解margin: auto ==>
规定: 自动填充的特性在设置宽度和高度的时候就会失效
有时候元素没有设置width或者height,元素会自动填充
有时候元素没有设置width或者height,元素会自动填充对应的方位
<!-- 这个元素的宽度会自动填满容器 -->
<div />
div {
position: absolute;
/* 表示元素与它相定位元素的左侧对齐 */
left: 0;
/* 表示元素与它相定位元素的右侧对齐 */
right: 0;
/* 既然是对齐,那么元素宽度不够的时候就会自动的拉伸填充 */
/* 也就是说这个元素会自动填满容器 */
}
说明: 假设外部容器的宽度是300px,而元素本身只有200px,那么剩下的100px就会闲置下来,而margin: auto就是为了这个闲置的空间而设置的,它具体的填充规则如下
如果margin的一侧是定值,一侧是auto,则auto表示剩余空间大小
如果两侧都是auto,则平分剩余空间
.father {
width: 200px
}
/* 一侧为定值 */
.son {
width: 100px
margin-left: 30px
/* 此时auto表示70px */
margin-right: auto
}
/* 两侧都是auto */
.son {
width: 100px
/* 此时auto表示50px */
margin-left: auto
margin-right: auto
}
对齐效果: 通过上面的举例可以使用margin来完成左右对齐、水平居中对齐、垂直居中对齐
/* 左对齐 */
.son {
width: 200px
/* 距离右侧使用全部的闲置空间,也就是左对齐了 */
margin-right: auto
}
/* 右对齐同理 */
.son {
width: 200px
margin-left: auto
}
/* 水平居中对齐 */
.son {
width: 200px
/* 左右两侧评分这个闲置空间,以此达到左右的间距一致,因此形成了居中效果 */
margin-left: auto
margin-right: auto
}
/* 垂直居中 */
.father {
width: 300px;
height: 150px;
position: relative;
}
.son {
position: absolute;
/* 这个设置top、left、right、bottom的值跟上面的规则二哪里是一致的 */
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 200px;
height: 100px;
margin: auto;
}
<== 常见margin无效的场景 ==>
display: inline:如果是内联非替换元素,则垂直margin无效,如果是内联替换元素,则垂直margin有效并且不会出现margin合并的问题
<tr>和<td>:当设置display的值为table-cell、table-row的时候设置margin无效
margin合并:当发生margin合并的时候,除非设置的值比临界值大或者小,否则等于没有设置,这个可以参考上面合并的内容
绝对定位元素:对于绝对定位元素的非定位方位设置margin是无效的,比如我定位时只设置left的值,而你去设置margin-right的值的话,会发现设置的值无效
四、内联元素
(1)小写字母x
==> x-height 与基线 <==
说明: 在各种内联相关模型中,凡是涉及垂直方向上的排版或者对齐的,都离不开基线,而对于基线的定义,就是字母x下边缘线,与之相关的还有一个概念叫做x-height,这个指的是小写字母x的高度
注意: css中的 vertical-aline:middle 中的middle指的是基线往上0.5个x-height的地方,近似是x焦点的那个位置,由此这并不是绝对的垂直居中,而是一种近似的效果
==> 尺寸单位 ex <==
说明: 这是css中的一个单位,它指的是小写字母x的高度,也就是x-height,不过它受与字体相关的css影响,因此不用于限定元素尺寸,而是来用实现不受字体和字号影响的内联元素垂直居中的对齐效果
举例: 实现文字后面跟着一个小三角形图标的效果
/* 这种就算你修改字体大小和字体一样可以对齐 */
.icon-arrow {
display: inline-block;
width: 20px;
height: 1ex;
background: url("1..png") no-repeat center;
}
每页显示<i class="icon-arrow"></i>
(2)line-height
==> 理解line-height <==
<== 引入 ==>
问题: 默认空的<div>的高度是0,但是如果里面存在文字,那么高度就有了,那么这个高度是由什么决定的呢。答案是line-height,不过有些场景是通过font-size决定的,看下面的例子
<div class="test1">font-size 决定高度</div>
<div class="test2">line-height 决定高度</div>
.test1 {
font-size: 16px;
line-height: 0;
border: 1px solid #ccc;
background: #eee;
}
.test2 {
/* 可以看到这里的高度是由 line-height 决定的 */
font-size: 0;
line-height: 16px;
border: 1px solid #ccc;
background: #eee;
margin-top: 20px;
}
注意: 通常line-height的高度作用细节都是通过行距和半行距来解释的
<== 理解行距与半行距 ==>
解释: 在日常阅读的过程中,行距能够明确我们阅读的方向,让阅读文字轻松起来,它具体指的是上下两行文字之间的间距,而第一行是没有行距的,css中的行距就可以这么理解,不过文字的上方和下面都会存在,只不过高度是行距的一半,因此叫做半行距
<== 行距与半行距指哪 ==>
公式: 行距 = line-height - font-size
说明: 由于1em表示一个font-size的大小,所以它也称为em-box,一般来说,它跟看到的文字内容区域是不一样的,因为 em-box 只受 font-size 的影响,而所看到的文字内容受font-size、font-family的影响,因此内容区域的高度会更高一些,不过有一种情况除外,就是当字体是宋体的时候,宋体是一种方方正正的字体,因此它的文字内容区域与 em-box 的区域是相等的
.test {
font-family: simsun;
font-size: 24px;
line-height: 36px;
background-color: yellow;
}
.test > span {
background-color: white;
}
<div class="test">
<span>sphinx</span>
</div>
注意: 如果line-height的值没有单位,则表示几倍的font-size的大小,同时是不存在小数的,因此需要进行取整的操作
<== 结论 ==>
非替换元素和纯内联元素:可视高度由 line-height 决定
替换元素和块级元素:line-height不能影响这些元素本身的高度,只能改变元素里面内联级别元素占据的高度来实现高度的控制
==> 内联元素垂直居中 <==
说明: 这里的居中是近似居中的,因为文字字形的垂直中线位置普遍要比真正的行框盒子的垂直中线位置低,由于平时使用的字体大小都比较小,字体下沉一两个像素往往察觉不到,因此看上去是垂直居中的,实际上不是;另外由于行距在文字的上方和下方都存在,因此 line-height可以实现垂直居中
注意: 使用line-height进行文字垂直居中的时候与height是没有任何关系的
<== 单行文本居中 ==>
.title {
/* 实际的居中效果与height没有关系,只是提供一个建议值 */
height: 100px
line-height: 100px
}
<== 多行文本居中 ==>
.box {
width: 280px;
line-height: 120px;
background-color: #f0f3f9;
margin: auto;
}
.content {
/* 设置为inline-block是为了重置外部的line-height,使其为正常大小, */
/* 其次又能保持内联元素的特性,从而使用vertical-align属性,同时产生 */
/* 了一个行框盒子,每个盒子都会存在一个宽度为0的幽灵空白节点,从而使 */
/* 高度能够设置在这个幽灵节点上面 */
display: inline-block;
line-height: 20px;
margin: 0 20px;
/* 内联元素默认是基线对齐,通过这个属性将其改为垂直居中对齐, */
/* 不过这个对齐也是近似的 */
vertical-align: middle;
}
<!-- 多行文字使用一个标签包裹 -->
<div class="content">
基于行高实现的多行文字垂直居中效果,需要vertical-align属性帮助。
</div>
注意: 图片的垂直居中也可以这样做
==> line-height的取值 <==
说明: 这个属性的默认值是normal,本质上,它是一个变量,这个变量的值与 font-family 相关;除了默认值,还支持数值、百分比、长度值,它们的区别如下:
数值:最终计算值是和当前 font-size相乘后的值,这个数值会继承给它的子元素,也就是子元素的 line-height 的最终值都是会乘以这个数值倍率的
百分比:最终计算值是和当前 font-size相乘后的值,不过它够继承的是计算的结果 line-height,也就是子元素的行高 line-height 跟父元素的是一致的
长度值:也就是带单位的值,比如10px,1em这种,这个也是将行高继承下去,让子元素的 line-height是一样的
/* 虽然这三种得出的结果都是21px,但是对子元素的影响不同 */
body {
font-size: 14px
line-height: 1.5
}
body {
font-size: 14px
line-height: 150%
}
body {
font-size: 14px
line-height: 1.5em
}
/* 使用数值的行高 = 32px * 1.5 */
/* 使用百分比的行高 = 21px */
/* 使用长度值的行高 = 21px */
h3 {
font-size: 32px
}
<h3>计算举例<h3/>
推荐:
如果是一个重图文内容展示的网页或者是网站,例如博客、公众号这种,就使用数值作为单位,此时 line-height 可以设置
1.6 - 1.8之间如果是偏重于布局结构精致的网站,百分比和长度值都可以,如果使用长度值,推荐
20px,方便排版计算
==> line-height的大值性 <==
解释: 这里说的是内联元素的 line-height 如何设置,最终父元素的高度都是由数值最大的那个 line-height的子元素决定的,比如下面的例子:
.box {
line-height: 20px
}
.box span {
line-height: 96px
}
.box {
line-height: 96px
}
.box span {
line-height: 20px
}
<!-- 上面两种css的写法得到的结果是一样的,也就是.box的高度都是96px -->
<div class="box">
<span>内容</span>
</div>
理解: <span>是一个内联元素,因此自身是一个内联盒子,由于只要有内联盒子存在,就会存在一个行框盒子,而行框盒子前面存在一个宽度为0的幽灵空白节点,每次给box设置的值都会设置在这个上面,因为行框盒子的高度由高度最高的那个内联盒子决定,因此这里box的高度都是96px
(3)vertical-align
说明: 这个跟 line-height 的作用是紧密相关的,只要line-height发挥了作用,那么vertical-align也会发生作用,只是感觉不明显而已,看下面这个例子:
.box {
line-height: 32px;
}
.box > span {
font-size: 24px;
}
<!-- 此时这个box盒子的高度并不是32px,而是会大一点 -->
<!-- 这就是vertical-align作用的结果 -->
<div class="box">
<span>文字内容</span>
</div>
==> 基本的规则 <==
说明: 这个属性的属性值默认是baseline,也就是基线对齐,这里说一下它的数值百分比类的属性值,也就是20px、20em、20%这种,在渲染时这种属性值遵守的规则为根据计算值的不同,会相对于基线往上或者往下进行偏移,如果是正值就往上,反之就往下,那么0就是分界线了,也就是说vertical-align: baseline 和 vertical-align: 0是等价的
注意: 基线的定义是小写字母x的下边缘,因此内联元素都是沿着字母x的下边缘对齐的,对于图片这种替换元素,往往使用的是元素本身的下边缘线作为基线的;最后就是如果属性值是百分比,那么它是相对于元素本身的line-height来计算的
==> 发挥作用前提 <==
说明: 这个的前提条件就是只能应用于内联元素以及diaplay的值为table-cell的元素,也就是通常适用于span、strong、em、img、button、input、td等元素上面;块级元素是不支持的
.box {
height: 128px;
/* 居中对齐是相对于行框盒子的,这个盒子的高度由前面的幽灵空白节点撑开, */
/* 由于存在的默认高度比较小,而普通的高度是不会设置在这个节点上面的, */
/* 一般通过行高,来设置,因此在没有设置行高之前会看见图片是紧紧 */
/* 贴着容器的上面的 */
line-height: 128px;
}
.box > img {
height: 96px;
vertical-align: middle;
}
<div class="box">
<img src="D:1.jpg" width="96px" />
</div>
==> 与 line-height 的关系 <==
说明: 由于vertical-align的百分比值是相对于line-height计算的,因此只要出现内联元素,这两个属性就一定在作怪
<== 作怪的幽灵节点 ==>
举例: 为什么下面的容器高度不等于行高呢
.box {
line-height: 32px;
}
.box > span {
font-size: 24px;
}
<div class="box">
<span>文字</span>
</div>
解释: span元素前面存在一个幽灵空白节点,下面用字符x来表示,这样也能看出基线的位置,字母x和后面的文字内容分别在两个内联盒子里面,由于受到父元素行高的影响,因此两个内联盒子的高度都是32px,由于文字大小不同,其基线的位置也不一样,而元素默认是基线对齐的,因此当两个大小不同的文字元素在一起的时候,就会彼此上下位移,如果位移的举例足够大,超出行高的限制,就会出现意外的高度,也就是为什么这里的高度不是32px的原因了
<== 为何存在间隙 ==>
说明: 除了上面这种文字对齐导致的间隙还是下面这种图片产生额外的高度的情况,主要原因是幽灵空白节点、line-height、vertical-align三者一起作用导致的
作用细节: 假设行高与字体大小的差值存在正值,那么也就存在行距,行距过大就会导致半行距过大,由于图片这种替换元素是以元素自身底部对齐的,而一般的文字又是基线对齐,也就是与小写字母x的底部对齐,由于存在半行距,那么字母x的底部也存在半行距,由于这个行距是透明的,这样就会导致图片下面会存在间隙,这个间隙就可以理解为半行距,但实际的值应该是比这个略大的
<div class="box">
<img src="D:1.jpg" width="96px" />
</div>
<== 间隙的处理 ==>
图片块状化:由于上面三个要素都与内联元素相关,因此将其变成块状就没事啦
减小容器的行高或字体大小:因为行距与行高和字体大小都有关系,因此减小就是缩小字母x下面的半间距
设置其他的vertical-align值:这个主要是因为基线对齐,那换一个对齐方式不就行了
==> 常用的线类属性值 <==
<== inline-block 和 baseline ==>
说明: vertical-align属性的默认值是baseline,表示基线对齐,也就是文本类的内联元素就是小写字母x的下边缘,对于替换元素就是替换元素的下边缘,但如果是inlien-block元素,其基线规则如下:
如果里面存在内联元素:基线就是最后一行内联元素的基线
如果里面没有内联元素:基线就是元素的margin的底边缘,对于overflow不是visible的元素也是适用的
举例: 发现下面两个元素会不再一个水平线上对齐,原因就是它们的基线不一致所对齐导致的
.dib-baseline {
display: inline-block;
width: 150px;
height: 150px;
border: 1px solid #cad5eb;
background-color: #f0f3f9;
}
<span class="dib-baseline"></span>
<span class="dib-baseline">x-baseline</span>
<== top 和 bottom ==>
说明: 这两个是相反的,一个向上,一个向下,具体规则如下:
如果是内联元素:则与这一行位置最 高(低) 的内联元素 顶部(底部) 对齐
如果是 table-cell 元素:可以将它理解为td元素,则和tr的上边缘(下边缘)对齐
注意: 这里的边缘指行框盒子的边缘,如不是指容器的边缘,也就是如果两张相同的图片放在一起,有一张设置 vertical-align: bottom,这两张图片是底部对不了齐的,因为图片的前面存在幽灵空白节点,其底部存在间隙,因此对齐是参照间隙底部对齐的,所以存在对齐偏差
<== middle ==>
说明: 这个属性值是用来实现近似垂直居中的效果的,为什么这样说呢,先看它的规则再解释
内联元素:将元素的垂直中心点与行框盒子基线往上0.5个x-height处对齐
table-cell元素:将单元格填充盒子相对于外面的表格行居中对齐
解释: 这里主要说内联元素,因为在绝大数字体中,小写字母x的位置都是偏下面一点的,而font-size越大其偏移也就越多,因此才会造成近似垂直居中的现象,所以解决这种现象可以将字体大小设置为0就可以了
==> 了解标记类属性值 <==
<== sub 和 super ==>
说明: 这两个属性值表示元素的上标和下标,在html中存在相同作用的标签,分别是<sub>和<sup>,这两个标签的vertical-align对应的属性值为sub和super,前者主要用于数学公式、化学表达式这种情况,后者主要用于标注,也就这么一点作用了
哈哈哈<span class="top">上标</span>
<br />
H<span class="bottom">2</span>O
.bottom {
vertical-align: sub;
}
.top {
vertical-align: super;
}
==> 水平垂直居中的弹框 <==
效果: 无论浏览器尺寸如何、弹框尺寸如何,弹框永远水平垂直居中显示
.container {
/* 这部分主要用于填充背景色 */
/* 其次是让元素相对于浏览器窗口进行定位,也就是此时容器的左上角 */
/* 和浏览器的左上角是对齐的 */
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
/* 用于给一个浅灰色的背景 */
background-color: rgba(0, 0, 0, 0.5);
/* 字体大小变成0的时候,字母x就变成一个点,那么这个点就在container */
/* 的上边缘上面 */
font-size: 0;
/* 下面完成垂直居中了,这里就让其水平居中就好了 */
text-align: center;
}
.container:after {
/* 由于高度不确定,显然不能设置具体的行高,因此使用伪元素创建一个 */
/* 和外部容器一样高宽度为0的元素 */
content: "";
display: inline-block;
height: 100%;
/* 这里将元素的中线与字母x对齐,因为字母x在container的上边缘上面, */
/* 而这个元素的高度跟外面的容器是一致的,因此元素的一半会在container */
/* 的外面,不过由于对齐方式的更改,是以container的左上角开始对齐的, */
/* 所以元素与x会向下移动半个容器的举例,那么此时x就在容器的中垂线上 */
vertical-align: middle;
}
.dialog {
/* 这个是为了使用内联元素的对齐规则 */
display: inline-block;
/* 此时将元素的中线与x进行对齐,由于上面x已经在容器的中垂线上面, */
/* 因此元素的中线和容器container的中线重合,因此垂直居中对齐了 */
vertical-align: middle;
/* 方便看见容器的位置 */
background-color: #fff;
/* 显示容器内部字体 */
font-size: 14px;
}
<div class="container">
<div class="dialog">
<div class="content">内容范围</div>
</div>
</div>
五、文档流的破坏和保护
(1)浮动float
==> 了解本质与特性 <==
本质: 用于实现文字环绕的效果,所以对于布局层面在老版本的浏览器就会存在很多的问题。
特性: 它不存在margin合并的问题
包裹性:也就是浮动元素的子元素宽度如果不超过浮动元素的宽度,那么其里面的子元素的宽度就与浮动元素的宽度相同,这表现为包裹性;如果子元素的宽度超过浮动元素其父元素的宽度,则浮动元素的宽度就与其父元素的宽度相同,这表现为自适应性
块状化并格式上下文:也就是设置了float的元素它的display的值表现为block或者是table,相应的计算值可以参考下面的表
破坏文档流:这就是float的机制所在
| display的值 | 设置float后dispaly的值 |
|---|---|
| inline | block |
| inline-block | block |
| inline-table | table |
| table-row | block |
| table-row-group | block |
| table-column | block |
| table-column-group | block |
| table-cell | block |
| table-caption | block |
| table-header-group | block |
| table-footer-group | block |
==> 基础作用机制 <==
说明: 基础的机制有两条,一是浮动会使父元素的高度坍缩,二是行框盒子与浮动元素之间存在不可重叠的性质
机制一:高度坍缩
作用: 可以让跟随的文字内容和浮动元素在一个水平线上,从而形成文字环绕效果
.father {
width: 150px;
border: 1px solid red;
}
img {
float: left;
}
p {
width: 150px;
}
<div class="father">
<img src="D:1.jpg" alt="" width="100px" />
</div>
<p>这是一段测试内容,看看文字的环绕效果是怎样的</p>
机制一:不可重叠
说明: 这里指的是盛放内容部分的行框盒子与浮动元素之间是不可重叠的,但是与行框盒子外面的块级盒子是存在重叠部分的,将图片透明,给文字来点颜色就会看到这个效果
注意: 行框盒子里面内容的区域是被限制死的,在不改变布局的前提下,无法通过css将这个区域变大,比如下面设置的margin就没有效果了
p {
width: 150px;
margin-right: 20px;
}
p::first-line {
/* 将第一行的行框盒子给一个背景色 */
background: #abcdef;
}
==> 深入了解 <==
现象: 先看一段HTML片段,为什么会出现这种情况
<h3>
标题很长很长,来看一下浮动的效果怎样!!!!!!
<a href="">更多</a>
</h3>
h3 {
width: 140px;
height: 60px;
border: 1px solid red;
}
a {
float: right;
}
解释: 为什么浮动的对齐方式是这样的呢,首先需要了解两个概念浮动锚点和浮动参考,由于每一行都会产生一个行框盒子,不过上面的内容较多,沾满了三行,没有更多文字的内容,从而另起一行使用浮动锚点生成一个行框盒子,然后根据这个行框盒子对齐,从而表现这样的效果
浮动锚点:是浮动元素所在的文档流中的一个点,这个点本身并不浮动,就表现而言更像一个没有margin、border和padding的空的内联元素,也就起到产生行框盒子的作用了
浮动参考:浮动元素对齐参考的对象,在css中,这个对象是行框盒子,也就是浮动元素相对于当前的行框盒子进行定位,如果不存在行框盒子,那就使用浮动锚点来生成行框盒子,然后再进行对齐
==> 浮动与自适应布局 <==
说明: 简单来说就是浮动元素会与父元素贴贴,而且贴的很紧,父元素动浮动元素也会跟着动,那么布局就简单了,如果是两栏布局,一个元素给浮动,一个元素使用margin原理这个浮动元素就可以了,三栏布局就左右各一个浮动元素,然后中间元素同意使用margin将其远离这两个浮动元素就好,不过需要注意清除浮动带来的影响
(2)浮动的爹clear属性
==> 了解clear属性 <==
说明: 这个属性能够解决float属性带来的高度塌陷的问题,它的取值有四个,分别是:none、left、right、both,从字面意思来说是清除浮动的意思,但实质并不是这样,clear属性的定义是设置了clear属性的元素不能与前面的浮动元素相邻;也就是说浮动一直还在,看下面这个例子
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
/* 使用浮动进行布局 */
li {
width: 20px;
height: 20px;
margin: 5px;
float: left;
list-style: none;
background: #999;
}
/* 第三个li清除浮动 */
li:nth-of-type(3) {
clear: both;
}
注意: clear属性的right和left没啥用,都用both替代,因为对一个元素而言float的值不可能同时取left和right,然后根据定义clear属性对后面的浮动元素是不管的,因此当left的值有效的时候,right的值必定无效,那这样也等价于both了,反过来也是等效使用both,因此left和right几乎没啥使用的价值
==> clear属性的问题 <==
说明: clear属性只能使用在块级元素上面,而伪元素默认都是内联水平的,因此在借助伪元素清除浮动影响时需要设置display的值,将其变成块状的,取值可以有table、block、list-litm,但是由于both作用的本质不是清除浮动,所以可能存在以下现象,比如看下面这个例子
- 如果
clear:both元素前面的元素就是float元素,则margin-top即使设置很大,也不会看见任何效果clear:both后面的元素可能依旧存在文字环绕的现象
.father {
border: 2px solid red;
width: 100px;
height: 80px;
}
.father::after {
content: "";
display: table;
clear: both;
}
img {
float: left;
width: 60px;
height: 80px;
}
.father + div {
margin-top: -2px;
}
<!-- 其实造成这种原因的是图片下方还存在看不见的空白占位了 -->
<div class="father">
<img src="D:1.jpg" />
和图片一起的内容
</div>
<div>内容很多很多很多很多!!!!!!!!!</div>
(3)BFC
说明: 全称叫块级格式化上下文,可以将其理解为一个独立空间,这个空间表现为里面的子元素无论做任何操作都不会影响这个空间外面的元素,因此根据定义,它能够清除浮动并且不存在margin合并的问题
==> 常见触发条件 <==
float:right、left、bothoverflow:auto、scroll、hiddendisplay:table-cell、table-caption、inline-blockposition:absolute、fixed、sticky
==> 使用场景 <==
说明: 它的主要用途是用来做自适应布局,看下面的例子
<div class="father">
<img src="D:1.jpg" />
<div>内容很多很多很多很多!</div>
</div>
.father {
border: 2px solid red;
width: 150px;
height: 80px;
}
img {
float: left;
width: 60px;
}
.father div {
/* 这里不要使用margin-left去改变两者间的距离 */
overflow: hidden;
}
解释: 由于具有BFC特性的元素不会受到外部元素的影响,也不会影响外面的元素,因此这里的元素为了不和浮动元素产生任何的交集,会顺着浮动的边缘形成自己的独立空间,也就是会自动填充容器中除了浮动元素以外的剩余空间,形成自适应布局的效果,由于浮动元素的宽度不可控制,因此为了复用最好不要在BFC元素上面使用margin-指向浮动元素方向上的属性值,因为浮动元素宽度已变,这个属性的属性值就要变化,变成动态不可控了
<== 优点 ==>
由于空间独立导致其
容错性很强,比如内部去清除浮动的影响不会与float元素相互干扰从而影响布局由于自适应内容自动填满浮动以外的区域,所以
无需关注浮动元素的宽度,但是如果需要将两者间的间距弄大,注意margin的使用
<== 注意事项 ==>
说明: 理论上任何BFC元素和float元素相遇都可以自动填充形成自适应布局,但是大部分触发BFC的属性都会存在一些奇怪的特征,比如下面这些例子
float:left浮动元素本身BFC化,然而浮动元素存在破坏性和包裹性,所以会失去元素本身的自适应文档流的特性,因此无法实现自动填充容器的自适应布局
position:absolute脱离文档流,与非定位元素何难在一起相处
overflow:hidden唯一的问题在于容器盒子外面的元素可能会被隐藏掉,如果溢出隐藏的交互场景比例不是很高,还是能够作为常用的BFC布局属性
display:inline-block它会让元素尺寸包裹收缩,跟block水平的流动特性没有关联
(4)最佳解决overflow
说明: 清除浮动影响的最佳元素是overflow,而不是clear,它能够利用BFC的独立空间特性彻底解决浮动对外部或者里面元素的影响,但这个属性的本职工作在于指定块状容器元素内容溢出的部分是否需要隐藏起来,清除浮动带来的影响只不过是副业而言
==> 裁剪界限border box <==
说明: 也就是当子元素产出容器宽度高度限制的时候,裁剪的边界是border box的内边缘,而不是padding box的内边缘,看个例子,所以如果需要元素四周存在间隙的话,可以使用透明边框
<div class="box">
<img src="D:1.jpg" width="256" height="192" />
</div>
.box {
width: 200px;
height: 80px;
margin: auto;
padding: 10px;
border: 10px solid;
overflow: hidden;
}
==> overflow-x 和 overflow-y <==
说明: 这两个属性分别控制水平和垂直方向上的裁剪规则,取值和overflow一样,有下面这四个;不过需要注意不可能实现一个方向上进行溢出裁剪或者滚动,另一个方向上溢出显示的效果,因为除非两个值都是设置的visible,否则visible表现为auto
visible:默认值hidden:裁剪scroll:显示滚动条auto:宽度或者高度不足的时候显示滚动条
==> overflow 与滚动条 <==
说明: HTML中有两个便签是默认可以产生滚动条的,一个是根元素<html>,一个是文本域<textarea>,之所以可以出现滚动条是因为其默认的overflow属性的默认值是auto,在PC端,滚动条有以下结论
无论什么浏览器,滚动条默认是来自
<html>,而不是来自<body>这个滚动条是存在高度和宽度的,一般宽度为
17px
自定义滚动条: 以谷歌浏览器的滚动条为例,与自定义相关的几个属性如下;不过常用的就第1、3、5这三个属性而已
整体部分:::-webkit-scrollbar两端按钮:::-webkit-scrollbar-button外层轨道:::-webkit-scrollbar-track内层轨道:::-webkit-scrollbar-track-piece滚动滑块:::-webkit-scrollbar-thumb边角:::-webkit-scrollbar-corner。
==> 依赖overflow的效果 <==
<== 文本溢出隐藏 ==>
单行:
.ell {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
多行:
/* 一般用于支持 -webkit- 前缀的浏览器 */
.ell-rows-2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
==> overflow 与锚点定位 <==
说明: 锚点理解就是可以让页面定位到某个位置的点,一般在高度较高的页面中经常见到,比如自己举个例子,当我点击链接的时候,它会跳到锚点这个位置,这种跳转使用的是<a>的name属性完成的,还有一种是使用普通标签的id属性完成;一般链接中的这个值叫锚链值,锚链值都是以#开头的,这个值在URL中也有体现;而name和id属性则不需要,带这两个属性的元素叫锚点元素
<div class="box">
<!-- 这个表示回到页面的顶部 -->
<a href="#">点击</a>
<a href="#1">点击</a>
</div>
<a name="1">锚点</a>
.box {
height: 10000px;
}
<== 锚点定位的触发条件 ==>
URL地址中的锚链与锚点元素能够
对应上,也就是href中的值去掉#能够和id或者name属性中的值对应上,同时还需要存在交互行为,比如点击一个链接,改变地址栏中的锚链值等操作类似链接、按钮等可以被focus的元素在
被focus的时候也能够触发锚点定位,这种定位有一个特点就是如果定位的元素在浏览器的可视窗口里面,就不会触发浏览器可视窗口的滚动
<== 锚点定位的本质 ==>
说明: 其本质是通过改变容器滚动高度或者是宽度来实现的,也就是说锚点定位可以发生在普通容器上面,并且这种定位行为是由内而外的,比如下面这个例子
.box {
height: 120px;
width: 120px;
border: 1px solid #bbb;
overflow: auto;
}
.content {
height: 200px;
background: #eee;
}
<div class="box">
<div class="content"></div>
<h4 id="title">底部标题</h4>
</div>
<p>
<!-- 点击这里的时候上面的文字就会显示 -->
<a href="#title">点击测试</a>
</p>
注意: 由内而外以上面的例子来说就是如果box这个盒子也能够使用锚点定位进行滚动的话,那么先触发这个盒子里面锚点定位的效果,之后再触发box这个元素所在盒子的效果
<== hidden属性值 ==>
说明: overflow的三个属性值hidden、auto、scroll的差别在于有没有滚动条,也就是设置了overflow:hidden的元素依然可以滚动,只不过是没有滚动条而已,比如发生锚点定位
.box {
height: 120px;
width: 120px;
border: 1px solid #bbb;
/* 将这个属性改为hidden发现元素还是能够进行锚点定位 */
overflow: hidden;
}
<== 选项卡 ==>
说明: 由于锚点定位的本质是改变scrollTop或者是scrollLeft的值,因此可以根据锚点定位的两种方式做选项卡
缺点: 容器的高度是固定的
方式一:URL地址定位
说明: 就是简单让列表的大小和容器的可视大小一样大,这样就保证了每次只显示一个列表,然后通过锚点定位来进行相应的切换,这个还有一个缺点就是如果容器外面的可视窗口可以滚动,那么可能会出现跳动的情况
<div class="box">
<div class="list" id="one">1</div>
<div class="list" id="two">2</div>
<div class="list" id="three">3</div>
<div class="list" id="four">4</div>
</div>
<div class="link">
<a class="click" href="#one">1</a>
<a class="click" href="#two">2</a>
<a class="click" href="#three">3</a>
<a class="click" href="#four">4</a>
</div>
.box {
width: 20em;
height: 10em;
border: 1px solid #ddd;
overflow: hidden;
}
.list {
line-height: 10em;
background: #ddd;
text-align: center;
}
方式二:focus元素定位
说明: 这个能够解决上面跳动的问题,它是通过在每个列表里面添加一个不可见的input元素,然后通过选项卡的label的for属性与其id属性相关联,从而触发input的focus行为来完成锚点跳转,从而形成切换的效果
<div class="box">
<div class="list"><input id="one" readonly />1</div>
<div class="list"><input id="two" readonly />2</div>
<div class="list"><input id="three" readonly />3</div>
<div class="list"><input id="four" readonly />4</div>
</div>
<div class="link">
<label class="click" for="one">1</label>
<label class="click" for="two">2</label>
<label class="click" for="three">3</label>
<label class="click" for="four">4</label>
</div>
.box {
width: 20em;
height: 10em;
border: 1px solid #ddd;
overflow: hidden;
}
.list {
height: 100%;
background: #ddd;
text-align: center;
position: relative;
}
.list > input {
position: absolute;
top: 0;
height: 100%;
width: 1px;
border: 0;
padding: 0;
margin: 0;
clip: rect(0 0 0 0);
}
(5)兄弟属性 position:absolute
说明: 这个属性和float有些类似,比如它们都存在块状化、包裹性、破坏性等特性,因此说它们是兄弟关系,但是absolute更加牛x一点,因此两个属性同时存在的时候,float是无效的
块状化:一旦元素的position属性值为absolute或者是fixed,其display的计算值就是block或者是table
破坏性:虽然absolute是破坏标准文档流来实现自己的特性,但是本身还是受普通的流体元素布局的影响的
包裹性:也就是尺寸收缩包裹,同时又具有自适应性,不过这个自适应性有所不同,那就是在于absolute的自适应性最大宽度往往不是由父元素决定的,这个差异由absolute元素的与众不同的包含块引起的
==> 特殊的包含块 <==
说明: 这个是元素用来计算和定位的一个框,比如width:50%,那么这个50%是那个元素宽度的呢,其实这个元素就是这里所说的包含块,常见包含块的计算规则如下,这里有一点需要注意就是absolute的计算和定位是相对于祖先定位元素的 padding box
根元素被称为
初始包含块,它的尺寸大小等同于浏览器可视窗口的大小对于其它元素,如果该元素的position是relative或者是static,则包含块由最近的块级容器的祖先盒子的content box的边界形成
如果position是fixed,则包含块是初始包含块
如果元素position是absolute,则包含块是由最近的position
不为static的祖先元素建立,建立的过程如下:建立过程分两种,如果不是纯lnline元素,则包含块由该祖先的padding box的边界形成,下面介绍的是纯inline元素的建立过程,还有就是如果找不到position不为static的祖先元素,则包含块就是初始包含块
- 在内联元素前后都生成一个宽度为0的内联盒子,这两个内联盒子的padding box外面的包围盒子就形成了包含块
- 如果该内联元素被
跨行分隔了,那么包含块就是没有标准的了,由浏览器自由发挥生成,因此会存在兼容性问题
<== 内联元素包含块 ==>
说明: 也就是内联元素也可以作为包含块所在的元素,比如下面这一段HTML片段,这里span的包含块如图片所示,这是因为内联元素的包含块是由生成的前后两个宽度为0的内联盒子决定的,与里面内联盒子的作用细节没有什么关系,这样看它不受line-height的影响
<span style="position: relative">
我是
<big style="font-size: 200%">字号很大</big>
的文字
</span>
<== 包含块所在元素 ==>
说明: 这里说的是包含块所在的元素不是父块级元素,而是最近的 position 不为 static 的祖先元素或根元素,这对于定位元素而言,就产生height:100%和height:inherit的小小区别,与普通元素相比,absolute元素的包裹性中的自适应性也是相对于包含块来表现的
height:100%相对于第一个具有定位属性值得祖先元素的高度
height:inherit单纯的父元素高度的继承
举例: 下面代码中box元素的宽度是多少?文字会换行吗?如果box元素中有满满 1000个汉字,文字会换行吗?如果换行,在哪里换行?
<div class="container">
<div class="box">文字内容</div>
</div>
.container {
width: 200px;
border: 1px solid;
position: relative;
}
.box {
position: absolute;
}
解释: 在通常场景下,box元素宽度就是里面文字的宽度,不会换行;随着文字越来越多,如果文字足够多,box 元素宽度会越来越大,但是不会无限制大下去,因为超过一定限制是会自动换行的,而这个限制就是box元素的包含块,在这里包含块元素就是指container元素,所以box在此处的最大宽度就是200px,也就是absolute元素默认的最大宽度就是包含块的宽度
==> 无依赖的absolute定位 <==
注意:absolute是非常独立的css属性值,其样式和行为表现不依赖其它任何css属性就可以完成
说明: 假设一个absolute元素,没有任何的left、top、right、bottom属性的设置,并且祖先元素全部是非定位元素,那么这个元素位置在哪,答案是原地,可以这么理解,把它看成一个孩子在幼儿园里面,它没有看见自己的父母,所以没有随便走动,但是在幼儿园里面很多小孩子在玩老鹰捉小鸡,它觉得很有趣,就跟上去和它们一起玩,在游戏的过程中体现了一种相对性,那就是游戏开始的位置和结束的位置,孩子的位置就是固定的,所以是相对于位置的,比如下面这个例子,不过玩的过程中,自身性质还是存在的,比如性别,所以这里absolute元素的性质还是存在的
注意: margin在此时对absolute元素是生效的,不过建议只用在静态效果上
<!-- 当span里面的内容增多或者减少的时候,后面的图片是会跟着动起来的 -->
<!-- 因此体现出一种相对性 -->
<span>11</span>
<img src="D:1.jpg" alt="" />
img {
position: absolute;
width: 10px;
height: 10px;
}
<== 相对性的理解 ==>
说明: 也就是absolute定位的位置和没有设置absolute时候的位置是一样的,看下面这个例子
<h3>标题<span class="follow">span</span></h3>
<h3>
标题
<div class="follow">div</div>
</h3>
.follow {
position: absolute;
}
==> absolute 和 text-align <==
说明: 这里指的是原本是内联水平的元素absolute后可以接受text-align的影响,比如下面这个现象
<p>
<img src="D:1.jpg" />
</p>
p {
text-align: center;
width: 400px;
height: 100px;
background: #abcdef;
}
img {
position: absolute;
width: 100px;
}
解释: img是一个内联元素,那么它的前面存在一个宽度为0的幽灵空白节点,图片是跟在这个节点后面显示的,由于img被设置了absolute,因此图片不占空间,当元素被text-align影响的时候,它作用在这个幽灵节点上,因此变得居中展示,而图片会紧跟在后面,因此就会出现这种现象
(6)absolute 和 overflow
说明: 如果overflow不是定位元素,并且absolute元素和overflow容器之间也没有定位元素,则overflow无法对absolute元素进行裁剪
<!-- 不会裁剪 -->
<div style="overflow: hidden">
<img src="1.jpg" style="position: absolute" />
</div>
<!-- 不会裁剪 -->
<div style="position: relative">
<div style="overflow: hidden">
<img src="1.jpg" style="position: absolute" />
</div>
</div>
<div style="overflow: hidden; position: relative">
<!-- 会剪裁 -->
<img src="1.jpg" style="position: absolute" />
</div>
<div style="overflow: hidden">
<div style="position: relative">
<!-- 会剪裁 -->
<img src="1.jpg" style="position: absolute" />
</div>
</div>
注意: 如果 overflow 的属性值不是 hidden 而是 auto 或者 scroll,即使绝对定位元素高宽比 overflow 元素高宽还要大,也都不会出现滚动条,不过非绝对定位元素会出现滚动条,因此绝对定位元素和非绝对定位元素往往可以混杂在一起,虽然绝对定位元 素不能让滚动条出现,但是非绝对定位元素可以,于是,就可能出现另外一种很有特色的现象,即当容器滚动的时候,绝对定位元素微丝不动,不跟着滚动,表现类似 fixed 固定定位,比如下面这样的效果
(7)absolute与clip
说明: 在css中,有些属性或则特性必须和其它属性一起使用才有效,比如这里的clip裁剪属性想要起作用必须和position的值为absolute或者fixed结合起来
语法: clip(top right bottom left)
注意: 这几个值不能缩写并且不能使用%
clip: rect(30px 200px 200px 20px)
==> 用途 <==
<== fixed元素的裁剪 ==>
说明: 对于一般元素或者absolute元素来说,可以使用overflow属性对其溢出的部分进行显示和隐藏,也就是起到裁剪的作用,但是overflow属性对fixed的元素就不行了,因为fixed元素的包含块是根元素,除非是根元素滚动条进行滚动,否则overflow属性是作用不了的,因此可以使用clip属性,比如
.fixed-clip {
position: fixed;
clip: rect(30px 200px 200px 20px);
}
<== 可访问性隐藏 ==>
说明: 这里说的是虽然内容肉眼看不见,但是其它辅助设备却能够进行识别和访问的隐藏
举例: 每个网站都会存在以及的标识,一般在页面开头都会使用h1元素将自己网站的名字显示出来,那么如何将h1标签里面的文字隐藏起来呢,有以下推荐做法
下策是
display:none或者visibility:hidden隐藏,因为屏幕阅读设备会忽略 这里的文字。
text-indent缩进是中策,但文字如果缩进过大,大到屏幕之外,屏幕阅读设备也 是不会读取的。
color:transparent是移动端上策,但却是桌面端中策,因为原生 IE8 浏览器并不 支持它。color:transparent 声明,很难用简单的方式阻止文本被框选。
clip剪裁隐藏是上策,既满足视觉上的隐藏,屏幕阅读设备等辅助设备也支持得很好。
.clip {
position: absolute;
clip: rect(0 0 0 0);
}
<h1 class="clip">哈哈哈</h1>
特点: clip属性隐藏仅仅是决定那部分是可见的,非可见部分无法响应点击事件,并且虽然是视觉上的隐藏,但是元素的尺寸还是原来的尺寸
(8)absolute的流体特性
==> 变成绝对定位元素 <==
说明: 这里需要使用到top、right、bottom或者是left属性,使用之后absolute元素就变成绝对定位元素,其中left和right表示水平方向,top和bottom表示垂直方向,使用到哪一个属性哪一个方向上的相对特性丢失
/* 相对于absolute元素包含块的左上角对齐,此时水平和垂直方向上相对特性会丢失 */
.box {
position: absolute;
left: 0; top: 0;
}
/* 相对于absolute元素包含块的左边对齐,此时水平方向上相对特性会丢失 */
.box {
position: absolute;
left: 0;
}
==> absolute的流体特性 <==
说明: 这里说的特性就是和普通div这种块级元素在水平方向上的流体特性一样,只不过absolute元素不是默认就存在这种特性的,需要特殊条件,也就是使用对立定位属性,并且它们的属性值相等,这里的对立定位属性指的是top和bottom、left和right
<div class="box"></div>
/* 如果只有 left 属性或者只有 right 属性,则由于包裹性, */
/* 此时.box 宽度是 0。但是在 本例中,因为 left 和 right 同时存在, */
/* 所以宽度就不是 0,而是表现为“格式化宽度”,宽 度大小自适应于.box */
/* 包含块的 padding box,也就是说,如果包含块 padding box 宽度发生 */
/* 变 化,.box 的宽度也会跟着一起变 */
.box {
position: absolute;
left: 0;
right: 0;
}
注意: 假设.box 元素的包含块是根元素,则下面的代码可以让.box 元素正好完全覆盖浏览器的可视窗口,并且如果改变浏览器窗口大小,.box 会自动跟着一起变化,也就是在水平和垂直方向上都有流体特性,因此盒模型相关的属性也就能够使用了
.box {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
(9)position: realtive
说明: 这个就是将absolute元素狠狠的干住,也就是absolute元素会相对于relative元素进行定位,在使用的时候relative尽量少使用,多试试absolute的无依赖定位
==> 对absolute元素的限制 <==
说明: 感觉最主要的限制就是更改absolute元素的包含块变成relative元素吧
<div class="icon">
<div class="box"></div>
</div>
.box {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.icon {
width: 20px;
height: 20px;
position: relative;
}
解释: 在没有设置relative元素之前,box的尺寸是浏览器可视窗口的尺寸,设置完之后,尺寸就变成20px * 20px了,因为absolute元素的包含块变成了icon
==> 定位特性 <==
相对自身:也就是relative元素使用left、top、right、bottom这几个属性的时候,是相对于自身进行元素偏移的
无影响:也就是使用relative进行定位偏移的时候,一般不会对周围元素产生影响
==> 注意 <==
在relative定位的时候,使用
百分比值是相对于包含块进行计算的,而不是自身top 和 bottom 这两个垂直方向的百分比值计算跟 height 的百分比值是一样的,都是
相对高度计算的。同时,如果包含块的高度是 auto,那么计算值是 0,偏移无效,也就是说,如果父元素没有设定高度或者不是格式化高度,那么 relative 类似 top:20% 的代码等同于 top:0。对立方向定位值只能有一个生效,一般top和left
优先级更高
==> 最小化影响 <==
说明: 也就是让relative元素里面影响很少的元素,这样能够提高代码的可维护性,比如下面这个例子
举例: 假设需要在某个模块的右上角定位一个图标,可能有下面两种做法,但是推荐第二种
<div style="position: relative">
<img src="icon.png" style="position: absolute; top: 0; right: 0" />
<p>内容 1</p>
<p>内容 2</p>
<p>内容 3</p>
<p>内容 4</p>
...
</div>
<div>
<div style="position: relative">
<img src="icon.png" style="position: absolute; top: 0; right: 0" />
</div>
<p>内容 1</p>
<p>内容 2</p>
<p>内容 3</p>
<p>内容 4</p>
...
</div>
解释: 这是因为relative影响的元素只是图片,而后面的内容是没有被污染的,因为假设说过了一个月,我们不需要右上角的图标了,直接移除这个 relative 最小化的单元即可!但是,如果 relative 是这个容器上的,这段样式代码你敢删吗?万一其他 元素定位也需要呢?万一 relative 还有提高层叠顺序的作用呢?留着没问题,删掉可能出 bug,所以还是学吧!!!
(10)position: fixed
说明: 这个固定定位与relative和absolute定位的差别在于包含块不一样,fixed的包含块是根元素,简单理解就是相对于浏览器定位,它和absolute有相似的特性,也就是无依赖的fixed定位
六、层叠规则
说明: 层叠规则指的是当网页中的元素发生层叠时的表现规则
(1)了解 z-index
准则:对于非浮层元素,避免使用z-index,如果设置,其值不要超过2
说明: 字面意思,z轴顺序,很明显与层叠规则有关,在css2.1中,z-index只能和定位元素在一起的时候才能够生效,其基本的表现形式为数值越大层级越高
注意: 这个属性并不能代表css中的层叠规则,它只是一小部分而已
(2)了解层叠上下文和层叠水平
层叠上下文: 这是一个概念,当元素含有层叠上下文,那么可以理解为这个元素在z轴上面离你越近
层叠水平: 它决定了在同一个层叠上下文中元素在z轴上显示的顺序,因此不管是层叠上下文元素还是当前层叠上下文中的普通元素都有层叠水平这个概念,也就是说层叠水平和z-index是不相等的,最起码作用范围都不一样
(3)层叠顺序
说明: 这是一条规则,表示元素发生层叠时有特定的垂直显示顺序规则,在css2.1的年代,存在以下层叠顺序规则
注意:
每一个层叠顺序规则
仅仅适用于当前层叠上下文元素inline水平盒子指的是inline、inline-block、inline-table元素,它们是
同等级的单从
层叠水平上看,z-index:0和z-index:auto可以看成是一样的
(4)层叠准则
谁大谁上:当具有明显的层叠水平标识的时候,比如生效的z-index属性值,在同一个层叠上下文领域,值大的哪一个会覆盖小的哪一个
后来居上:当元素的层叠水平一致、层叠顺序相同的时候,处于DOM流中后面的元素会覆盖前面的元素
(5)理解层叠上下文
==> 特性 <==
层叠上下文的层叠水平比普通元素要
高层叠上下文可以
阻断元素的混合模式层叠上下文可以
嵌套,内部层叠上下文及其所有的子元素均受制于外部的层叠上下文每个层叠上下文和兄弟元素
独立,也就是当进行层叠变化或者渲染的时候,只需要考虑后代元素就好每个层叠上下文都是
自成体系,当元素发生层叠的时候,整个元素可以被认为是在父层叠上下文的层叠顺序中
==> 创建 <==
天生型:这个指页面的根元素<html>,天生就有层叠上下文
传统型:也就是对于position的值为relative、absolute,或者Firefox/IE浏览器的position的值为fixed时,只要z-index的值不是auto的时候,就会创建一个层叠上下文
新增型:这个属于css3的内容,css2.1就不说了
举例: 比如下面这两组HTML,只是z-index的值从auto变成了0,但是得到两种不同的层叠顺序
<!-- 美女在上,美景在下 -->
<div style="position: relative; z-index: auto">
<!-- 美女 -->
<img src="1.jpg" style="position: absolute; z-index: 2" />
</div>
<div style="position: relative; z-index: auto">
<!-- 美景 -->
<img src="2.jpg" style="position: relative; z-index: 1" />
</div>
解释: 由于z-index的值为auto,因此不会创建层叠上下文,于是,里面的两个img元素的层叠比较就不受父级的影响,两者直接套用层叠准则。这里,两个img元素有着明显不一的 z-index 值,因此遵循谁大谁上的准则,于是,z-index 为 2 就显示在 z-index 为 1 的上面了。
<!-- 美女在下,美景在上 -->
<div style="position: relative; z-index: 0">
<!-- 美女 -->
<img src="1.jpg" style="position: absolute; z-index: 2" />
</div>
<div style="position: relative; z-index: 0">
<!-- 美景 -->
<img src="2.jpg" style="position: relative; z-index: 1" />
</div>
解释: z-index 一旦变成数值,哪怕是 0,就会创建一个层叠上下文。此时,层叠规则就发 生了变化。层叠上下文的特性里面最后一条是自成体系。两个img元素的层叠顺序比较变成 了优先比较其父级层叠上下文元素的层叠顺序。这里,由于外面的两个
元素都是 z-index:0,两者层叠顺序一样大,此时遵循层叠准则的另外一个准则后来居上,根据在 DOM 文档流中的位置决定谁在上面,于是,位于后面的美景就自然而然显示在美女上面了
==> 与层叠顺序的关系 <==
如果层叠上下文元素
不依赖z-index的数值,则其层叠顺序是z-index:auto,可以看成是z-index:0级别如果层叠上下文元素
依赖z-index的数值,则其层叠顺序由z-index值决定
(6)z-index负值
说明: z-index为负值渲染的过程就是一个寻找第一个层叠上下文元素的过程,然后层叠顺序就止步于这个层叠上下文元素,从上面的图可以看出,z-index为负值的元素在层叠上下文元素和block元素之间
/* 此时div元素是一个普通的块级元素,因此图片会在div后面 */
.box {
background-color: blue;
width: 100px;
height: 100px;
}
/* 这里没找到层叠上下文元素,如果存在这个元素,那么一定是box的祖先元素 */
.box > img {
width: 100px;
position: relative;
z-index: -1;
right: -50px;
}
<div class="box">
<img src="D:1.jpg" />
</div>
/* css3的transform属性能够创建层叠上下文,那么此时图片就不能再box后面了 */
.box {
background-color: blue;
width: 100px;
height: 100px;
transform: scale(1);
}
七、文本处理
(1)font-size
说明: 默认情况font-size的值为16px
==> 与vertical-align的关系 <==
说明: 由于line-height的部分类型属性值是相对于font-size计算的,而vertical-align的百分比值是相对于line-height进行计算的,因此font-size与vertical-align之间存在联系
p {
font-size: 16px;
line-height: 1.5;
}
/* 计算值:16px * 1.5 * 25% = 6 */
/* 区别:%值是会跟随font-size的变化而变化的 */
p > img {
/* 等同于 vertical-align: -6px */
vertical-align: -25%;
}
举例: 比如实现文字和图片的垂直居中对齐
<p>文字 <img src="delete.png" /></p>
p > img {
width: 16px;
height: 16px;
/* 图片默认是使用其下边缘与汉字底部边缘往上一点的位置对齐的 */
/* 通过vertical-align: 25%;可以让图片下边缘与汉字的中心对齐 */
/* 当然这里使用ex单位也是可以的 */
vertical-align: 25%;
/* 如果需要垂直居中,那么就需要将图片往下移动50%的高度 */
position: relative;
top: 8px;
}
==> ex、em、rem <==
ex:就是字符x的高度,与font-size的关系密切,font-size越大,字符x也就越大,对应的ex也就越大
em:其值是相对于当前元素所在的font-size进行计算的,默认情况下1em的值为16px
rem:相对于根元素的font-size进行计算,默认情况下1rem的值为16px
==> 关键字属性值 <==
说明: 属性值分为两类,一种是相对尺寸关键字,这种是相对于当前元素的font-size进行计算的;一种是绝对尺寸关键字,它与元素的font-size无关,仅仅只受浏览器字号的设置,并不是根元素;其具体的属性值分别如下:
larger:大一点,是<big>元素的默认 font-size 属性值
smaller:小一点,是<small>元素的默认 font-size 属性值
xx-large:好大好大,跟<h1>元素的计算值一样
x-large:好大,跟<h2>元素的计算值一样
large:大,跟<h3>元素的计算值近似,相差不过1px
medium:不大不小,是font-size的初始值,和<h4>元素的计算值一样,这个关键字的属性值只与浏览器设置有关,由于font-size具有继承性,因此大多数元素的这个值都被覆盖掉了
small:小,跟<h5>元素的计算值近似
x-small:好小,跟<h6>元素的计算值近似
xx-small:好小好小,没有对应的HTML元素
注意: 有项目使用价值的只有medium
/* 默认情况下这两个大小是一样的,但是如果更改浏览器字体大小的设置 */
/* 下面的会跟着放大缩小,而上面的永远保持14px */
html {
font-size: 14px;
}
html {
font-size: 87.5%;
}
==> font-size: 0 <==
说明: 浏览器会有最小字号的限制,比如Chrome浏览器的最小字号为12px,大部分小于12px的font-size都会当做12px来处理,不过0例外,当设置font-size为0的时候,文字就被隐藏了
(2)font-family
说明: 这个表示使用了什么字体,它的默认值会根据不同的操作系统和不同的浏览器而不同,它支持两类属性值,一类是字体名,也就是对应字体的名称;一类是字体族,常见的如下:
body {
/* 宋体 */
font-family: simsun;
/* 如果字体名称包含空格则需要引号包起来 */
font-family: 'Microsoft Yahei';
/* 如果存在多个字体设定则会从左到右依次在本地寻找是否存在对应的字体 */
font-family: 'PingFang SC', 'Microsoft Yahei'
}
serif:衬线字体sans-serif:无衬线字体。monospace:等宽字体。cursive:手写字体。fantasy:奇幻字体。system-ui:系统 UI 字体。
==> 衬线、无衬线字体 <==
衬线字体:从笔画开始和结束的地方有额外装饰而且笔画的粗细会有所不同,比如中文的宋体
非衬线字体:没有额外的装饰并且笔画的粗细差不多,比如中文的微软雅黑
注意: 这两个在写的时候一定要写在最后面,因为大多数浏览器下这两个属性值后面的字体都会被忽略掉
body {
font-family: "Microsoft Yahei", sans-serif;
}
==> 中文字体和英文名称 <==
说明: 使用中文字体,必须使用其对应的英文名称,这样是为了防止乱码的风险,window操作系统下常见中文字体对应的英文名称如下
| 字体中文 | 字体英文 |
|---|---|
| 宋体 | Simsun |
| 黑体 | SimHei |
| 微软雅黑 | Microsoft Yahei |
| 微软正黑体 | Microsoft jhengHei |
| 楷体 | KaiTi |
| 新宋体 | nsimSun |
| 仿宋 | FangSong |
(3)font-weight
说明: 用于控制文字的粗细程度,默认值是normal了,如果粗略的加粗就是bold;如果需要更加细致的控制字体粗细则可以使用100-900的整百数;如果需要相对于父元素则可以使用lighter和bolder
注意: 100-900的整百数外表上看像数值,实际上是一个具有特定含义的关键字,比如400就是对应了上面的normal,700则对应了上面的bold,因此400和700加上最大值和最小值900和100组成了四个临界点,上面所说的lighter和bolder是相对于这四个临界值进行解析和渲染的,具体关系如下:
| font-weight | bolder | lighter |
|---|---|---|
| 100 | 400 | 100 |
| 200 | 400 | 100 |
| 300 | 400 | 100 |
| 400 | 700 | 100 |
| 500 | 700 | 100 |
| 600 | 900 | 400 |
| 700 | 900 | 400 |
| 800 | 900 | 700 |
| 900 | 900 | 700 |
误区: font-weight发挥作用,不在于css的支持,而在于是否存在对应的字体
(4)font-style
说明: 这个表示文字是斜体还是正常的展示,默认值是normal,其其它属性值如下:
italics:使用当前字体的斜体形式,如果没有找到,则解析为oblique
oblique:单纯的让字体倾斜,这个属性不推荐使用
(5)font-variant
说明: 它的作用就是将英文字母以大写的形式展现但是其大小还是跟小写的一样,它只有两个属性值,一个是默认值normal,另一个就是small-caps,对于中文来说这个属性有点鸡肋
<div>ABC</div>
<p>abc</p>
p {
font-variant: small-caps;
margin: 0;
}
(6)font属性
==> 基本使用 <==
说明: 当看见这个属性的时候,就表示将一些文本相关的属性简写到这个属性里面了,具体参见语法,其中,语法的顺序是推荐你这么写,不按这个顺序写也行,只不过font-size和font-family是必需的,其余的属性则不是必需的,如果你不写,这些属性会被浏览器初始化为默认值
语法: 这里的属性并不是每一个都需要的,
.font {
font: font-style font-variant font-weight font-size/line-height font-family
}
==> 关键字属性值 <==
说明: 这里说的有六个分别为caption、icon、menu、message-box、small-caption、status-bar,如果将font设置为这六个里面的一个,则表示使用系统在这个部分使用的字体,具体如下:
cation:活动窗口标题栏使用的字体
icon:包含图标内容所使用的字体,如所有文件夹名称、文件名称、磁盘名称,甚至 浏览器窗口标题所使用的字体
menu:菜单使用的字体,如文件夹菜单
message-box:消息盒里面使用的字体
small-caption:调色板标题所使用的字体
status-bar:窗体状态栏使用的字体
注意: 这几个关键字属性值的使用是独立的,它和上面所说的font属性缩写不一样;其次caption、icon、message-box这三个关键字尽量避免使用,因为在Chrome中存在不会跟着系统字体走的问题
优点:网站使用的字体能够与操作系统一起与时俱进缺点:呈现的字体风格是不可控的
(7)了解@font face的规则
==> 本质是变量 <==
说明: @font face的本质就是一个定义字体或者字体集的变量,这个变量不仅仅是简单的定义字体,还包括字体的重命名这些,这里介绍它的如下属性:
@font-face {
font-family: "example";
src: url(example.ttf);
font-style: normal;
font-weight: normal;
unicode-range: U+0025-00FF;
}
<== font-family ==>
说明: 这个可以看成是一个字体变量,名称一般情况下可以随便写,在写的时候需要带上'',对于系统原有的字体名称,就不能随便设置了,不然会对字体进行修改的
/* 此时example.ttf文件的字体就是微软雅黑了 */
@font-face {
font-family: "Microsoft Yahei";
src: url(example.ttf);
}
<== src ==>
作用: 用于引入字体资源,这个资源可以是系统自带的,这个需要使用local()来引入,不过IE9以上才能使用;如果是外部资源,则使用url()引入,这个不存在兼容性问题
@font-face {
font-family: ICON;
/* 两个src的原因是是低版本的IE浏览器不认识?的写法 */
/* 因此为了兼容才出现两个 */
src: url("icon.eot") format("eot");
/* #iefix是没啥用的,主要是前面的?有用,在IE9之前 */
/* 浏览器会将长长的字符作为一个地址解析而返回404错误 */
/* 存在这个?后,会把?之后的内容当做url的请求参数 */
src: url("icon.eot?#iefix") format("embedded-opentype"),
/* 这里放置这么多字体完全是为了兼容性 */
url("icon.woff2") format("woff2")
url("icon.woff") format("woff"),
url("icon.ttf") format("typetrue"),
/* format的作用 在于让浏览器提前知道字体的格式,以 */
/* 决定是否需要加载这个字体,如果不能加载是不会加载的 */
url("icon.svg#icon") format("svg");
font-weight: normal;
font-style: normal;
<== font-style ==>
说明: 用来设置在对应样式下面应该使用什么字体
/* 这个表示如果是斜体字下,会使用下面的那个字体 */
@font-face {
font-family: "I";
font-style: normal;
src: local("FZYaoti");
}
@font-face {
font-family: "I";
font-style: italic;
src: local("FZShuTi");
}
<== font-weight ==>
说明: 跟上面作用类似,也就是根据不同的字重使用不同的字体,由于字重有100-900的整百数有9个,因此用来实现响应式图标,也就是指的字号较大的时候图标细节更丰富,字号小的时候更简约而已
@font-face {
font-family: ICON;
src: url(icon-large.eot);
src: local("☺"), url(icon-large.woff);
font-weight: 700;
}
@font-face {
font-family: ICON;
src: url(icon-medium.eot);
src: local("☺"), url(icon-medium.woff);
font-weight: 400;
}
@font-face {
font-family: ICON;
src: url(icon-small.eot);
src: local("☺"), url(icon-small.woff);
font-weight: 100;
}
.icon {
font-family: ICON;
}
.icon-large {
font-weight: 700;
font-size: 128px;
}
.icon-medium {
font-weight: 400;
font-size: 64px;
}
.icon-small {
font-weight: 100;
font-size: 16px;
}
<i class="icon icon-small">🎤</i>
<i class="icon icon-medium">🎤</i>
<i class="icon icon-large">🎤</i>
<== unicode-range ==>
作用: 让特定的字符或者特定范围的字符使用指定的字体
/* 微软雅黑 字体的引号左右间隙不均,方向不明,实在是看着不舒服, */
/* 此时我们就专门指定这两个引号使用其他字体 */
@font-face {
font-family: quote;
src: local("SimSun");
unicode-range: U+201c, U+201d;
}
.font {
font-family: quote, "Microsoft Yahei";
}
(8)文本控制
说明: css的很多属性是专门来对文本进行控制的,由于这些属性的作用机制往往是基于内联盒模型的,因此对于内联块状元素同样是有效的
==> text-indent <==
说明: 最开始用于文字的缩进,不过这对内容要求比较高,需要内容是单一类型,不然中文英文什么的结合起来,缩进可能会产生一种参差不齐的感觉,用的比较多的是负值隐藏文本内容,这个值不要设置很大,不然可能存在潜在的性能风险;
注意: 它也支持百分比,不过百分比是相对于当前元素的包含块进行计算的,而不是当前元素,一般情况下包含块的宽度是大于子元素宽度的,如果使用不大于,则会出现样式问题
了解:
Chrome浏览器下,img标签没有src属性的时候会出现一个灰色边框,这是给Alt属性预留的,由于是内联水平元素,因此可以使用text-indent来将其隐藏
text-indent 仅对第一行内联盒子内容有效
非替换元素以外的 display 计算值为 inline 的内联元素设置 text-indent 值无 效,如果计算值是 inline-block/inline-table 则会生效。因此,如果父级块状元素设置 了 text-indent 属性值,子 inline-block/inline-table 需要设置 text-indent:0 重置
input标签按钮 text-indent 值无效
button标签按钮 text-indent 值有效,但是存在兼容性差异,IE 浏览器理解为 单标签,百分比值按照容器计算,而 Chrome 和 Firefox 浏览器标签内还有其他 Shadow DOM 元 素,因此百分比值是按照自身的尺寸计算的。
input和textarea的 text-indent 在低版本 IE 浏览器下有兼容问题。
==> letter-spacing <==
说明: 这个用于控制字符的间距,字符包括英文、中文、空格等,它具有以下特性
继承性
默认值是normal,正常情况下计算的值为0,但是跟0有一点区别,在于某些情况下normal的值是会自动的计算的,但是0不会支持
负值,当值足够大的时候,会让字符进行重叠,甚至反向排列(IE浏览器除外),重叠只会发生在字符身上,并不会让替换元素或者inline-block、inline-table元素发生重叠无论值的大小如何,第一行
至少存在一个字符,在默认左对齐的情况下,无论怎样操作第一个字符的位置是不变的支持
小数值,不过并不是一直能看到效果,这还与屏幕的密度有关对百分比是
不支持的
==> word-spacing <==
说明: 只用于空格,也就是增加空格的间隙宽度,它和letter-spacing很类似,因此其特性也差不多,比如在继承、默认值、小数、百分比这里都是一样的,区别在于下面两条
对于负值,也是可以让字符重叠的,只不过对于inline-block和inline-table元素,存在兼容性的差异
间隔算法都会收到text-align:justify两端对齐的影响
==> word-break 和 word-wrap <==
说明: 这里说的是word-break:break-all 和 word-wrap:break-word 的区别,这两个属性的值分别如下;从属性值就可以看出其区别在于换行的时机
word-break: normal默认的换行规则
word-break: break-all允许任意的非中文、日语、韩语的文本中的单词换行
word-break: keep-all不允许中文、日语、韩语的文本中的单词换行,只能在半角空格或者连字符处换行
word-wrap: normal默认的换行规则
word-wrap: break-word一行文本中,如果存在单词,这个单词之间是不会换行的,它会完整的显示一个单词,一般是不会拦腰截断的
==> white-space <==
说明: 它用来处理元素的空白字符,这些空白字符包括空格、回车、tab键产生的空格,因此它能够实现是否一行显示、是否大段空白等效果,其常见属性值如下;根据其作用的效果也能得到一个作用的表格;
normal:合并空白字符和换行符
pre:空白字符不合并,并且内容只在有换行符的地方换行
nowrap:该值和 normal 一样会合并空白字符,但不允许文本环绕,这里的文本环绕指文字超过容器高度,自动从下一行展示
pre-wrap:空白字符不合并,并且内容只在有换行符的地方换行,同时允许文本环绕
pre-line:合并空白字符,但只在有换行符的地方换行,允许文本环绕
| 属性值 | 换行 | 空格 | 文字环绕 |
|---|---|---|---|
| normal | 合并 | 合并 | 可以 |
| nowrap | 合并 | 合并 | 不可以 |
| pre | 保留 | 保留 | 不可以 |
| pre-wrap | 保留 | 保留 | 可以 |
| pre-line | 保留 | 合并 | 可以 |
==> text-align:justify <==
说明: 这个会调整单词中字符的间距,使每行尽量多的去填充容器的宽度,这种对齐方式称为两端对齐;它也能实现两端对齐的布局,不过是针对inline-block元素,其次需要满足两个条件,一是存在换行符,二是要超过一行,非最后一行的内容会两端对齐
.box {
width: 200px;
height: 50px;
background: #abcdef;
margin: 20px;
}
.justify {
text-align: justify;
}
<div class="box">这是一段文字,测试一下QAQ</div>
<div class="box justify">这是一段文字,测试一下QAQ</div>
==> text-decoration <==
说明: 以text-decoration产生的下划线为例,其经常会与文字黏在一起,有点难看,此时可以用border来完全模拟,这个好处是对于纯内联元素,垂直方向上的padding和border对原来的布局定位没有任何的影响,也就是我border-bottom设置10000px,上下行文字的垂直位置依然不动
.box {
width: 200px;
height: 50px;
margin: 20px;
}
.border {
text-decoration: none;
border-bottom: 1px solid;
}
<a href="" class="box">这是一段文字,测试一下QAQ</a>
<a href="" class="box border">这是一段文字,测试一下QAQ</a>
==> text-transform <==
说明: 适用英文字体,要么uppercase全大写,要么lowercase全小写,完全不用担心大小写的的问题,所以一般在身份证输入、验证码输入这种地方使用的比较多
(9):first-letter 和 :first-line
==> :first-letter <==
说明: :first-letter和::first-letter的作用都是选择第一个字符,只不过一个是伪类,一个是伪元素
<== 生效前提 ==>
元素的display的计算值
必须是block、inline-block、list-item、table-cell和table-caption这几个之一常见的标点符号、各类括号和引号都是不会使其生效的,也就是
·@#%&*()()[]【】{}::"“”;;'‘’》《,,.。??!!…*、/\这些符号是无效的,可以理解为买商品时的赠品,这个是不可以直接购买的数字、中文、$、一些运算符、空格是
有效字符,可以理解为商品字符前面不能有图片或者inline-block、inline-table之类的元素,它们会让
伪元素直接失效
<!-- 这里的 辅 才是商品,前面的 ? 都当做赠品一起回收 -->
<p>???????辅助</p>
<p><i style="display: inline-block"></i>银色</p>
p:first-letter {
color: red;
}
<== 生效的css属性 ==>
字体相关:font、font-style、font-variant、font-weight、 font-size、line-height、 font-family
背景相关:background-color、background-image、background-position、background-repeat、background-size、background-attachment。
margin相关:margin、margin-top、margin-right、margin-bottom、margin-left
padding相关:padding、padding-top、padding-right、padding-bottom、padding-left
border相关:缩写的 border、border-style、border-color、 border-width 和普通书写的属性
color属性text-decoration、text-transform、letter-spacing、word-spacing(合适情境下)、line-height、float 和 vertical-align(只有当 float 为 none 的时候)等属性
<== 其它特点 ==>
支持部分display属性值得标签嵌套: inline、block、list-ltem这些盒子的嵌套和不嵌套的作用效果是一样的
p:first-letter {
color: red;
}
p > span {
display: inline;
}
<p><span>第一个</span>字符看看会不会变色?</p>
颜色权重多一层:
p::first-letter {
color: red;
}
p > span {
color: blue !important;
}
<p><span>第一个</span>字符看看会不会变红?</p>
解释: ::first-letter 伪元素其实是作为子元素存在的,或者说应当看出是子元素,于是就很好理解了。对于类似 color 这样的继承属性,子元素的 CSS 设置一定比父元素的级别要高,哪怕父级使用了重量级的!important,因为子元素会先继承,然后再应用自身设置。因此,上面 CSS 和 HTML 代码的最终结果是,第一个字符“第”字的颜色是 red,红色!
<== 实际应用 ==>
举例: 价格前面大号的¥
p:first-letter {
margin-right: 5px;
font-size: xx-large;
vertical-align: -2px;
color: red;
}
<p>¥399</p>
==> :first-line <==
说明: 前者是选择第一个字符,那这个就是选择一行了,只是没有无效字符一说,其它的跟前面的类似
八、装饰与美化
(1)单调的color
==> 很少的颜色关键字 <==
说明: 这里说的关键字指red、blue这些,在css2.1这里,颜色关键字只有17个,如下;
注意: 如果浏览器不认识这些颜色关键字,HTML会用一种算法将其替换成另一种毫不相干的颜色,css会使用默认的颜色
==> 不支持的transparent关键字 <==
background-color:transparentIE6开始支持border-color:transparentIE7开始支持color:transparentIE9+开始支持
==> 不支持的currentColor变量 <==
说明: 它可以计算当前color的计算值,IE9以上才支持这个变量,不过css中很多属性都有这样的表现,因此一般不用再次声明这个关键字
.test {
color: red;
border: 2px solid;
}
/* 画蛇添足的写法 */
.test {
color: red;
border: 2px solid currentColor;
}
==> 不支持rgba颜色和hsla颜色 <==
hsla颜色: 它属于css3,hsl 颜色的 3 个字母也有自己的含义。其中,h 表示 hue,是色调的意思,取值 0~ 360,大致按照数值红、橙、黄、绿、青、蓝、紫变化节奏;s 表示 saturation(饱和度),用 0~ 100%表示,值越大饱和度越高,颜色越亮,通常我们评价某设计“亮瞎我们的眼”,就是“这 个设计颜色饱和度太高”的另一种说法;l 表示 lightness(亮度),也用 0~100%表示,值越高 颜色越亮,100%就是白色,50%则是正常亮度,0%就是黑色。
rgba颜色: 同样属于css3,跟rgb颜色类似,前面三个字母分别表示红色、huangse跟rgb颜色类似,前面三个字母分别表示红色、绿色、蓝色,取值范围为0-255,最后一个字母表示透明度,0表示透明,1表示显示
注意: rgb这三个字母的取值都不能是小数,但是可以为百分比
九、元素的显示和隐藏
(1)常见隐藏方式的汇总
方法一: 如果需要元素不可见、不占据空间、辅助设备无法访问、不渲染,可以使用<script>标签隐藏,使用的时候注意,这个表情是不支持嵌套的,如果希望在这个标签里面放置其它不渲染的模板内容,可以使用<textarea>元素
<!-- Script标签中隐藏的内容可以使用script.innerHTML获取 -->
<script type="text/html">
<img src="1.jpg" />
<!-- 使用textarea.value来获取 -->
<textarea style="display:none;">
<img src="2.jpg">
</textarea>
</script>
方法二: 如果希望元素可见、不占据空间、辅助设备无法识别,但是存在资源加载,DOM可访问,可以使用display:none隐藏
.dn {
display: none;
}
方法三: 如果希望元素不可见、不占据空间、辅助设备无法访问,但是显示隐藏的时候有transition过渡的效果
.hidden {
position: absolute;
visibility: hidden;
}
方法四: 如果希望元素不可见,不能点击,辅助设备无法访问,但占据空间保留,则可以使用 visibility:hidden隐藏
.vh {
visibility: hidden;
}
方法五: 如果希望元素不可见,不能点击,不占据空间,但键盘可访问,则可以使用 clip 剪裁隐藏
.clip {
position: absolute;
clip: rect(0 0 0 0);
}
.out {
position: relative;
left: -999em;
}
方法六: 如果希望元素不可见,不能点击,但占据空间,且键盘可访问,则可以试试 relative 隐藏,如果条件允许,也就是和层叠上下文之间存在设置了背景色的父元素, 则也可以使用更友好的 z-index 负值隐藏
.lower {
position: relative;
z-index: -1;
}
方法七: 如果希望元素不可见,但可以点击,而且不占据空间,则可以使用透明度
.opacity {
position: absolute;
opacity: 0;
filter: Alpha(opacity=0);
}
方法八: 如果单纯希望元素看不见,但位置保留,依然可以点可以选,则直接让透明度为 0
.opacity {
opacity: 0;
filter: Alpha(opacity=0);
}
(2)display隐藏的特性
说明: 对一个元素而言,如果 display 计算值是 none 则该元素以及所有后代元素都隐藏,如果是其他 display 计算值则显示
对于background、background-image中的图片,对于Firefox浏览器来说,display:none的图片是不加载的,父元素也是一样;对于Chrome和Safari浏览器来说,父元素设置就不加载,图片自身设置就会加载;而对于IE来说,无论怎样设置都会加载;这个特性在轮播图这里使用可以优化性能,提高页面整体的加载速度
对于img下的图片,无论怎样设置都会加载图片资源
HTML中有很多标签默认就是display:none,比如style、Script,它们设置display:block的时候会看见css和JS代码在页面上显示
display: none的显示隐藏不会影响css3中的动画,但是会影响过渡
(2)display与visibility的区别
继承性:父元素设置visibility: hidden,子元素也会继承,因此子元素设置visibility:visible是可以让子元素显示的
css计数器的影响:visibility: hidden元素的css计数器不受元素隐藏的影响,但是display: none的元素会直接不参与计数的运算
对transition的支持:transition支持的css属性有visibility,但是没有display
十、流向的改变
(1)改变水平流向的direction
==> 简介 <==
解释: 以文字为例,默认情况都是从左往右写的,这个属性能够让你从右往左写,这两种情况分别对应属性值ltr和rtl,前面那个是默认值,这个属性的出现是为了兼容不同的文字,因为不同文字可能书写顺序上面不是一致的,但是在项目里面使用多语音的情况很少见,因此这个属性都是用在布局上面
特性: 可以改变替换元素或者inline-block/inline-table元素的水平呈现顺序
<div style="direction: rtl">
<img src="" alt="图片1" />
<img src="" alt="图片2" />
</div>
说明: 这有啥用呢,它可以很简单的改变元素的水平呈现顺序,比如一个界面上存在两个按钮,需要在移动端的时候改变这两个按钮的顺序,这使用场景不就来了么,所以只要是内联元素,只要与流的顺序有关,都可以试一下这个属性
==> unicode-bidi <==
说明: 它需要借助direction属性才能使用,其次这个主要是针对纯文字使用的,也就是改变文字的方向,属性的默认值是normal,它还有两个属性值,一个是embed,一个是bidi-override,它们的作用如下
normal:正常排列,也就是文字默认从左到右展示,没啥好说的
embed:它只能作用于内联元素上面,通常它和normal的表现是一致的,只不过它规定好的顺序是不受外界影响的,看下面的例子就明白了
bidi-override:文字排列的顺序跟direction的顺序是一致的
<p class="rtl">
开头是我,<span style="unicode-bidi: normal">这是中间</span>,然后是我
</p>
<!-- embed的表现不受外界影响 -->
<p class="rtl">
开头是我,<span style="unicode-bidi: embed">这是中间</span>,然后是我
</p>
.rtl {
direction: rtl;
unicode-bidi: bidi-override;
}
.rtl > span {
background-color: red;
}