css揭秘阅读笔记

记录一些关于 css 的一些奇妙的方法。

背景与边框

粘性碰撞

    <style>
      // 外面的容器
      #hit-container {
        width: 320px;
        height: 200px;
        padding-top: 50px;
        filter: contrast(10);
        background: #fff;
        position: relative;
      }

      #blackball {
        width: 100px;
        height: 100px;
        background: black;
        padding: 10px;
        border-radius: 50%;
        margin: 0 auto;
        z-index: 1;
        filter: blur(5px);
      }
      #redball {
        width: 60px;
        height: 60px;
        background: #f00;
        padding: 10px;
        border-radius: 50%;
        position: absolute;
        top: 70px;
        left: 50px;
        z-index: 2;
        filter: blur(5px);
        animation: rball 6s infinite;
      }

      @keyframes rball {
        0%,
        100% {
          left: 35px;
          width: 60px;
          height: 60px;
        }
        4%,
        54% {
          width: 60px;
          height: 60px;
        }
        10%,
        60% {
          width: 50px;
          height: 70px;
        }
        20%,
        70% {
          width: 60px;
          height: 60px;
        }
        34%,
        90% {
          width: 70px;
          height: 50px;
        }
        41% {
          width: 60px;
          height: 60px;
        }
        50% {
          left: calc(100% - 95px);
          width: 60px;
          height: 60px;
        }
      }
    </style>

多重边框

多重边框也是依靠 box-shadow 绘制而成。

<style>
  .borders {
    width: 60px; height: 60px;
    border-radius: 50%;
    background: #fafafa;
    margin: 105px 29px;
    box-shadow: 0 0 0 10px #E8E2D6, 0 0 0 20px #E1D9C9,
                0 0 0 30px #D9CFBB, 0 0 0 40px #D2C6AE,
                0 0 0 50px #CABCA0, 0 0 0 60px #C3B393,
                0 0 0 70px #BBA985, 0 0 0 80px #B4A078;
  }
</style>

条纹背景

条纹进度条使用的是linear-gradient绘制条纹,keyframes绘制动画。

