分类
CSS

内联盒模型-关于line-box的探究(多图预警)

涉及到内联盒模型,应该是css世界中最复杂,最难以理解的模型,本次仅仅探索涉及到内联盒模型的line-box的一些让人难以理解的现象,找到本质原因之后一定会让你足够惊喜。

参考文献(理论基础):https://www.cnblogs.com/10yearsmanong/p/13084706.html

首先看例子

qi ye wei xin jie tu 16145161258073 - 内联盒模型-关于line-box的探究(多图预警)

html

<body>
<div class="z"></div>
<div class="x">
    <span class="a">x</span>
    <span class="b">哇</span>
    <span class="c">移</span>
</div>
<div class="y"></div>
</body>

css

 .z{
            height:100px;
            background:yellow;
        }
        .x{
            font-size:0;
            line-height:0;
        }
        .a{
            font-size:200px;
        }
        .b{
            display: inline-block;
            font-size:20px;
        }
        .c{
            font-size:20px;
        }
        .y{
            height:10px;
            background-color: red;
        }

问题1:line-box是哪个区块?

是红色与黄色之间的白色块,我们可以通过定义证明,vertical-align:top/bottom的定义为与line-box的顶部或底部对齐。于是我们设置.b与.c的vertical-align分别为top和bottom。

qi ye wei xin jie tu 16145168104716 - 内联盒模型-关于line-box的探究(多图预警)

我们确实能够看到‘哇’和‘移’在白色块的上边和下边,但为什么是两字的中间对齐line-box的上边缘与下边缘呢?

问题2:为什么是‘哇’字中间对齐上边缘?

首先我们可以看到‘哇’对应的属性是line-height:0;font-size:20;这个line-height为什么是0呢,就要从该属性说起,line-height是可以继承的,当它是数字的时候,子元素继承的也是数字,当它是百分比或者说数值(12px,1em,1rem,等)它会根据当前font-size的大小计算得出一个具体值然后继承下去(比如font-size:20px;line-height:200%,继承下去的是line-heignt:40px;),因此‘哇’的visual-area的顶部对齐了line-box的顶部。

问题3:什么是visual-area?

就是该内联元素的line-height,既然有了visual-area那就引申出content-area。

3720408019 5a3b79af7559e articlex - 内联盒模型-关于line-box的探究(多图预警)
1496711390 5a3b79b00736d articlex - 内联盒模型-关于line-box的探究(多图预警)

以Baseline基线为0,content-area=fontSize*(ascender-descender+lineGap)/emSquare

其中ascender,descender,lineGap是一款字体定义的属性。

137665312 5a3b79af2f6be articlex - 内联盒模型-关于line-box的探究(多图预警)

基于此line-height:normal也可以计算

line-height:normal=(ascender-descender+lineGap)/emSquare。

因此我们知道content-area只会受font-family和font-size影响。当visual-area大于content-area时,会产生leding,1/2的leading分别加到content-area的上方与下方所以content-area总是处于visual-area中间,当visual-area为0时(line-height:0)就能看到‘哇’字的中间处于line-box上边缘。

问题4:line-box是如何产生的?

首先内联盒模型会产生line-box,它的触发条件时块状盒子内部只有内联元素(inline-block也算)。

问题5:为什么白色区块是line-box?

qi ye wei xin jie tu 16145161258073 - 内联盒模型-关于line-box的探究(多图预警)

首先我们得了解line-box的意义,它决定了一行内联元素所占据文档流的高度,若超出一行,则会重新生成一行line-box。所以每一行line-box的高度可能是不同的。每一行line-box会生成一个宽度为0,font-size为父元素font-size的幽灵子节点(strut)。

要解决这个问题,首先要知道base-line的位置是由什么决定的。

问题6:base-line的位置由什么决定?

若只有一个元素,base-line的位置由ascender与descender共同决定(小写x底部位置),若有多个元素,则由最下方的base-line决定

qi ye wei xin jie tu 16145210404958 - 内联盒模型-关于line-box的探究(多图预警)

首先‘x’,‘哇’,‘移’的line-height均为0,因此他们的实际高度也为0,于是从黄色块下边缘依次排布,content-area在中间位置,得出base-line为‘x’的x下边缘(在所有base-line的最下方)。

而base-line是所有的内联元素共同决定的。它是怎么得出的呢?看下图。

qi ye wei xin jie tu 16145221431830 - 内联盒模型-关于line-box的探究(多图预警)
多个元素决定line-box高度

也许有小伙伴对x的line-height所处位置存疑,请看下图。

qi ye wei xin jie tu 16145225721799 - 内联盒模型-关于line-box的探究(多图预警)
qi ye wei xin jie tu 16145226212275 - 内联盒模型-关于line-box的探究(多图预警)

2021/03/01更新

我们基于最开始的代码,进行一点变更继续探索,首先变更的地方为

  .x{
            font-size:1px;
        }
qi ye wei xin jie tu 16145637328073 - 内联盒模型-关于line-box的探究(多图预警)

