CSS 世界 阅读笔记:(Ch4-上篇)

CSS 世界 阅读笔记:

对于CSS 这门语言,3 年学习80 分和10 年学习90 分对于产品价值的区别其实有限。
拨开眼前的面纱,定睛一看,会发现,缺的其实不是前端,而是优秀的、有资历的、技术有深度的前端开发人员。
在CSS 的世界里,页面上的任何看似简单的呈现都是由许许多多CSS 属性共同作用的结果。

Ch4 盒尺寸四大家族

4.1 深入理解content

4.1.1 content 与替换元素
1.什么是替换元素

替换元素,顾名思义,内容可以被替换。这种通过修改某个属性值呈现的内容就可以被替换的元素就称为“替换元素”。
(1)内容的外观不受页面上的CSS 的影响。用专业的话讲就是在样式表现在CSS 作用域之外。
(2)有自己的尺寸。
(3)在很多CSS 属性上有自己的一套表现规则。

2.替换元素的默认display 值
元素ChromeFirefoxIE
<img>inlineinlineinline
<iframe>inlineinlineinline
<video>inlineinlineinline
<select>inline-blockinline-blockinline-block
<input>inline-blockinlineinline-block
range/file <input>inline-blockinline-blockinline-block
hidden <input>nonenonenone
<button>inline-blockinline-blockinline-block
<textarea>inline-blockinlineinline-block
3.替换元素的尺寸计算规则

(1)固有尺寸指的是替换内容原本的尺寸。
(2)HTML 尺寸这个概念略微抽象,“HTML 尺寸”只能通过HTML 原生属性改变,这些HTML 原生属性包括<img> 的width 和height 属性、<input> 的size 属性、<textarea> 的cols 和rows 属性等。
(3)CSS 尺寸特指可以通过CSS 的width 和height 或者max-width/min-width 和max-height/min-height 设置的尺寸,对应盒尺寸中的content box。
如果没有CSS 尺寸和HTML 尺寸,则使用固有尺寸作为最终的宽高。
如果没有CSS 尺寸,则使用HTML 尺寸作为最终的宽高。
如果有CSS 尺寸,则最终尺寸由CSS 属性决定。
如果“固有尺寸”含有固有的宽高比例,同时仅设置了宽度或仅设置了高度,则元素依然按照固有的宽高比例显示。
如果上面的条件都不符合,则最终宽度表现为300 像素,高度为150 像素,宽高比2:1。
内联替换元素和块级替换元素使用上面同一套尺寸计算规则。
CSS 世界中的替换元素的固有尺寸有一个很重要的特性,那就是“我们是无法改变这个替换元素内容的固有尺寸的”。

div:before {
    content: url(1.jpg);
    display: block;
    width: 200px; height: 200px;
}

图片中的content 替换内容默认的适配方式是填充(fill),也就是外部设定的尺寸多大,我就填满、跟着一样大。尺寸变化的本质并不是改变固有尺寸,而是采用了填充作为适配HTML 尺寸和CSS 尺寸的方式。

4.替换元素和非替换元素的距离有多远

观点1:替换元素和非替换元素之间只隔了一个src 属性!
由于我们平时使用图片肯定都会使用src 属性,所以难免会思维定式,认为<img> 等同于图片,实际上完全不是的。如果我们把src 属性去掉,<img> 其实就是一个和<span> 类似的普通的内联标签,也就是成了一个非替换元素。

<img alt="美女沉思图" data-src="1.jpg">
<p><button>设置src属性显示图片</button></p>
img {
    display: inline-block;
    width: 256px; height: 192px;
    /* 隐藏Firefox alt文字 */
    color: transparent;
    position: relative;
    overflow: hidden;
}
img:not([src]) {
    /* 隐藏Chrome alt文字以及银色边框 */
    visibility: hidden;
}
img::before {
    /* 淡蓝色占位背景 */
    content: "";
    position: absolute; left: 0;
    width: 100%; height: 100%;
    background-color: #f0f3f9;
    visibility: visible;
}
img::after {
    /* 黑色alt信息条 */
    content: attr(alt);
    position: absolute;
    left: 0; bottom: 0;
    width: 100%;
    line-height: 30px;
    background-color: rgba(0,0,0,.5);
    color: white;
    font-size: 14px;
    transform: translateY(100%);
    /* 来点过渡动画效果 */
    transition: transform .2s;
    visibility: visible;
}
img:hover::after {
    transform: translateY(0);
}
var eleButton = document.querySelector('button'),
    eleImg = document.querySelector('img');