<style>
    .progress-outer {
        width: 60%; height: 12px;
        border-radius: 8px;
        overflow: hidden;
        position: relative;
    }
    .progress-enter {
        height: inherit;
        background: rgba(180, 160, 120, .2);
    }
    .progress-bg {
        width: 60%; height: inherit;
        border-radius: 6px;
        background-size: 16px 16px;
        animation: panoramic 20s linear infinite;
        background: linear-gradient(-45deg, #D9CFBB  25%, #C3B393 0, #C3B393 50%,
            #D9CFBB 0, #D9CFBB 75%, #C3B393 0);
        // 关于这里的#C3B393 0,表示终止渐变,<color-stop> = <color> [ <percentage> | <length> ]。这里的0代表的是0px,表示在25%的时候#C3B393颜色的长度为0,当某个色标的位置值比整个列表中在它之前的色标的位置值都要笑,则该色标的位置值会被设置为它前面所有色标位置的最大值,所以他的长度为0,就相当于#C3B393 25%,然后#C3B393 50%表示在从之前的位置到50%都是#C3B393,所以就相当于这25%到50%没有发生渐变。

    }

    @keyframes panoramic{
        to {
            background-position: 200% 0;
        }
    }
</style>

边框内角圆弧

因为 box-shadow 会在 border 外侧紧贴 border,而 outline 则紧贴没有 radius 的 border。所以两者一起使用可以使内边框产生一定的弧度。

<style>
  .radius{
    width: 209px;
    margin: 29px auto;
    padding: 8px 16px;
    border-radius: 8px;
    background: #f4f0ea;
    outline: 6px solid #b4a078;
    box-shadow: 0 0 0 6px #b4a078;
  }
</style>
Here is some text!

伪随机背景

所谓伪随机背景,就是我们不能通过肉眼观察到背景以某种规律排列。

在 css 揭秘中,他使用的方法的思想是,在一种颜色作为底色,然后其他的颜色覆盖在这个底色上,然后每隔一段距离重复。但是既然要生成伪随机背景,这个距离就要求他们的最小公倍数尽可能的大,因为他们的最小公倍数就是一个循环所需要的距离。 在总共使用 4 个背景的情况下,他使用的距离是41,61,83

<style>
  .pesudo-random-bg {
    width: 400px;
    height: 100px;
    margin: 0 auto;
    background: hsl(20, 40%, 90%);
    background-image: linear-gradient(90deg, #fb3 11px, transparent 0),
                      linear-gradient(90deg, #ab4 23px, transparent 0),
                      linear-gradient(90deg, #655 41px, transparent 0);
    background-size: 41px 100%, 61px 100%, 83px 100%;
  }
</style>

连续的图像边框

这个 demo 主要学习的是多个背景的添加以及 border-image 的设置。

<style>
  .bg-within-words {
    width: 100px;
    height: 100px;
    padding: 20px;
    border: 20px solid transparent;
    background: linear-gradient(white, white), url(./bg.jpg);
    background-size: cover;
    background-clip: padding-box, border-box;   // 背景绘制的区域
    background-origin: padding-box, border-box;    // 背景图片相对于某个边框来定位
  }
</style>
Hey!

顺便我还学习了 border-image 这个 css 属性,虽然以前用过它来写渐变的按钮背景,但是发现自己对它的相关属性还是不是很了解。主要是border-image-slice。有人说它和background-clip类似,但是我发现其实还是有很大出路的。因为background-clip是相对于左上角来写top right bottom left的距离,但是border-image-slice是相对于各个边来写距离。
border-image-width会覆盖border-width

形状

椭圆

由于平时我们用的 border-radius 都是单数据的,导致我们对这个属性了解的不深入,其实他实际包括了 8 个值:border-radius: 左上 右上 右下 左下的水平半径 / 左上 右上 右下 左下的垂直半径,注意这里的/之前都是水平,之后都是垂直。并不是通常我们认为的每个位置都是左上水平/左上垂直 右上水平/右上垂直这么定义的。

而且,boder-radius 具有大值特性和等比例特性。大值特性指的是当定义的数值大于元素所能渲染的数值的时候,元素只会渲染所能够渲染的数值。而等比例特性是指各个角都按照所定义的水平/垂直比例。

了解了这些,我们就可以基于这个属性绘制多种图片了。

注意,当在 border-radius 中使用百分比的时候,如:

<style>
    width: 50px;
    height: 100px;
    border-radius: 50% / 100% 100% 0 0;    // 这个时候水平的radius为25px,垂直的radius为100px,这就相当于水平:垂直为1:4;

    那么就可以思考一下
    border-radius: 50px / 100% 100% 0 0;
    border-radius: 100px / 100% 100% 0 0;
    border-radius: 100px / 25% 25% 0 0;
    等这些属性的不同emmmm我思考了这些思考了好久总算是比较深入的理解了

    诀窍是最好将百分比换算成px然后再根据比例和宽高算出宽和高哪个是较小值接着就可以清楚绘制出的图是什么样子的了
</style>

菱形图片

菱形图片主要可以用 rotate 方法来实现,但是 css 揭秘中使用了clip-path方法,此前没有看过到,这里记录一下。

<style>
  .img {
    clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);

    or

    tranform: rotate(-45deg) scale(1.42);
  }
</style>

梯形

关于梯形的制作,主要有 2 中方法:

  1. 设置 width 和 height,然后设置 border 属性,让其中的一边显示,另外三条边的 border 不显示。具体的角度控制可以通过设置临边的 border 的 width 来调节。
  2. 通过 rotateX 来实现,具体的方法可以参考我的这篇博客

切角效果

切角效果主要是通过 gradient 效果来实现,设置好各个渐变的位置,大小和颜色,镂空的地方颜色设置为 transparent。

当然linear-gradient效果可通过clip-path实现,只不过后者的兼容性目前还不是很好(clip-path 目前只在 firefox54 版本以上才可以使用)。

radial-gradientlinear-gradient不同,他是径向渐变,所以可以用来制作与圆相关的效果,比如如下。

<style>
    .card {
        width: 200px;
        height: 120px;
        background-image: radial-gradient(circle at 100px -8px, transparent 20px, #b4a078 21px);
    }
</style>
You can write on it!

饼图及其动画

使用普通的css
<style>
    #pie-chart-css {
      width: 300px;
      height: 300px;
      margin: 200px auto;
      position: relative;
      border-radius: 50%;
      background: yellowgreen;
      background-image: linear-gradient(to right, transparent 50%, #655 0);
    }

    #pie-chart-css::before {
      background-color: inherit;
      content: '';
      display: block;
      margin-left: 50%;
      height: 100%;
      border-radius: 0 100% 100% 0/ 50%;
      transform-origin: left;
      animation: spin 5s linear infinite,
      bg 10s step-end infinite;
    }

    @keyframes spin {
      to {
        transform: rotate(180deg);
      }
    }

    @keyframes bg {
      50% {
        background: #655;
      }
    }
</style>

这里要好好理解一下 step-end 的含义:

  1. step-start 在变化过程中,都是以下一帧的显示效果来填充间隔动画
  2. step-end 与上面相反,都是以上一帧的显示效果来填充间隔动画

所以在这里,0%~50%都是伪元素的背景都是yellowgreen,但是 50%~100%开始才变成#655,step-start 就刚好相反。

使用svg的stroke-dasharray
<style>
    #pie-chart-svg {
      display: block;
      width: 300px;
      height: 300px;
      margin: 200px auto;
      background: #E8E2D6;
      border-radius: 50%;
      transform: rotate(-90deg);
    }

    #pie-chart-circle {
      fill: #E8E2D6;
      // svg中stroke-width是沿着边缘中心向内向外的宽度,所以实际上向内的宽度只有stroke-width的一半。所以这里是32不是16。
      stroke-width: 32px;
      // 这里需要好好理解stroke-dasharray的含义!
      stroke-dasharray: 0 100;
      stroke: #b4a078;
      animation: pie-chart 5s forwards infinite linear;
    }

    @keyframes pie-chart {
      to { stroke-dasharray: 100 100; }
    }
</style>

五边形左右底脚的圆弧

关于这个图片中左下和右下的两个角的弧度,具体的实现办法是添加 before 和 after 伪类,设计成平行四边形分布在两边,然后再应用 border-radius。

<style>
  .container {
    margin: 300px;
    display: inline-block;
    width: 200px;
    height: 240px;
    line-height: 20px;
    color: #fff;
    text-align: center;
    position: relative;
    cursor: pointer;
    font-size: 12px;
    overflow: hidden;
  }

  .container::before {
    transform: skewY(-30deg);
    transform-origin: left bottom;
    content: "";
    display: block;
    width: 100%;
    height: 100%;
    background-color: red;
    border-radius: 3px;
    position: absolute;
    top: 0;
    z-index: -1;
  }

  .container::after {
    transform: skewY(30deg);
    transform-origin: right bottom;
    content: "";
    display: block;
    width: 100%;
    height: 100%;
    background-color: red;
    border-radius: 3px;
    position: absolute;
    top: 0;
    z-index: -1;
  }
</style>

视觉效果

遮罩的实现

一般实现遮罩都是通过另一个背景 div 实现的,但是其实可以通过 box-shadow 实现。

<style>
  .shade {
    box-shadow: 0 0 0 20px rgba(0, 0, 0, .8);
  }
</style>
You can see me!

毛玻璃效果

<style>
  .blur-bg {
    margin: 0 auto;
    overflow: hidden;
    width: 480px;
    height: 320px;
  }
  .blur-bg, .blur-img::before {
    background: url(/public/tech/css-magic/blur-img.jpg);
  }

  .blur-img {
    position: relative;
    overflow: hidden;
    width: 300px;
    height: 200px;
    margin: 60px 90px;
    color: black;
    z-index: 1;
    text-align: center;
    line-height: 200px;
  }

  .blur-img::before {
    content: '';
    position: absolute;
    top: 0; right: 0; left: 0; bottom: 0;
    filter: blur(5px);
    margin: -30px;
    border-radius: 3px;
    z-index: -1;
    background-position: -60px -30px;
    background-repeat: no-repeat;
  }
</style>
You can see me!

折角效果

这里需要一点逆向思维

<style>
  @mixin folded-corner($background, $size, $angle:30deg) {
    position: relative;
    background: $background;
    background: linear-gradient($angle - 180deg, transparent $size, $background 0);
    border-radius: 0.5em;

    $x: $size / sin($angle);
    $y: $size / cos($angle);

    $::before {
      content: '';
      position: relative;
      top: 0; right: 0;
      background: linear-gradient(to left bottom, transparent 50%, rgba(0,0,0,.2) 0, rgba(0,0,0,.4)), 100% 0 no-repeat;
      width: $y; height: $x;
      transform: translateY($y - $x) rotate(2*$angle - 90deg);
      transform-origin: bottom right;
      border-bottom-left-radius: inherit;
      box-shadow: -.2em .2em .3em. -.1em rgba(0,0,0,.2);
    }
  }
</style>
You can see me!

字体排印

连字符断行

使用的 css3 的 hyphens 属性

插入换行

Unicode 字符中一个字符时专门代表换行的:0x000A。在 css 中,这个字符可以写作”\000A”,或简化成”\A”,他可以写在::before 和::after 的 content 中来达到换行的效果。

但是 html 代码中换行符会与相邻的其他空白符进行合并,如果我希望保留代码中的空白符和换行,可以使用white-space:pre属性。

文本的斑马条纹

使用的 css3 渐变函数,控制 background-size 和 line-height,使文本居中。

调整 tab 的宽度

使用 tab-size 属性。

连字

使用 font-variant-ligatrues 属性。

华丽的&符号

在自定义的 font-family 中设置 unicode-range 指定&字符。

    @font-face: {
      font-family: Ampersand;
      src: local(......),
           local(.....),
      unicode-range: U+26;
    }

    h1 {
      font-family: Ampersand, Helvetica;
    }

自定义下划线

可以使用渐变达到虚线下划线效果。

background: line-gradient(90deg, gray 66%, transparent 0) repeat-x;
background-size: 0.2em 2px;
background-position: 0 1em;

现实中的文字效果

使用 text-shadow 可以加粗文字。

使用 svg 的 stroke 可以产生空心字效果

.hollow-word {
  font: 500%/1 Rockwell, serif;
  background: deeppink;
  color: white;
}
.hollow-word text {
  fill: currentColor;
}
.hollow-word svg {
  overflow: visible;
}
.hollow-word use {
  stroke: black;
  stroke-width: 6;
  stroke-linejoin: round;
}
CSS

文字外的发光效果

.shine-word {
  background: #203;
  font-size: 3em;
  color: #ffc;
  text-shadow: 0 0 0.1em, 0 0 0.3em;
}
Glow

文字突起效果

.break-out-word {
  background: #58a;
  font-size: 3em;
  color: white;
  text-shadow: 0 1px hsl(0, 0%, 85%), 0 1px hsl(0, 0%, 80%),
    0 1px hsl(0, 0%, 75%), 0 1px hsl(0, 0%, 70%), 0 1px hsl(0, 0%, 65%), 0 5px
      10px black;
}
Glow

修改 text-shadow 中的颜色也可以修改阴影的颜色。

结构与布局

自适应内部元素

如果一个 div 需要自适应内部图片的宽度,并且文字的宽度不大于图片的宽度,可以使用max-width:min-content属性。

min-content这个属性将解析为这个容器内部最大的不可断行元素的卡 U 难度(即最宽的单词、图片或具有固定宽度的盒元素)。

精确控制表格列宽

之前控制表格列宽的时候都是内部添加 div 来实现的。现在可以通过table-layout:fixed来实现。

绝对底部

之前自己实现的绝对底部是在父元素上 padding 一定距离,然后设置 relative,footer 设置 absolute 置底展示。不过这还可以通过 cale()这个函数实现。

<style>
  .toBottom {
    min-height: calc(100% - 100px);
    // 不过他获取的100%是父元素的height,所以当页面的总height小于窗口height的时候会失效,这个时候就需要让父元素获取到整个窗口的height。
  }
</style>

过渡与动画

3D旋转倒影

使用纯css3的transform实现

<style>
.reflect-container {
  text-align: center;
  background-color: #eee;
  position: relative;
  height: 240px;
  padding: 20px 0;
}

/* The reflect-loader container */
.reflect-loader {
  position: absolute;
  top: 50%;
  left: 50%;
  
  width: 200px;
  height: 100px;
  
  margin-top: -100px;
  margin-left: -100px;
  
  perspective: 1000px;
  transform-style: preserv3d;
}

.reflect-loader--reflect {
  margin-top: 0;
}

.reflect-loader--reflect:after {
  content: '';
  position: absolute;
  top: 0;
  left: -25%;
  
  width: 150%;
  height: 110%;
  
  background: linear-gradient(0deg, rgba(238, 238, 238, 1), rgba(238, 238, 238, 1) 20%, rgba(238, 238, 238, 0.3));
}


/* The bar */
.reflect-bar {
  position: absolute;
  bottom: 0;
  left: 0;

  width: 20px;
  height: 100px;

  background-color: #1e3f57;
  
  transform: scaleY(0);
  transform-style: preserve3d;

  animation: reflect-bar 3s cubic-bezier(.81,.04,.4,.7) infinite;
}

.reflect-bar:nth-child(2) {
  left: 20px;
  
  background-color: #264a63;
  
  animation-delay: 50ms;
}

.reflect-bar:nth-child(3) {
  left: 40px;
  
  background-color: #2d566f;
  
  animation-delay: 100ms;
}

.reflect-bar:nth-child(4) {
  left: 60px;
  
  background-color: #35617a;
  
  animation-delay: 150ms;
}

.reflect-bar:nth-child(5) {
  left: 80px;
  
  background-color: #3d6d86;
  
  animation-delay: 200ms;
}

.reflect-bar:nth-child(6) {
  left: 100px;
  
  background-color: #447892;
  
  animation-delay: 250ms;
}

.reflect-bar:nth-child(7) {
  left: 120px;
  
  background-color: #4c849e;
  
  animation-delay: 300ms;
}

.reflect-bar:nth-child(8) {
  left: 140px;
  
  background-color: #548fa9;
  
  animation-delay: 350ms;
}

.reflect-bar:nth-child(9) {
  left: 160px;
  
  background-color: #5c9bb5;
  
  animation-delay: 400ms;
}

.reflect-bar:nth-child(10) {
  left: 180px;
  
  background-color: #63a6c1;
  
  animation-delay: 450ms;
}

.reflect-loader--reflect .reflect-bar {
  animation-name: reflect-bar-reflect;
}

@keyframes reflect-bar {
  0% {
    transform: rotateZ(-180deg) rotateX(-360deg);
  }
  75%,100% {
    transform: rotateZ(0) rotateX(0);
  }
}

@keyframes reflect-bar-reflect {
  0% {
    transform: rotateZ(180deg) rotateX(360deg);
  }
  75%,100% {
    transform: rotateZ(0) rotateX(0);
  }
}
</style>

走马灯效果

使用的是 svg 的 stroke-dasharray 和 stroke-dashoffset 的应用。

首先使用 stroke-dasharray 创建出间隔边框,然后再使用 stroke-dashoffset 推延起始位置。但是这个有个关键是,stroke-dashoffset 必须是 stroke-dasharray 数值的偶数倍,不然就会出现瞬移。

<style>
    #strokedrect-svg {
        margin: 30px auto;
        display: block;
        width: 600px;
        height: 200px;
    }

    #strokedrect {
      stroke: hsl(260, 50%, 90%);
      fill: white;
      stroke-width: 7;
      stroke-dasharray: 10;
      animation: marchingants 1s forwards infinite linear;
    }

    @keyframes marchingants {
      to { stroke-dashoffset: 20; }
    }