问题7:红块为什么会上移?

首先我们将.x元素的font-size设置为1px后,我们在chrome上进行调试,chrome的font-size在1-12px之间时,统一为12px。因此可以有这样一张图。

qi ye wei xin jie tu 16145641934716 - 内联盒模型-关于line-box的探究(多图预警)

因为幽灵字节的的font-size从0上升至12px,因此幽灵字节点的line-height位置由在baseline处往上抬了当前字体在12px时所生成的该x的baseline到该x的1/2content-area的距离。因为在目前line-box中还是幽灵子节点的font-size最小,因此还是取幽灵子节点的line-height位置为最下方,并生成line-box。

问题8:transform对内联元素的影响?

transform属性对display:inline的元素无任何作用,对inline-block的元素有样式上的影响,但对他本身占据的文档流的位置和大小无任何影响。

qi ye wei xin jie tu 16145659814958 1024x403 - 内联盒模型-关于line-box的探究(多图预警)

问题9:vertical-align:text-top/text-bottom对齐的是谁。

幽灵子节点的content-area。以下是证明

qi ye wei xin jie tu 16145665543453 1024x555 - 内联盒模型-关于line-box的探究(多图预警)
qi ye wei xin jie tu 16145666932449 1024x484 - 内联盒模型-关于line-box的探究(多图预警)

问题10:vertical-align:text-top/text-bottom与line-height有关吗?

无关,以下是证明

qi ye wei xin jie tu 16145687882171 1024x484 - 内联盒模型-关于line-box的探究(多图预警)

问题11:为何经过上方设置后,line-box变这么大?

  • 通过各元素的content-area比较得出最下方的baseline为最大的X(幽灵子节点content-area为0)
  • 幽灵子节点加入战场,它的line-height为200px,所处位置为baseline处,但它的visual-area比其他子元素都要大于是由它决定了line-box
qi ye wei xin jie tu 16145692985085 1024x410 - 内联盒模型-关于line-box的探究(多图预警)

问题12:inline-block对line-box有何影响?

inline-block元素的padding,margin,border,height共同组成content-area,inline-block的content-area等于visual-area。

分类
CSS

凹形文字凸形文字生成

前置学习

ui工程师会给我们rgb颜色值,若要制作一个凹形或凸形文字需要另一个相对颜色作为文字或背景颜色。所以rgb转hsl。

fc13b9d7fe908945256576c87e621ebf - 凹形文字凸形文字生成
e910e98140e29eb144d3de71e83a1aa5 - 凹形文字凸形文字生成
7b0b16bda5541d50fb9e65755d53a840 - 凹形文字凸形文字生成

凹形文字

浅色背景深色文字底部加上浅色投影
.x{
            display:flex;
            justify-content:center;
            align-items: center;
            color:hsl(210,13%,30%);
            background-color:hsl(210,13%,60%);
            text-shadow:0 .03em .03em hsla(0,0%,100%, .8);
        }

凸形文字

深色背景浅色文字顶部加上深色投影
.y{
            display:flex;
            justify-content:center;
            align-items: center;
            color:hsl(210,13%,60%);
            background-color:hsl(210,13%,30%);
            text-shadow:0 -.03em .03em hsla(0,0%,0%, .8);
        }
分类
CSS

一种新动画 我称之为组装。

这种动效也是我灵光一闪想出来的,当然需要一些基础的沉淀。

动画效果

assemble - 一种新动画 我称之为组装。

技术储备

这里需要两种技术沉淀,第一种是transition-timing-function中的steps,它可以使动画像阶梯状呈现,就像一部连续的电影取其中的几帧一样。第二种是-webkit-mask遮罩,在css中若对一个元素使用遮罩,那被遮元素则只能看见一部分内容,这部分就是遮罩图片不透明的部分。如果遮罩图片有半透明的部分,则也会显示出来,只不过显示出来的部分也是半透明的。

思路

首先我们假设有这样一张遮罩图片

0000.20.40.60.811111
00000.20.40.60.81111
000000.20.40.60.8111
里面的数字代表透明度

然后我们把遮罩元素的大小定义为宽400%高100%。

现在我们遮罩的位置在初始位置,所以我们是看不见任何东西的。

那如果我们遮罩的位置向右移动一格呢?我们会发现右上角有一个小方块能显示出来了,按照规律一步步的向右移动,最后该元素就会完全显示!

好了,我们现在要解决一个每次移动都精准的只移动一格的问题。

首先我们要让遮罩移动,则一定会改变-webkit-mask-position,它的作用规则与background-position是一样的。无论背景大小定义的有多大,只要他们的值定义为100%,那就会移动到最右边。然后steps函数就派上了用上,我们设定移动到最右边需要9步,那么每一次截图出来的动画正好是移动一格的位置。

 @keyframes wpSpan{
            0%{
                -webkit-mask-position:0;
            }
            100%{
                -webkit-mask-position:100%;
            }
        }