if (eleButton && eleImg) {
    var initValueButton = eleButton.innerHTML;
    // 图片地址
    var srcImage = eleImg.getAttribute('data-src');
    // 移除该属性
    eleImg.removeAttribute('data-src');
    // 按钮点击事件
    eleButton.addEventListener('click', function() {
        if (this.innerHTML == initValueButton) {
            this.innerHTML = '移除src属性';
            // 图片显示
            eleImg.setAttribute('src', srcImage);
        } else {
            this.innerHTML = initValueButton;
            // src属性移除
            eleImg.removeAttribute('src');
        }
    });
}

此时,图片src 没有,因此,::before 和::after 可以生效,我们就可以把alt 属性值通过content 属性呈现出来。当我们点击按钮给图片添加一个src 地址时,图片从普通元素变成替换元素,原本都还支持的::before 和::after 此时全部无效,此时再hover 图片,是不会有任何信息出现的。

观点2:替换元素和非替换元素之间只隔了一个CSS content 属性!
替换元素之所以为替换元素,就是因为其内容可替换,而这个内容就是margin、border、padding 和content 这4 个盒子中的content box,对应的CSS 属性是content,所以,从理论层面讲,content 属性决定了是替换元素还是非替换元素。
如果图片原来是有src 地址的,我们也是可以使用content 属性把图片内容给置换掉的,于是,我们就能轻松实现hover 图片变成另外一张图片的效果。要是放在以前,我们只能借助background-image 或者两个<img> 元素显隐控制实现。

<img class="emoji" src="laugh.png">
.emoji:hover {
    content: url(laugh-tear.png);
}

然后,还有一点有必要说明一下,content 属性改变的仅仅是视觉呈现,当我们以右键或其他形式保存这张图片的时候,所保存的还是原来src 对应的图片。

不仅如此,使用content 属性,我们还可以让普通标签元素变成替换元素。

<h1>《CSS世界》</h1>
h1 {
    content: url(logo.png);
}

传统CSS 代码的<h1>是一个普通元素,因此需要设定尺寸隐藏文字;但是,使用content 属性实现,<h1>分分钟就变成了替换元素,文字自动被替换,同时尺寸规则就是替换元素的尺寸规则,完美适应原始图片大小。
此外,虽然视觉上文字被替换了,但是屏幕阅读设备阅读的还是文字内容,搜索引擎SEO
抓取的还是原始的文本信息,因此,对页面的可访问性等没有任何影响。

5.content 与替换元素关系剖析

(1)我们使用content 生成的文本是无法选中、无法复制的,好像设置了user-select: none 声明一般。
(2)不能左右:empty 伪类。:empty 是一个CSS 选择器,当元素里面无内容的时候进行匹配。

<h4>有内容</h4>
<div class="box">有内容</div>
<h4>无内容</h4>
<div class="box"></div>
<h4>空格也算内容</h4>
<div class="box"> </div>
<h4>伪元素不算内容</h4>
<div class="box pseudo"></div>
.box { 
    width: 216px; 
    padding: 10px; 
    border: 10px solid #cd0000; 
    margin: auto; 
}
.box:empty { 
    border-style: dashed; 
}

(3)content 动态生成值无法获取。

4.1.2 content 内容生成技术
1.content 辅助元素生成

清除浮动;

.clear:after {
	content: '';
	display: table; /* 也可以是'block' */
	clear: both;
}

辅助实现“两端对齐”以及“垂直居中/上边缘/下边缘对齐”效果。:before 伪元素用于辅助实现底对齐;:after 伪元素用于辅助实现两端对齐。