</style>

打字效果

依靠 animation 的 steps 实现。

<style>
  .typing-div {
    background: #fff;
    padding: 10px;
  }

  .typing {
    display: inline-block;
    width: 16ch;
    background: #fff;
    font: bold 200% Consolas, Monaco, monospace;   /*等宽字体*/
    overflow: hidden;
    white-space: nowrap;
    font-weight: 500;
    color: black;
    border-right: 1px solid transparent;
    // 注意这里的steps针对的是每2帧,并不是整个动画!
    animation: typing 8s steps(16) infinite, caret 0.5s steps(1) infinite;
  }

  @keyframes typing{
    from {
      width: 0;
    }
  }

  @keyframes caret {
    50% {
      border-color: currentColor;
    }
  }
</style>
You-can-see-me!

状态平滑的动画

如果有一张非常长的图片,但是我们只能提供一个较小的 div 来展示他,那我们可以给这个图片上添加动画,当我们鼠标放上去的,他自动从左往右展示。但是这会出现一个问题,当我们的鼠标从这张图片移开的时候,图片会瞬间回到最左端。要改善这个情况,我们可以让这个动画自动执行,只不过一开始是出于停止的状态,当我们的鼠标放上去的时候,动画开始执行,鼠标移开,动画停止。

@keyframes panoramic {
  to {
    background-position: 100% 0;
  }
}
.animation {
  width: 100px;
  height: 100px;
  background: url();
  background-size: auto 100%;
  animation: panoramic 10s linear infinite alternate;
  animation-play-state: paused;
}
.animation:hover,
.animation:focus {
  animation-play-state: running;
}

