CSS: 潜藏着的BFC

2017/12/07 · CSS · 1
评论

原来的文章出处:
杳杳飞花_Hwj   

在写样式时,往往是增加了贰个体制,又或然是修改了某些属性,就达到了大家的料想。
而BFC就潜藏在当中,当你改改样式时,一相当大心就会接触它而毫无察觉,因而未曾发觉到BFC的美妙之处。

CSS本领:逐帧动画抖动实施方案

2017/08/16 · CSS ·
动画

原稿出处:
坑坑洼洼实验室   

笔者所在的前端团队重要从事活动端的H5页面开辟,而团队使用的适配方案是:
viewport units + rem。具体能够参见凹凸实验室的篇章 –
行使视口单位贯彻适配布局

小编近日(2017.08.12)接触到的运动端适配方案中,「利用视口单位落实适配布局」是最佳的方案。可是使用
rem 作为单位会蒙受以下八个难点:

  • 微观尺寸(20px左右)定位不准
  • 逐帧动画轻易有振憾

率先个难题的平日出现在 icon 绘制进程,能够选择图片或者
svg-icon 消除这几个主题材料,笔者猛烈提议使用
svg-icon,具体理由能够远瞻:「拥抱Web设计新取向:SVG
Sprites实行应用」。

其次个困难作者比释尊深入分析抖动的缘故和查找解决方案。

何以只用 CSS 实现可以的加载

2017/08/15 · CSS · 2
评论 ·
加载

原稿出处: Julien
Benchetrit   译文出处:枫上雾棋   

图片 1

一、什么是BFC(Block Formatting Context)

写CSS样式时,对三个成分设置css,大家第一要明了那一个成分是块级元素依然行内成分,而BFC正是用来格式化块级盒子的。

Formatting
Context:指页面中一个渲染区域,何况存有一套渲染准绳,它调整了其子元素怎么样定位,以及与别的因素的相互关系和作用。

BFC定义:块级格式化上下文,它是指二个单独的块级渲染区域,唯有Block-level
Box参预,该区域拥有一套渲染法则来约束块级盒子的布局,且与区域外界非亲非故。

三个震荡的例证

做贰个8帧的逐帧动画,每帧的尺码为:360×540。

JavaScript