.x1{
            height:510px;
            background-image: url(./img/border-1.png);
            background-size:cover;
            -webkit-mask-image:url(./svg/8.svg);
            -webkit-mask-size: 400% 100%;
            visibility: hidden;
            -webkit-mask-position:0;
            transition: -webkit-mask-position 1s steps(9,end),visibility 0s 1s;
        }
.x1.active{
            visibility:visible;
            -webkit-mask-position:100%;
            transition: -webkit-mask-position 1s steps(9, end);
        }

图片选择

其实这样看来,最后使这个动画实现的决定性因素其实是图片。我曾经做过这样的探索,如果使用canvas创建一个这样一个图片并转换为base64格式能不能实现这样的效果呢?

结论是实现效果不理想,因为图片太小,在放大后小方格就显示不出来了,如果图片太大,那获取图片的代价有点大,而且有失真的缺点。

所以我选择的是svg图片,如果要制作上述的遮罩,只要设定宽12高3,在非透明的地方放入小方块。

普通的svg图片是不能自适应大小的,所以我们要设置如下

<svg width="12" height="3" viewBox="0 0 12 3"
     preserveAspectRatio="none"
     xmlns="http://www.w3.org/2000/svg">
。。。。。
</svg>

结束语

如果想要源代码和这个svg图片的话,欢迎访问我的github

https://github.com/zhuishao/hundredstest/blob/master/138.html

分类
CSS

css加载优化

不参与首屏渲染的css异步加载

<link rel="stylesheet" href="/path/to/my.css" media="print" onload="this.media='all'">

media=“print”是打印时的css,因此它不会立刻加载,但是我们又希望加载后的css应用于所有屏幕,所以会有onload=”this.media=’all'”

将某一段css提升至很高的优先级

<link rel="preload" href="/path/to/my.css" as="style">

使用的是预加载技术

qi ye wei xin jie tu 16005895378073 1024x591 - css加载优化

根据不同的屏幕分辨率加载不同的css

<link rel="stylesheet" href="index.css" media="all" />
<link rel="stylesheet" href="mobile.css" media="(max-width:44.9375rem)" />
<link rel="stylesheet" href="table.css" media="(min-width: 45rem)" />

不同的页面加载不同的css

这方面vue做的很好,进入一个vue的路由,它将加载该路由下所有组件的style处的css,因此我们可以尝试减少公有的css,将特定使用的css放入组件内。

分类
CSS

CSS复现让你惊叹的PPT技巧(1)

概览

  • 字体中的风景
  • 图像进度条

字体中的风景

需要一个背景,并将背景剪裁到字体。最后将字体的颜色设置为透明。

技术要点
diu - CSS复现让你惊叹的PPT技巧(1)
选用的背景图片

选用的字-MMJJ

合成效果图

Rec 0002 - CSS复现让你惊叹的PPT技巧(1)
由于文章内不好写代码,只能录制为gif。

代码

html

<div class="txt-clip">MMJJ</div>

css

 .txt-clip {
            height: 100vh;
            font-size: 20vw;
            display: flex;
            /*水平居中*/
            justify-content:center;
            /*垂直居中*/
            align-items:center;
            /*背景图*/
            background-image: url(./img/diu.gif);
            background-size: cover;
            /*背景位置*/
            background-position:center 121px;
            /*背景裁剪*/
            background-clip: text;
            -webkit-background-clip: text;
            /*字体颜色设置*/
            color: transparent;
        }

图像进度条

需要一张图片,在两块地方使用,一张原图做背景,一张置灰做内部图片,并重合。经过裁剪显示进度。

上方是思路

选择图片

fenda - CSS复现让你惊叹的PPT技巧(1)

实现效果

Rec 0003 - CSS复现让你惊叹的PPT技巧(1)
由于变成了gif,会有点卡。

代码

html

<div class="img-clip-wrap">
    <img class="img-clip" src="./img/fenda.png" height="300">
</div>

css

     @keyframes progress{
            from {
                /*clip-path:polygon点的集合连接成一个图形,该图形是保留的部分*/
                clip-path:polygon(0 0, 100% 0, 100% 50%, 0 50%);
            }
            to {
                clip-path:polygon(0 0, 100% 0, 100% 0, 0 0)
            }
        }
  .img-clip-wrap{
            height:300px;
            display: flex;
            justify-content:center;
            align-items:center;
            background-image: url(./img/fenda.png);
            background-size:auto 100%;
            background-repeat:no-repeat;
            background-position:center;
        }
.img-clip{
            /*使用滤镜变灰色*/
            filter:grayscale(1);
            /*初始裁剪是裁剪了图片的上半部分*/
            clip-path:polygon(0 0, 100% 0, 100% 50%, 0 50%);
            animation: progress 3s ease-in-out infinite;
        }

总结

  • 在字体中的风景部分,主要用到了背景设置,背景裁剪技术。同样,也可以用mask遮罩实现该效果,这里暂且不表。
  • 在图像进度条部分,主要用到了filter滤镜,clip-path裁剪。