抖动效果

抖动效果主要还是依靠 animation 完成,只不过需要比较多的状态。

<style>
  .shake-div {
    background: #b4a078;
    margin: 30px auto;
    color: white;
    margin: auto;
    width: 180px;
    padding: .3em 1em .5em;
    border-radius: 3px;
    box-shadow: 0 0 .5em #b4a078;
    animation: shake-animation 1s ease infinite;
  }

  @keyframes shake-baidu {
    from    { transform: rotate(0deg); }
    4%      { transform: rotate(5deg); }
    12.5%   { transform: rotate(-5deg); }
    21%     { transform: rotate(5deg); }
    29%     { transform: rotate(-5deg); }
    37.5%   { transform: rotate(5deg); }
    46%     { transform: rotate(-5deg); }
    50%,to  { transform: rotate(0deg); }
  }
</style>
You can see me!

沿环形路径平移的动画

这是作者给的代码,并不是最终版,可以优化。

emm,这个特效的实现我真的学到了很多,虽然超级绕脑子,而且现在我再记录这些的东西的时候,我脑子还是一堆浆糊,不过我还是先写下来,以后慢慢消化。

首先最重要的一个知识点是,transform-origin只是一个语法糖,每个transform-origin都是可以被两个translate()模拟出来

代码一
transform: rotate(30deg);
transform-origin: 300px 300px;

