《CSS世界》读书笔记

7 阅读13分钟

要点

第三章 基本尺寸

1. 宽度分离

所谓“宽度分离原则”,就是 CSS 中的 width 属性不与影响宽度的 padding/border(有时候包括 margin)属性共存,也就是不能出现以下的组合:

 .box { width: 100px; border: 1px solid; } 

或者

.box { width: 100px; padding: 20px; } 

要改为:

 .father {   width: 180px;  } 
 .son {   margin: 0 20px;   padding: 20px;   border: 1px solid;  } 

2. 如何评价 *{box-sizing:border-box}

  1. 这种做法易产生没必要的消耗

search 类型的搜索框,其默认的 box-sizing 就是 border-box(如果浏览器支持)

  1. 这种做法并不能解决所有问题

box-sizing 不支持 margin-box,只有当元素没有水平 margin 时候,box-sizing 才能真正无计算,而“宽度分离”等策略则可以彻底解决所有的宽度计算的问题。

  1. 【疑问】margin如何改变元素的尺寸?

3. width/height

  1. 【疑问】既然子元素没渲染,怎么知道宽度?

4. 关于 height:100%

  1. 为何 height:100%无效

如果包含块的高度没有显式指定(即高度由内容决定),并且该元素不是绝对定位,则计算值为 auto。一句话总结就是:因为解释成了 auto。

宽度的解释却是:如果包含块的宽度取决于该元素的宽度,那么产生的布局在 CSS 2.1 中是未定义的。