<div id="box" class="box"><i class="bar"></i>
    <i class="bar"></i>
    <i class="bar"></i>
    <i class="bar"></i>
</div>
.box {
    width: 256px;
    height: 256px;
    border-bottom: 1px dashed #ccc;
    text-align: justify;
}
.box:before {
    content: "";
    display: inline-block;
    height: 100%;
}
.box:after {
    content: "";
    display: inline-block;
    width: 100%;
}
.bar {
    display: inline-block;
    width: 20px; height: 0;
}
2.content 字符内容生成

content 字符内容生成就是直接写入字符内容,中英文都可以,比较常见的应用就是配合@font-face 规则实现图标字体效果。除常规字符之外,我们还可以插入Unicode 字符,比较经典的就是插入换行符来实现某些布局或者效果。

正在加载中<dot>...</dot>
dot {
    display: inline-block; 
    height: 1em;
    line-height: 1;
    text-align: left;
    vertical-align: -.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); }
}
3.content 图片生成

content 图片生成指的是直接用url 功能符显示图片。不支持CSS3 渐变背景图。设置宽高无法改变图片的固有尺寸。

4.了解content 开启闭合符号生成

content 支持的属性值中有一对不常用的open-quote 和close-quote 关键字,顾名思义,就是“开启的引号”和“闭合的引号”,使用纯正的中文解释就是“上引号”和“下引号”。
CSS 世界中有一个名为quotes 的属性,可以指定open-quote 和close-quote 字符具体是什么。

5.content attr 属性值内容生成

attr 功能符中的属性值名称千万不要在外面加个引号,否则浏览器会认为是无效的声明。

6.深入理解content 计数器

所谓CSS 计数器效果,指的是使用CSS 代码实现随着元素数目增多,数值也跟着变大的效果。
(1)属性counter-reset。顾名思义,就是“计数器-重置”的意思,主要作用就是给计数器起个名字。默认是0,counter-reset 的计数重置可以是负数,另外,counter-reset 还可以设置为none 和inherit。取消重置以及继承重置。
(2)属性counter-increment。顾名思义,就是“计数器递增”的意思。值为counterreset 的1 个或多个关键字,后面可以跟随数字,表示每次计数的变化值。如果省略,则使用默认变化值1。
普照源(counter-reset)唯一,每普照(counter-increment)一次,普照源增加一次计数值。无论位置在何处,只要有counter-increment,对应的计数器的值就会变化。
计数器的数值变化遵循HTML 渲染顺序,遇到一个increment 计数器就变化,什么时候counter 输出就输出此时的计数值。
counter-reset 可以一次命名两个计数器名称,counter-increment 自然有与之呼应的设定,在写法上也是空格区分就可以了。
正如本节开始时提到的,这变化的值不一定是1,可以灵活设置。值还可以是none 或者inherit。
(3)方法counter()/counters()。这是方法,不是属性。

counter(name);
counter(name, style);