代码二
transform:  translate(300px, 300px);
            rotate(30deg);
            translate(-300px, -300px);
transform-origin: 0 0;

这两段代码渲染的结果是一样的但是注意在代码二中是明确设置了transform-origin的

如果你理解了上面那一句话,再来看下面的内容。

虽然可以通过两个 translate()模拟出 transform-origin 的效果,但是在没有设置 transform-origin 的情况下,他的 transform-origin 还是在中心,所以在作者给出的代码中,他是没有设置 transform-origin,所以其实他所围绕旋转的点其实并不是这个圆的圆心,而是这个圆的圆心再往右 50%,往下 50%的位置。
所以如果没有后面对圆做 translate(50%, 50%)等相关处理的话(可以形象的理解成补足由于旋转点在中心的问题),这个结果会和现在的表现的不一样。这是这里最最最搞脑子的地方!!!!

为了简单的理解,我们可以先想想作者给出的代码中我们可以怎么样优化。

相信不少人可以想到,既然 transform-origin 默认为中心,那么如果我直接将圆移动到大圆的正中心呢?

那么我就不需要一开始操作的translateY(150px), 而且也不需要后面translateY(50%)和translateY(-50%)
所以最终代码就是:

from {
  transform: rotate(0turn) translateY(-125px) rotate(1turn);
}
to {
  transform: rotate(1turn) translateY(-125px) rotate(0turn);
}

