css世界--流

本书主要基于css2进行讲解,本书除了对于一些属性的讲解,最重要的部分就是对于css流的介绍。在一开始学习了解css的时候我们就知道css的基础就是“流”,但是当时对于流的理解是css自身的一种属性。但是通过本书可以了解到流也是由来和作用。

流体布局

所谓“流体布局”,指的是利用元素“流”的特性实现的各类布局效果,因为“流”本身具有自适应性,所以“流体布局”往往都是具有自适应性的。但是,“流体布局”并不等于“自适应布局”

无宽度

对于块状元素,如果width:auto,则元素会如流水一样充满整个容器,而一旦设定了width具体数值,则元素的流动性会消失。如果宽度作用在content box上,内外流动性皆无。

CSS流体布局下的宽度分离原则

所谓“宽度分离原则”,就是css中width属性不与影响宽度的padding/border(有时候包括margin)属性共存。
如下:

  • 不要出现这种写法
    1
    .box { width:100px; border: 1px solid; padding:20px;}
  • 鼓励这种写法(分离 width 独立占用一层标签,padding\border\margin利用流动性在内部自适应)
    1
    2
    3
    4
    5
    6
    7
    .father {
    width:142px;
    }
    .son {
    padding:20px;
    border:1px solid;
    }
    思想:
    便于维护,盒子尺寸中4个属性都能影响到宽度,因此改动需要非常小心精确算好对于宽度的影响。宽度分离后,宽度在外层单独固定。内部调整padding\margin\border相互自适应调整(流体)依旧充满整个父元素空间。如果不考虑替换元素,所有页面基本只需要一个width设定就可以了,内部元素根据流体填充。

*{box-sizing:border-box} vs 宽度分离

border-box 无法解决所有问题。box-sizing 不支持margin-box,只有元素没有水平margin的时候,box-sizing才能和我们预想中一样,宽度分离可以使用所有情况。
而且 box-sizing 的初衷是解决替换元素的宽度自适应问题。

无宽度业务运用

通用:

  1. 如必须使用 width 属性数值使用比例数值

左右两栏布局

  1. position:absolute + padding-left
  2. float:left + padding-left

多栏布局

  1. column-width + 百分比

总结:宽度分离—充分利用流动性用内部元素充满父元素,不要用具体数值限制非直接内容元素的宽度,让他们被具体内容填充。具体的排版使用padding\margin\float\positon 等属性进行调整。充分利用子元素填充支撑父元素。

奇怪的行高

问题点

我们先想想这段代码的浏览器渲染效果是什么样?

1
2
3
4
5
6
7
<!-- 页面骨架 -->
<div class="test">
<span class="size-style">sphinx</span>
</div>
<div class="test1">
<span class="size-style1">sphinx</span>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* 页面样式 */
.test {
font-family: simsun;
line-height: 40px;
background-color: yellow;
display: inline-block;
}
.size-style {
font-size: 31px;
background-color: white;
}

.test1 {
font-family: simsun; //宋体,字体显示区域大小与字体大小一致
line-height: 40px;
font-size: 31px;
background-color: yellow;
display: inline-block;
}
.size-style1 {
background-color: white;
}

粗看这段代码是两个一模一样的行内块级元素并排,因为 CSS font-size 属性的继承性,内部只有一个子元素,属性值写在子或父元素全部一致。理论渲染的效果也应该是一样。

理论效果.png

  • test 与 test1 的高度为 40px (行高)

但是实际浏览器渲染的结果如下图所示

实际效果.png

  • test1 元素高度 44px
  • test 元素高度 40px (行高)

这多出来来的4px高度是撒?

看渲染效果 test 和 test1 大体相似上半行距和字体显示局域是一样的,区别在于下半行距,test 多出的 4px就在这个区域。我们可以猜测是 test 内的 span 下方多出一个块级元素或换行的行内元素还有同行的行内元素(无宽度)。

  1. 我们先试试改变行高这个 4px 差的差距会跟随变化吗。(有变化=>但是从数值看不会是元素下方的)
  2. 删除 test 上的 line-height 属性。(发现 line-height 的默认值不会产生这个 4px 的误差)
  3. 查询 line-height 的默认值,是相对量。尝试使用其他相对量。(发现相对量不会产生 4px 误差;只有绝对量才会产生)。
  4. 尝试改变 font-size 的值(发现 4px 大小发生变化;额外元素能响应 font-size,但是想不出那个元素符合)。
  5. 好难看不出这是个撒,google了下发现每个 line-box 的起始位置都有一个宽度为 0 的字符(CSS 文档将其称为 strut),并将其纳入 line-box 的高度的计算中。

下面我们来验证下这个看不见的字符

前提:

  • 行内元素默认对齐是根据字符的基线
  • font-size的大小不等于实际看见的字符大小(content area)
  • 同一个 size 不同字体看见的字符大小也不一样,具体跟字体自己的规定相关(注:simsun 宋体 字符大小和font-size一致)
1
2
3
4
5
6
<div class="test">
<span class="size-style2">x</span>
</div>
<div class="test">
<span class="size-style">sphinx</span>
</div>
1
2
3
.size-style2 {
background-color: white; //其他属性继承自父元素,模拟幽灵元素
}

snipaste_20200229_172517.png

可以发现x字符由于字体和字号的不一样,字符占据的空间 + 字间距对比会有下沉。如果用一个元素包裹 x 和 test1 元素就会渲染出 test1 的样式。test1 中幽灵元素没造成影响是因为幽灵元素继承了父元素的字体字号与中属性一致​。​

问题解决

可以发现只要控制幽灵元素和其上下间距的范围不超出想实现效果的范围即可

方案:

  • 减小幽灵元素的字体大小(推荐,比较彻底直接设置0)
  • 减小幽灵元素的行高大小

参考:

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×