高度明确了就是 auto, 高度百分比计算自然无果,width 却没有这样的说法,因此,就按照包含块真实的计算值作为 百分比计算的基数。

  1. 如何让元素支持 height:100%效果

    • 设定显式的高度值
    • 使用绝对定位
  2. 宽高百分比计算(查看示例

    • 绝对定位的宽高百分比计算 是相对于 padding box 的,也就是说会把 padding 大小值计算 在内

    • 非绝对定位元素则 是相对于 content box 计算的

  3. max-* min-*

    • max-width 和 max-height 的初始值是 none
  4. min-width/min-height 的初始值

    • MDN 和 W3C 维基的文档上都显示 min-width/min-height 的初始值是 0
    • 作者测试是 auto
  5. 规则冲突的时候,min-width覆盖max-width

  1. 幽灵空白节点

“幽灵空白节点” 实际上也是一个盒子,不过是个假想盒,名叫“strut”,中文直译为“支柱”,是一个存在于每个“行 框盒子”前面,同时具有该元素的字体和行高属性的 0 宽度的内联盒。

第四章 盒尺寸

1. content

  1. 伪元素的宽高取决于固有尺寸,不受 css 属性控制

  2. 替换元素和非替换元素

    • src 属性去掉,替换元素表现为非替换元素

    存疑,火狐中即使设置 block 和宽高,空的 img标签尺寸为0*0

    • content 属性可以将非替换元素展示为替换元素(如 h1

2. Padding

  1. 内联元素的padding,会影响自身尺寸,不影响外部尺寸

CSS 中还有很多其他场景或属性会出现这种不影响其他元素布局而是出现层叠效果的现 象。比如,relative 元素的定位、盒阴影 box-shadow 以及 outline 等。这些层叠现象虽 然看似类似,但实际上是有区别的。其分为两类:一类是纯视觉层叠,不影响外部尺寸;另一 类则会影响外部尺寸。box-shadow 以及 outline 属于前者,而这里的 inline 元素的4.2 温和的 padding 属性 75 padding 层叠属于后者。区分的方式很简单,如果父容器 overflow:auto,层叠区域超出父 容器的时候,没有滚动条出现,则是纯视觉的;如果出现滚动条,则会影响尺寸、影响布局

  1. 如何避免hash定位被fixed元素挡住?

很多人会想到让标题栏设置一个 padding-top:50px,但是,这种影响布局的事情大多 数时候只是理论上可行,难道没有什么简单实用的办法吗?这时候,我们不妨试试使用内联元 素,块级元素设置 padding-top:50px 会影响布局,但是内联元素不会,于是,事情就简单 了。假设下面是原来的实现:

<style>
 h3 { line-height: 30px; font-size: 14px; }
</style>
<h3 id="hash">标题</h3>

则我们可以将其改成:

<style>
h3 { line-height: 30px; font-size: 14px; } h3 > span { padding-top: 58px; }
</style>
<h3><span id="hash">标题</span></h3> 

这样既不影响原来的布局和定位,同时又把定位位置往下移动了 50 像素

虽然这不是十全十美的方法,但是总体性价比还是很不错的。然后,如果我们的 <h3> 标签设置 overflow:hidden,则 Chrome 和 Firefox 浏览器定位不受影响,但是 IE 浏览器会定位在<h3>标签位置,这个需要注意。

3. 【存疑】padding-bottom在火狐中失效?

书中提到:

只能使用子元素的 margin-bottom 来实现滚动容器的底部留白

使用父元素padding-bottom:

<div style="overflow: auto; padding-bottom: 100px; height: 200px; scroll-behavior: auto">
            <img height="300" style="border: 1px red solid; width: 100px" />
</div>

火狐中,可以看到边距

3. margin

  1. margin:auto 如果一侧定值,一侧 auto,则 auto 为剩余空间大小
  2. 等高布局 demo.cssworld.cn/4/3-2.php
.column-box {   overflow: hidden;  }  
.column-left,  .column-right {   margin-bottom: -9999px;   padding-bottom: 9999px;  } 
  1. 【疑问】列表两端对齐?自测并无该效果

4. border

  1. border-width 支持若干关键字,包括 thin、medium(默认值) 和 thick,对应的尺寸大小具体如下

• thin:薄薄的,等同于 1px。

• medium(默认值):薄厚均匀,等同于 3px。

• thick:厚厚的,等同于 4px。

  1. 清除边框性能最高的办法:
border-bottom: 0 none; 
  1. border-color 默认颜色就是 color 色值
  2. 默认 background 背景图片是相对于 padding box 定位的,也就是说,background-position:100%的位置计算默认是不会把 border-width 计算在内的
  3. 等高布局 demo.cssworld.cn/4/4-4.php

左侧深色背景区域是由 border-left 属性生成的。元素边框高度总是和元素 自身高度保持一致,因此可以巧妙地实现等高布局效果。

.box {   border-left: 150px solid #333;   background-color: #f0f3f9;  }  
.box > nav {   width: 150px;   margin-left: -150px;   float: left;  }
.box > section {   overflow: hidden;  } 

第五章 内联元素与流

1. 字母X

  1. ex垂直居中 demo.cssworld.cn/5/1-1.php
.icon-arrow {
   display: inline-block;
   width: 20px;
   height: 1ex;   
   background: url(arrow.png) no-repeat center;  
}

2. 行高

  1. 父元素设置 line-height:150% 或 1.5em ,子元素按父元素的 font-size 计算行高

父元素设置 line-height:1.5 ,子元素按自身 font-size 计算行高

  1. 在 CSS 中,计算行高的时候,行高值一定不要向下舍 入,而要向上舍入。上面虽然 14*1.42857 计算机近乎是 20px,但在 Chrome 浏览器下,依 然以 19px 的高度呈现,如果我们向上舍入取 1.42858,则最终所有浏览器行高计算值是 20px
body {   line-height: 1.42857;   font-size: 14px;  } 
  1. 一个 inline-block 元素,如果里面没有内联元素,或者 overflow 不是 visible, 则该元素的基线就是其 margin 底边缘;否则其基线就是元素里面最后一行内联元素的基线。

  2. 基于 20px 图标对齐的处理技巧

    • 图标高度和当前行高都是 20px
    • 图标标签里面永远有字符,这个可以借助:before 或:after 伪元素生成一个空格字 符轻松搞定。
    • 图标 CSS 不使用 overflow:hidden 保证基线为里面字符的基线,但是要让里面潜在的字符不可见。
.icon {
    display: inline-block;   width: 20px; height: 20px; 
    background: url(sprite.png) no-repeat;   
    white-space: nowrap;   
    letter-spacing: -1em;   
    text-indent: -999em;  
 }  
.icon:before {   content: '\3000';  } 

/* 具体图标 */  
.icon-xxx {   background-position: 0 -20px;  }
  1. 疑问:为什么此时 .box 用font-size:0没有这种效果,反而让.box高度更大了?

 <style>
            .box {
                line-height: 32px;
                font-size: 0;
            }
            .box > span {
                font-size: 24px;
            }
  </style>
  <div class="box">
       <span>文字</span>
  </div>

第六章 流

1. Float

  1. 浮动元素的 display 计算值是 block 或者 table (应该还有 flex grid)
  2. float 定位参考的是“行框盒子”

  1. clear 属性是让自身不能和前面的浮动元素相邻,对“后面的”浮动元素是不闻不问的

  2. 关于 overflow-x 和 overflow-y 属性

书中提到:

如果 overflow-x 和 overflow-y 属性中的一个值设置为 visible 而另 外一个设置为 scroll、auto 或 hidden,则 visible 的样式表现会如同 auto。

也就是说, 除非 overflow-x 和 overflow-y 的属性值都是 visible,否则 visible 会当成 auto 来解析。

换句话说,永远不可能实现一个方向溢出剪裁或滚动,另一方向内容溢出显示的效果。

因此,下面 CSS 代码中的 overflow-y:auto 是多余的:

html {   
    overflow-x: hidden;   
    overflow-y: auto; /* 多余 */  
} 
  1. 纵轴滚动条的宽度

Chrome: 以前是17px,现在15px

Firefox:0px

2. position

  1. absolute 定位默认在原位置,而非左上角
  2. 如果 overflow 不是定位元素,同时绝对定位元素和 overflow 容器之间也没有定位元素,则 overflow 无法对 absolute 元素进行剪裁。

因此下面 HTML 中的图片不会被剪裁:

   <div style="overflow: hidden;">
            <img src="1.jpg" style="position: absolute;">
     </div>

overflow 元素父级是定位元素也不会剪裁,例如:

<div style="position: relative;"> 
     <div style="overflow: hidden;"> 
     <img src="1.jpg" style="position: absolute;">  </div> 
</div>

但是,如果 overflow 属性所在的元素同时也是定位元素,里面的绝对定位元素会被剪裁:

 <div style="overflow: hidden; position: relative;">
     <img src="1.jpg" style="position: absolute;"> <!-- 剪裁 --> 
</div> 

如果 overflow 元素和绝对定位元素之间有定位元素,也会被剪裁:

<div style="overflow: hidden;"> 
     <div style="position: relative;">
         <img src="1.jpg" style="position: absolute;"> <!-- 剪裁 -->
     </div> 
</div> 

如果 overflow 的属性值不是 hidden 而是 auto 或者 scroll,即使绝对定位元素高宽 比 overflow 元素高宽还要大,也都不会出现滚动条。demo:demo.cssworld.cn/6/5-11.php

第七章 层叠规则

z-index

  1. 层叠顺序

  • inline 水平盒子指的是包括 inline/inline-block/inline-table 元素的“层 叠顺序”,它们都是同等级别的

  • 单纯从层叠水平上看,实际上 z-index:0 和 z-index:auto 是可以看成是一样的

  1. 创建层叠上下文

(1)元素为 flex 布局元素(父元素 display:flex|inline-flex),同时 z-index 值不是 auto。

(2)元素的 opacity 值不是 1。

(3)元素的 transform 值不是 none。

(4)元素 mix-blend-mode 值不是 normal。

(5)元素的 filter 值不是 none。

(6)元素的 isolation 值是 isolate。

(7)元素的 will-change 属性值为上面 2~6 的任意一个(如 will-change:opacity、 will-chang:transform 等)。

(8)元素的-webkit-overflow-scrolling 设为 touch。

第八章 强大的文本处理能力

1. font-size

  1. 文字图标对齐:demo.cssworld.cn/8/1-1.php
p > img {
    width: 16px; height: 16px;
    /* vertical-align: 25%; */
    /* 更推荐 ex */
     vertical-align: .6ex;
    position: relative;
    top: 8px;
}
  1. 1em 的计算值等同于当前元素所在的 font-size 计算值

所以如下代码中,<h1> 元素 margin-before 的像素计算值 是 32px×0.67 = 21.44px

h1 {
      font-size: 2em;
      -webkit-margin-before: 0.67em;
      -webkit-margin-after: 0.67em;
} 
  1. em的使用场景:适用于图文内容展示的场景,对此进行弹性布局。

    1. <h1>~ <h6>以及<p>等与文本内容展示的元素的 margin 都是用 em 作为单位,这样,当用户把浏览 器默认字号从“中”设置成“大”或改成“小”的时候,上下间距也能根据字号大小自动调整, 使阅读更舒服。
    2. 如果我们使用 SVG 矢量图标,建议设置 SVG 宽高如下:
        svg {
                width: 1em; height: 1em;
        } 
    

这样,无论图标是个大号文字混在一起还是和小号文字混在一起,都能和当前文字大小保持一致

  1. 字重临界点:100、400、700、900

先 font-weight:100,然后再 font-weight:bolder 后的 font-weight 计算大小是 400

此前做需求时遇到过浏览器智能加粗的情况:

在预设了缺少 font-weight 的 @font-face 后,使用时设置了字重,浏览器的加粗效果与设计要的效果不一样。

解决方案是再引入一套加粗的字体:

@font-face { font-family: 'xxx'; font-weight: 400; }
  1. font 简写属性完整语法:
[ [ font-style || font-variant || font-weight ]? font-size [ / line-height ]? 
    font-family ]

font-size 和 font-family 必须都有。

2. White-space

3. text-decoration

如何解决下划线和文本重叠的问题?

使用 border

a {
   text-decoration: none; border-bottom: 1px solid; padding-bottom: 5px; 
} 

4. ::first-letter

  1. 伪元素生效的前提

    1.   不是所有的字符都能单独作为::first-letter 伪元素存在的。比如 ·@#%&*()()[]【】{}::"“”;;'‘’》《,,.。??!!...*、/\
    2.   正常情况下可以直接作为伪元素的字符就是数字、英文字母、中文、$、一些运算符,以 及非常容易被忽视的空格等。 还有::before 伪元素
  2. 【疑问】书上提到:

元素的 display 计算值必须是 block、inline-block、list-item、table- cell 或者 table-caption,其他所有 display 计算值都没有用,包括 display:table 和 display:flex 等。

后面又说:

demo.cssworld.cn/8/7-1.php 实测,flex 不生效。

书上提到 table 有效,测试同样无效。

第九章 元素的装饰与美化

  1. background-position 百分比计算方式

positionX = (容器的宽度 - 图片的宽度) * percentX;

positionY = (容器的高度 - 图片的高度) * percentY;

如果图片尺寸大于容器尺寸,设置的又是负数百分比,那么最终算出来是正数,定位在容器内部。

  1. 【疑问】大量小图渲染会有卡顿?

第十章 元素的显示与隐藏

visibility

  1. 父元素不可见时,子元素可以可见
  2. visibility:hidden 不会影响计数器的计数,这和 display:none 完全不一样
  3. 让鼠标光标移出的时候列表无延时地迅速隐藏
.list {   position: absolute;   visibility: hidden;  }  
td:hover .list {   visibility: visible;   transition : visibility 0s . 2s ;  }

第十二章 流向的改变

writing-mode、direction 和 unicode-bidi 是 CSS 世界中三大可以改变文本布局 流向的属性,其中 direction 和 unicode-bidi 属于近亲,经常一起使用,也是仅有的两个 不受 CSS3 的 all 属性影响的 CSS 属性

其他语录摘抄

  1. #iefix 严格来说还是有点儿用的,它可以让请求地址短一 些,因此请求地址是不包括锚点标志#及其后面的内容的。如果按照这种说法,那岂不是说 iefix 这几个字符多余?没错,多余!不懂的人不知道是干什么用的,懂的人知道它是没什么用的,因此多余。
  2. 关于使用空标签心理障碍。有人对代码有洁癖,原本规整的列表最后加几个空标签, 心里难受。这种心理往往出现在新人身上,本质上是因为关注点是代码自身,而不是产品、同 事或公司更高层面的东西。于是,当产品经理提需求时,他们想到的是我的代码如何如何,而 不是产品收益如何如何。毕竟我们是职场人,很显然,创造收益和价值的意识要远比代码洁癖 心理对职业生涯发展帮助更大。回到我们这里,代码排版确实不美了,但是功能很好地实现了, 且非常健壮,容错性强,而且对 SEO 没有任何干扰,对辅助设备访问也没有任何干扰,百益无 一害,有什么好难受的呢!