style 参数的作用是:我们递增递减可以不一定是数字,还可以是英文字母或者罗马文等。
counter 还支持级联。也就是说,一个content 属性值可以有多个counter()方法。
counters(name, string);
其中,string 参数为字符串(需要引号包围的,是必需参数),表示子序号的连接字符串。
显示 content 计数值的那个DOM元素在文档流中的位置一定要在counter-increment 元素的后面,否则是没有计数效果的。

        <p>我叫王小二,字如其名,下面要出现的数字是:</p>
        <p class="counter counter1"></p>
        <p>我叫王小二,万万没想到,会出现另外一个数字:</p>
        <p class="counter counter2"></p>
        <p>我本名王小二,万万没想到,我现在居然成了王小...</p>
        <p class="counter counter3"></p>
        <p>我叫王小二,万万没想到,兄弟情深,计数递增!</p>
        <p class="counter counter4"></p>
        <p>我叫王小二,万万没想到,我变成了罗马人!</p>
        <p class="counter counter5"></p>
        <p>我叫王小二,万万没想到,一着不慎,娃娃连营满地滚:</p>
        <div class="reset">
            <div class="counter6">我是王小二
                <div class="reset">
                    <div class="counter6">我是王小二的大儿子</div>
                    <div class="counter6">我是王小二的二儿子
                        <div class="reset">
                            <div class="counter6">我是王小二的二儿子的大孙子</div>
                            <div class="counter6">我是王小二的二儿子的二孙子</div>
                            <div class="counter6">我是王小二的二儿子的小孙子</div>
                        </div>
                    </div>
                    <div class="counter6">我是王小二的三儿子</div>
                </div>
            </div>
            <div class="counter6">我是王小三</div>
            <div class="counter6">我是王小四
                <div class="reset">
                    <div class="counter6">我是王小四的大儿子</div>
                </div>
            </div>
        </div>
        .counter {
            counter-reset: wangxiaoer 2 wangxiaosan 3;
            font-size: 32px;
            font-family: Arial black;
            color: #cd0000;
        }
        .counter1:before {
            content: counter(wangxiaoer);
        }
        .counter2:before {
            content: counter(wangxiaoer);
        }
        .counter2:after {
            content: counter(wangxiaosan);
        }
        .counter3 {
            counter-increment: wangxiaoer;
        }
        .counter3:before {
            content: counter(wangxiaoer);
            counter-increment: wangxiaoer;
        }
        .counter4:before,
        .counter4:after {
            content: counter(wangxiaoer);
            counter-increment: wangxiaoer;
        }
        .counter5:before,
        .counter5:after {
            display: block;
            content: counter(wangxiaoer, lower-roman);
            counter-increment: wangxiaoer;
        }
        .reset {
            padding-left: 20px;
            counter-reset: wangxiaoer;
        }
        .counter6:before {
            content: counters(wangxiaoer, '-') '. ';
            counter-increment: wangxiaoer;
        }
7.content 内容生成的混合特性

各种content 内容生成语法是可以混合在一起使用的。

4.2 温和的padding 属性

4.2.1 padding 与元素的尺寸

CSS 中默认的box-sizing 是content-box,所以使用padding 会增加元素的尺寸。
内联元素padding 对视觉层和布局层具有双重影响。
首先,我们可以在不影响当前布局的情况下,优雅地增加链接或按钮的点击区域大小。
利用内联元素的padding 实现高度可控的分隔线。

a + a:before {
    content: "";
    font-size: 0;
    padding: 10px 3px 1px;
    margin-left: 6px;
    border-left: 1px solid gray;
}
4.2.2 padding 的百分比值

padding 百分比值无论是水平方向还是垂直方向均是相对于宽度计算的!

.box { 
    padding: 10% 50%;
    position: relative;
}
.box > img {
    position: absolute;
    width: 100%; height: 100%;
    left: 0; top: 0;
}

对于内联元素,其padding 是会断行的,也就是padding 区域是跟着内联盒模型中的行框盒子走的。
内联元素的垂直padding 会让“幽灵空白节点”显现,也就是规范中的“strut”出现。由于内联元素默认的高度完全受font-size 大小控制,因此,我们只要:font-size: 0; 此时,“幽灵空白节点”高度变成了0,高和宽就会一样,和块状元素一样的正方形就出现了。

4.2.3 标签元素内置的padding

(1)ol/ul 列表内置padding-left,但是单位是px 不是em。
(2)很多表单元素都内置padding。既语义良好行为保留,同时UI 效果棒兼容效果好的实现小技巧,那就是使用<label>元素。

4.2.4 padding 与图形绘制

padding 属性和background-clip 属性配合,可以在有限的标签下实现一些CSS 图形绘制效果。
不使用伪元素,仅一层标签实现大队长的“三道杠”分类图标效果。

.icon-menu {
    display: inline-block;
    width: 140px; height: 10px;
    padding: 35px 0;
    border-top: 10px solid;
    border-bottom: 10px solid;
    background-color: currentColor;
    background-clip: content-box;
}

不使用伪元素,仅一层标签实现双层圆点效果。

.icon-dot {
	display: inline-block;
	width: 100px; height: 100px;
	padding: 10px;
	border: 10px solid;
	border-radius: 50%;
	background-color: currentColor;
	background-clip: content-box;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值