这是为什么呢?

我们可以想,一开始圆就在中心,然后顺时针旋转,旋转完移动圆的边缘,然后逆时针旋转相同的角度,这不就是我们要的效果了吗。

那么原来的代码怎么理解呢?首先圆在圆点正上方的顶点,然后往下移动 150px,刚好上边的中心点在圆心的地方,然后顺时针旋转,注意注意这里的旋转点是圆心正下方 25px 处,旋转完了上移 150px 回到原来的地方,然后往下移动 25px,逆时针旋转,再上移 25px。这里后面的上移和下移是必须的,如果没有的话,那么这个动画所围绕的点其实是圆心下方 25px 处,但是经过后面的下移逆时针旋转上移后,他其实是抵消了这 25px 的顺时针旋转所带来的位移。
或者这么理解,点 a 按照点 b 顺时针旋转一定角度,然后再按照点 c 逆时针旋转,最后的旋转的点其实就是在点 a 下面(点 b-点 c 的 y 轴距离,即 150px-25px = 125px)。

所以这里原书中代码有错误!!(不信你们可以是看看)

说句实话,虽然我了解这些代码的意思,但是我需要重头梳理,如果直接让我看最后的代码,我还是会迷糊一段时间,所以现在我还是不能很好的阐述,以后理解的更透彻了再来阐述。

结尾

参考资料

  • css 揭秘
blog comments powered by Disqus
目 录