.steps_anim { position: absolute; width: 9rem; height: 13.5rem;
background: url(//misc.aotu.io/leeenx/sprite/m.png) 0 0 no-repeat;
background-size: 45rem 13.5rem; top: 50%; left: 50%; margin: -5.625rem 0
0 -5.625rem; animation: step 1.2s steps(5) infinite; } @keyframes step {
100% { background-position: -45rem; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.steps_anim {
  position: absolute;
  width: 9rem;
  height: 13.5rem;
  background: url(//misc.aotu.io/leeenx/sprite/m.png) 0 0 no-repeat;
  background-size: 45rem 13.5rem;
  top: 50%;
  left: 50%;
  margin: -5.625rem 0 0 -5.625rem;
  animation: step 1.2s steps(5) infinite;
}
@keyframes step {
  100% {
    background-position: -45rem;
  }
}

观测在主流(手提式有线电话机)分辨率下的播放景况:

iPhone 6
(375×667)
iPhone 6+
(414×736)
iPhone 5
(320×568)
Android
(360×640)

各样分辨率下,能够见见除了 ip6 另外的三种分辨率都产生了振撼。ip6
不抖动的原因是适配方案是基本于 ip6 的分辨率订制的。)

干什么要做加载

只想说, 本文最重视的是对 CSS, 伪元素, keyframe的享受,
以及读者对这一个东西的真正掌握,
我并不是怂恿大家在种种页面包车型客车先头都去加三个炫酷的加载

二、BFC的生成

大家提起BFC是一块渲染区域,那么那块渲染区域究竟在哪儿吧,具体大小又是有个别?那一个都以由生成BFC的要平昔决定的。

满意下列CSS注明之一的要素便会生成BFC:

剖判抖动

图像由终端(荧屏)显示,而终端则是二个个光点(物理像素)组成的矩阵,换句话说图片也一组光点矩阵。为了有助于描述,小编倘若终端上的三个光点代表css中的1px。

以下是一张 9px * 3px 的sprite:

图片 2

每帧的尺码为 3px * 3px,逐帧的取位进度如下:
图片 3

把 sprite 的 background-size 的拉长率取四分之二,那么极端会怎么管理?
9 / 2 = 4.5
终点的光点都以以自然数的款式出现的,这里需求做取整管理。取整平时是三种艺术:round/ceil/floor。假设是
round ,那么 background-size: 5px,sprite 会是以下三种的二个:

情况一 情况二 情况三

理论上,5 / 3 = 1.666...。但事实上光点取整后,八个帧的宽度都不容许卓越
1.666...,而是有二个帧的肥瘦降级为 1px(亏),别的四个上涨的幅度晋级为
2px(盈),笔者把那几个地方叫做「盈利和亏蚀互补」。

再看一下盈利和亏蚀互补后,逐帧的取位进程:

情况一 情况二 情况三

能够见见由于盈利和亏蚀互补导致了多少个帧的增长幅度不均等,亏的那一帧在动画中的表示正是抖动

作者总结抖动的原由是:sprite在尺寸缩放后,帧与帧之间的财务成果互补现象导致动画抖动

附注:1px 由多少个光点表示是由以极端的 dpr 决定

本身是怎么做的

今是昨非的页面, 对加载的设计也就可能分歧. 本文设计的加载符合大大多页面.

而且, 本文就算读者已经非常熟练伪元素, CSS 动画属性keyframe,
假设读者想珍视提议, 上面两篇小说可做参照他事他说加以考察

  • 学会运用 CSS 中的 :after 和 :before
  • keyframe 动画直通车

1、根元素或别的满含它的要素

减轻方案

「盈利和赔本互补」也足以说是「盈利和蚀本不同」,要是尺寸在缩放后「盈亏一致」那么抖动现象能够消除。

初进入门

在初叶联合创设它前, 大家先看看它最后的效果

图片 4

正如您所观看的, 大家将经历 4 个步骤

  • 边框三个接一个地出现
  • 红/橙/浅绿灰方块向里滑入
  • 正方向外划出
  • 边框消失

咱俩只必要 animation-direction: alternate 来完成步骤 1 和 2, 步骤 3 和
步骤 4 大家得以采用 reverse, 其余, 大家得以应用
animation-iteration-count: infinite 重复动画

率先, 我们先书写好大旨的 HTML 结构

JavaScript

<!doctype html> <html> <head> <!– <link
rel=”preload”> for CSS, JS, and font files –> <style
type=”text/css”> /* * All the CSS for the loader * Minified and
vendor prefixed */ </style> </head> <body> <div
class=”loader”> <!– HTML for the loader –> </div>
<header /> <main /> <footer /> <!– Tags for CSS
and JS files –> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!doctype html>
<html>
  <head>
    <!– <link rel="preload"> for CSS, JS, and font files  –>
    <style type="text/css">
      /*
       *  All the CSS for the loader
       *  Minified and vendor prefixed
       */
    </style>
  </head>
  <body>
    <div class="loader">
      <!– HTML for the loader –>
    </div>
    <header />
    <main />
    <footer />
    <!– Tags for CSS and JS files –>
  </body>
</html>

2、float的值不为none;

杀鸡取卵构想一

作者遵照「盈利和亏本一致」设计了「化解构想一」:

图片 5

基于上海教室,其实很轻松就联想到二个大致的方案:不用七喜图(即一帧对应一张图纸)
其一方案确实是能够消除抖难题,但是笔者并不引入应用它,因为它有三个负面包车型大巴事物:

  • KB变大与乞求数扩大
  • 多余的 animation 代码

这些方案很简短,这里就不赘述了。

构建 logo 本身

图片 6

一同首大家先实现 logo 自身, 并非最后版本的功用

父级成分 logo, 差异颜色的方框都以它的子成分

JavaScript

<div class=”logo”> <div class=”white”></div> <div
class=”orange”></div> <div class=”red”></div>
</div>

1
2
3
4
5
<div class="logo">
  <div class="white"></div>
  <div class="orange"></div>
  <div class="red"></div>
</div>

我们用 less 来实现

JavaScript

.logo { position: relative; width: 100px; height: 100px; border: 4px
solid black; box-sizing: border-box; background-color: white; & > div
{ position: absolute; } .red { top: 0; bottom: 0; left: 0; width: 27%;
border-right: 4px solid black; background-color: #EA5664; } /* Similar
code for div.orange and div.white */ }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.logo {
  position: relative;
  width: 100px;
  height: 100px;
  border: 4px solid black;
  box-sizing: border-box;
  background-color: white;
 
  & > div {
    position: absolute;
  }
 
  .red {
    top: 0;
    bottom: 0;
    left: 0;
    width: 27%;
    border-right: 4px solid black;
    background-color: #EA5664;
  }
  /* Similar code for div.orange and div.white */
}

logo 的效劳图如下

图片 7

3、overflow的值不为visible;

化解构想二

把逐帧取位与图像缩放拆分成两个单身的长河,就是笔者的「化解构想二」:
图片 8

贯彻「构想二」,小编首先想到的是选择
transform: scale(),于是整理了一个兑现方案A:

.steps_anim { position: absolute; width: 360px; height: 540px;
background: url(//misc.aotu.io/leeenx/sprite/m.png) 0 0 no-repeat;
background-size: 1800px 540px; top: 50%; left: 50%; transform-origin:
left top; margin: -5.625rem 0 0 -5.625rem; transform: scale(.5);
animation: step 1.2s steps(5) infinite; } @keyframes step { 100% {
background-position: -1800px; } } /* 写断点 */ @media screen and
(width: 320px) { .steps_anim { transform: scale(0.4266666667); } }
@media screen and (width: 360px) { .steps_anim { transform:
scale(0.48); } } @media screen and (width: 414px) { .steps_anim {
transform: scale(0.552); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
.steps_anim {
  position: absolute;
  width: 360px;
  height: 540px;
  background: url(//misc.aotu.io/leeenx/sprite/m.png) 0 0 no-repeat;
  background-size: 1800px 540px;
  top: 50%;
  left: 50%;
  transform-origin: left top;
  margin: -5.625rem 0 0 -5.625rem;
  transform: scale(.5);
  animation: step 1.2s steps(5) infinite;
}
@keyframes step {
  100% {
    background-position: -1800px;
  }
}
/* 写断点 */
@media screen and (width: 320px) {
.steps_anim {
transform: scale(0.4266666667);
}
}
@media screen and (width: 360px) {
.steps_anim {
transform: scale(0.48);
}
}
@media screen and (width: 414px) {
.steps_anim {
transform: scale(0.552);
}
}

本条完结方案A存在显著的弱点:scale
的值须求写过多断点代码
。于是小编结全一段 js 代码来改正这一个达成方案B:

css:

.steps_anim { position: absolute; width: 360px; height: 540px;
background: url(“//misc.aotu.io/leeenx/sprite/m.png”) 0 0 no-repeat;
background-size: 1800 540px; top: 50%; left: 50%; transform-origin: left
top; margin: -5.625rem 0 0 -5.625rem; animation: step 1.2s steps(5)
infinite; } @keyframes step { 100% { background-position: -1800px; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.steps_anim {
  position: absolute;
  width: 360px;
  height: 540px;
  background: url("//misc.aotu.io/leeenx/sprite/m.png") 0 0 no-repeat;
  background-size: 1800 540px;
  top: 50%;
  left: 50%;
  transform-origin: left top;
  margin: -5.625rem 0 0 -5.625rem;
  animation: step 1.2s steps(5) infinite;
}
@keyframes step {
  100% {
    background-position: -1800px;
  }
}

javascript:

// 以下代码放到<head></head>中// <![CDATA[
document.write(” .steps_anim {scale(.5); } “); function doResize() {
scaleStyleSheet.innerHTML = “.steps_anim {-webkit-transform: scale(” +
(document.documentElement.clientWidth / 750) + “)}”; } window.onresize =
doResize; doResize(); // ]]>

1
2
3
4
5
6
7
8
9
10
11
12
13
// 以下代码放到<head></head>中// <![CDATA[
document.write("
 
.steps_anim {scale(.5); }
 
 
");
function doResize() {
  scaleStyleSheet.innerHTML = ".steps_anim {-webkit-transform: scale(" + (document.documentElement.clientWidth / 750) + ")}";
}
window.onresize = doResize;
doResize();
// ]]>

通过校正后的方案 CSS
的断点没了,感觉是不容争辩了,不过作者以为那么些方案不是个纯粹的营造方案。

大家驾驭<img>
是能够依照钦定的尺码自适应缩放尺寸的,假若逐帧动画也能与 <img>
自适应缩放,那就可以从纯创设角度达成「构想二」。

SVG正好能够化解难题!!!SVG 的显现与
<img>“类似同一时候可以做动画。以下是笔者的落实方案C。

html:

JavaScript

<svg viewBox=”0, 0, 360, 540″ class=”steps_anim”> <image
xlink:href=”//misc.aotu.io/leeenx/sprite/m.png” width=”1800″
height=”540″ /> </svg>

1
2
3
<svg viewBox="0, 0, 360, 540" class="steps_anim">
  <image xlink:href="//misc.aotu.io/leeenx/sprite/m.png" width="1800" height="540" />
</svg>

css:

JavaScript

.steps_anim { position: absolute; width: 9rem; height: 13.5rem; top:
50%; left: 50%; margin: -5.625rem 0 0 -5.625rem; image { animation: step
1.2s steps(5) infinite; } } @keyframes step { 100% { transform:
translate3d(-1800px, 0, 0); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.steps_anim {
  position: absolute;
  width: 9rem;
  height: 13.5rem;
  top: 50%;
  left: 50%;
  margin: -5.625rem 0 0 -5.625rem;
  image {
   animation: step 1.2s steps(5) infinite;
  }
}
@keyframes step {
  100% {
    transform: translate3d(-1800px, 0, 0);
  }
}

边框动画

接下去, 我们将跻身棘手(有趣)的部分

CSS 不允许大家向来对 div.logo 的边框实行安装达到大家想要的成效,
所以大家必需去除原来的边框, 选用别的的点子来贯彻

作者们要把四个边框细分开来, 然后让它们有序地涌出, 所以,
大家能够采取覆盖任何 div 的五个透明的伪元素

废话少说, 就让大家最初吧, 大家先做出它最起头的样子. 大家让
div.logo :: before 绝对位于 div.logo
的左上角,代表方块的上边框和右手框
, 让 div.logo::after 相对定位 div.logo 的右下角,
代表方块的底下框和右臂框

现行反革命, less 代码产生了这么

JavaScript

.logo { position: relative; width: 100px; height: 100px; box-sizing:
border-box; background-color: white; &::before, &::after { content: ”;
position: absolute; width: 100%; height: 100%; box-sizing: border-box;
border: 4px solid transparent; } &::before { top: 0; left: 0;
border-top-color: black; border-right-color: black; } &::after { bottom:
0; right: 0; border-bottom-color: red; // Red for demo purposes only
border-left-color: red; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
.logo {
  position: relative;
  width: 100px;
  height: 100px;
  box-sizing: border-box;
  background-color: white;
 
  &::before,
  &::after {
    content: ”;
    position: absolute;
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    border: 4px solid transparent;
  }
 
  &::before {
    top: 0;
    left: 0;
    border-top-color: black;
    border-right-color: black;
  }
 
  &::after {
    bottom: 0;
    right: 0;
    border-bottom-color: red; // Red for demo purposes only
    border-left-color: red;
  }
}

现在效果长这样

图片 9

接下去, 大家就用 keyframediv.logo::before 的第二个卡通

我们将 widthheight 早先都为 0, 然后用 keyframewidth

height 调整到 100%

随着大家在对应的日子把边框从透明变为黑色,
大家想要的最开首的效劳就出来了

该代码显示了伪元素的初始动画

div.logo { &::before, &::after { /* … */ animation-timing-function:
linear; } &::before { /* … */ animation: border-before 1.5s
infinite; animation-direction: alternate; } } @keyframes border-before {
0% { width: 0; height: 0; border-right-color: transparent; } 24.99% {
border-right-color: transparent; } 25% { height: 0; width: 100%;
border-right-color: black; } 50%, 100% { width: 100%; height: 100%; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
div.logo {
  &::before,
  &::after {
    /* … */
    animation-timing-function: linear;
  }
  &::before {
    /* … */
    animation: border-before 1.5s infinite;
    animation-direction: alternate;
  }
}
@keyframes border-before {
  0% {
    width: 0;
    height: 0;
    border-right-color: transparent;
  }
  24.99% {
    border-right-color: transparent;
  }
  25% {
    height: 0;
    width: 100%;
    border-right-color: black;
  }
  50%,
  100% {
    width: 100%;
    height: 100%;
  }
}

我们对 div.logo::after 重复一样的操作, 不要忘了调度时间和反转 width
height. 将来, 大家就有了最外层边框的漫天动画.

发表评论

电子邮件地址不会被公开。 必填项已用*标注