xml地图|网站地图|网站标签 [设为首页] [加入收藏]
秋月何时了,写一个网页进度loading
分类:web前端

CSS魔法堂:”那不是bug,是你不懂我!” by inline-block

2016/05/10 · CSS · inline-block

本文作者: 伯乐在线 - ^-^肥仔John 。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者。

写一个网页进度loading

2017/02/26 · JavaScript · 2 评论 · Loading

原文出处: jack_lo   

loading随处可见,比如一个app经常会有下拉刷新,上拉加载的功能,在刷新和加载的过程中为了让用户感知到 load 的过程,我们会使用一些过渡动画来表达。最常见的比如“转圈圈”,“省略号”等等。

网页loading有很多用处,比如页面的加载进度,数据的加载过程等等,数据的加载loading很好做,只需要在加载数据之前(before ajax)显示loading效果,在数据返回之后(ajax completed)结束loading效果,就可以了。

但是页面的加载进度,需要一点技巧。

页面加载进度一直以来都是一个常见而又晦涩的需求,常见是因为它在某些“重”网页(特别是网页游戏)的应用特别重要;晦涩是因为web的特性,各种零散资源决定它很难是“真实”的进度,只能是一种“假”的进度,至少在逻辑代码加载完成之前,我们都不能统计到进度,而逻辑代码自身的进度也无法统计。另外,我们不可能监控到所有资源的加载情况。

所以页面的加载进度都是“假”的,它存在的目的是为了提高用户体验,使用户不至于在打开页面之后长时间面对一片空白,导致用户流失。

既然是“假”的,我们就要做到“仿真”才有用。仿真是有意义的,事实上用户并不在乎某一刻你是不是真的加载到了百分之几,他只关心你还要load多久。所以接下来我们就来实现一个页面加载进度loading。

首先准备一段loading的html:

XHTML

<!DOCTYPE html> <html> <head> <title>写一个网页进度loading</title> </head> <body> <div class="loading" id="loading"> <div class="progress" id="progress">0%</div> </div> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<head>
    <title>写一个网页进度loading</title>
</head>
<body>
  <div class="loading" id="loading">
    <div class="progress" id="progress">0%</div>
  </div>
</body>
</html>

来点样式装扮一下:

CSS

.loading { display: table; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: #fff; z-index: 5; } .loading .progress { display: table-cell; vertical-align: middle; text-align: center; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.loading {
  display: table;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: #fff;
  z-index: 5;
}
 
.loading .progress {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}

我们先假设这个loading只需要在页面加载完成之后隐藏,中间不需要显示进度。那么很简单,我们第一时间想到的就是window.onload:

(以下内容为了方便演示,默认使用jQuery,语法有es6的箭头函数)

JavaScript

var $loading = $('#loading') var $progress = $('#progress') window.onload = () => { $loading.hide() }

1
2
3
4
5
6
var $loading = $('#loading')
var $progress = $('#progress')
 
window.onload = () => {
  $loading.hide()
}

ok,这样基本的loading流程就有了,我们增加一个进度的效果,每隔100ms就自增1,一直到100%为止,而另一方面window loaded的时候,我们把loading给隐藏。

我们来补充一下进度:

JavaScript

var $loading = $('#loading') var $progress = $('#progress') var prg = 0 // 初始化进度 var timer = window.setInterval(() => { // 设置定时器 if (prg >= 100) { // 到达终点,关闭定时器 window.clearInterval(timer) prg = 100 } else { // 未到终点,进度自增 prg++ } $progress.html(prg + '%') console.log(prg) }, 100) window.onload = () => { $loading.hide() }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var $loading = $('#loading')
var $progress = $('#progress')
var prg = 0  // 初始化进度
 
var timer = window.setInterval(() => {  // 设置定时器
  if (prg >= 100) {  // 到达终点,关闭定时器
    window.clearInterval(timer)
    prg = 100
  } else {  // 未到终点,进度自增
    prg++
  }
 
  $progress.html(prg + '%')
  console.log(prg)
}, 100)
 
window.onload = () => {
  $loading.hide()
}

效果不错,但是有个问题,万一window loaded太慢了,导致进度显示load到100%了,loading还没有隐藏,那就打脸了。所以,我们需要让loading在window loaded的时候才到达终点,在这之前,loading可以保持一个等待的状态,比如在80%的时候,先停一停,然后在loaded的时候快速将进度推至100%。这个做法是目前绝大部份进度条的做法。

JavaScript

var $loading = $('#loading') var $progress = $('#progress') var prg = 0 var timer = window.setInterval(() => { if (prg >= 80) { // 到达第一阶段80%,关闭定时器,保持等待 window.clearInterval(timer) prg = 100 } else { prg++ } $progress.html(prg + '%') console.log(prg) }, 100) window.onload = () => { window.clearInterval(timer) window.setInterval(() => { if (prg >= 100) { // 到达终点,关闭定时器 window.clearInterval(timer) prg = 100 $loading.hide() } else { prg++ } $progress.html(prg + '%') console.log(prg) }, 10) // 时间间隔缩短 }

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
var $loading = $('#loading')
var $progress = $('#progress')
var prg = 0
 
var timer = window.setInterval(() => {
  if (prg >= 80) {  // 到达第一阶段80%,关闭定时器,保持等待
    window.clearInterval(timer)
    prg = 100
  } else {
    prg++
  }
 
  $progress.html(prg + '%')
  console.log(prg)
}, 100)
 
window.onload = () => {
  window.clearInterval(timer)
  window.setInterval(() => {
    if (prg >= 100) {  // 到达终点,关闭定时器
      window.clearInterval(timer)
      prg = 100
      $loading.hide()
    } else {
      prg++
    }
 
    $progress.html(prg + '%')
    console.log(prg)
  }, 10)  // 时间间隔缩短
}

ok,这差不多就是我们想要的功能了,我们来提炼一下代码,把重复的代码给封装一下:

JavaScript

var $loading = $('#loading') var $progress = $('#progress') var prg = 0 var timer = 0 progress(80, 100) window.onload = () => { progress(100, 10, () => { $loading.hide() }) } function progress (dist, delay, callback) { window.clearInterval(timer) timer = window.setInterval(() => { if (prg >= dist) { window.clearInterval(timer) prg = dist callback && callback() } else { prg++ } $progress.html(prg + '%') console.log(prg) }, delay) }

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
var $loading = $('#loading')
var $progress = $('#progress')
var prg = 0
 
var timer = 0
 
progress(80, 100)
 
window.onload = () => {
  progress(100, 10, () => {
    $loading.hide()
  })
}
 
function progress (dist, delay, callback) {
  window.clearInterval(timer)
  timer = window.setInterval(() => {
    if (prg >= dist) {
      window.clearInterval(timer)
      prg = dist
      callback && callback()
    } else {
      prg++
    }
 
    $progress.html(prg + '%')
    console.log(prg)
  }, delay)
}

我们得到了一个progress函数,这个函数就是我们主要的功能模块,通过传入一个目标值、一个时间间隔,就可以模拟进度的演化过程。

目前来看,这个进度还是有些问题的:

  1. 进度太平均,相同的时间间隔,相同的增量,不符合网络环境的特点;
  2. window.onload太快,我们还来不及看清100%,loading就已经不见了;
  3. 每次第一阶段都是在80%就暂停了,露馅儿了;

第一个点,我们要让时间间隔随机,增量也随机;第二个点很简单,我们延迟一下就好了;第三点也需要我们随机产生一个初始值。

增量随机很好办,如何让时间间隔随机?setInterval是无法动态设置delay的,那么我们就要把它改造一下,使用setTimeout来实现。(setInterval跟setTimeout的用法和区别就不细说了吧?)

JavaScript

var $loading = $('#loading') var $progress = $('#progress') var prg = 0 var timer = 0 progress([80, 90], [1, 3], 100) // 使用数组来表示随机数的区间 window.onload = () => { progress(100, [1, 5], 10, () => { window.setTimeout(() => { // 延迟了一秒再隐藏loading $loading.hide() }, 1000) }) } function progress (dist, speed, delay, callback) { var _dist = random(dist) var _delay = random(delay) var _speed = random(speed) window.clearTimeout(timer) timer = window.setTimeout(() => { if (prg + _speed >= _dist) { window.clearTimeout(timer) prg = _dist callback && callback() } else { prg += _speed progress (_dist, speed, delay, callback) } $progress.html(parseInt(prg) + '%') // 留意,由于已经不是自增1,所以这里要取整 console.log(prg) }, _delay) } function random (n) { if (typeof n === 'object') { var times = n[1] - n[0] var offset = n[0] return Math.random() * times + offset } else { return n } }

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
35
36
37
38
39
40
41
42
43
44
45
var $loading = $('#loading')
var $progress = $('#progress')
var prg = 0
 
var timer = 0
 
progress([80, 90], [1, 3], 100)  // 使用数组来表示随机数的区间
 
window.onload = () => {
  progress(100, [1, 5], 10, () => {
    window.setTimeout(() => {  // 延迟了一秒再隐藏loading
      $loading.hide()
    }, 1000)
  })
}
 
function progress (dist, speed, delay, callback) {
  var _dist = random(dist)
  var _delay = random(delay)
  var _speed = random(speed)
  window.clearTimeout(timer)
  timer = window.setTimeout(() => {
    if (prg + _speed >= _dist) {
      window.clearTimeout(timer)
      prg = _dist
      callback && callback()
    } else {
      prg += _speed
      progress (_dist, speed, delay, callback)
    }
 
    $progress.html(parseInt(prg) + '%')  // 留意,由于已经不是自增1,所以这里要取整
    console.log(prg)
  }, _delay)
}
 
function random (n) {
  if (typeof n === 'object') {
    var times = n[1] - n[0]
    var offset = n[0]
    return Math.random() * times + offset
  } else {
    return n
  }
}

至此,我们差不多完成了需求。

but,还有一个比较隐蔽的问题,我们现在使用window.onload,发现从进入页面,到window.onload这中间相隔时间十分短,我们基本是感受不到第一阶段进度(80%)的,这是没有问题的——我们在意的是,如果页面的加载资源数量很多,体积很大的时候,从进入页面,到window.onload就不是这么快速了,这中间可能会很漫长(5~20秒不等),但事实上,我们只需要为 首屏资源 的加载争取时间就可以了,不需要等待所有资源就绪,而且更快地呈现页面也是提高用户体验的关键。

我们应该考虑页面loading停留过久的情况,我们需要为loading设置一个超时时间,超过这个时间,假设window.onload还没有完成,我们也要把进度推到100%,把loading结束掉。

JavaScript

var $loading = $('#loading') var $progress = $('#progress') var prg = 0 var timer = 0 progress([80, 90], [1, 3], 100) // 使用数组来表示随机数的区间 window.onload = () => { progress(100, [1, 5], 10, () => { window.setTimeout(() => { // 延迟了一秒再隐藏loading $loading.hide() }, 1000) }) } window.setTimeout(() => { // 设置5秒的超时时间 progress(100, [1, 5], 10, () => { window.setTimeout(() => { // 延迟了一秒再隐藏loading $loading.hide() }, 1000) }) }, 5000) function progress (dist, speed, delay, callback) { var _dist = random(dist) var _delay = random(delay) var _speed = random(speed) window.clearTimeout(timer) timer = window.setTimeout(() => { if (prg

  • _speed >= _dist) { window.clearTimeout(timer) prg = _dist callback && callback() } else { prg += _speed progress (_dist, speed, delay, callback) } $progress.html(parseInt(prg) + '%') // 留意,由于已经不是自增1,所以这里要取整 console.log(prg) }, _delay) } function random (n) { if (typeof n === 'object') { var times = n[1] - n[0] var offset = n[0] return Math.random() * times + offset } else { return n } }
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
var $loading = $('#loading')
var $progress = $('#progress')
var prg = 0
 
var timer = 0
 
progress([80, 90], [1, 3], 100)  // 使用数组来表示随机数的区间
 
window.onload = () => {
  progress(100, [1, 5], 10, () => {
    window.setTimeout(() => {  // 延迟了一秒再隐藏loading
      $loading.hide()
    }, 1000)
  })
}
 
window.setTimeout(() => {  // 设置5秒的超时时间
  progress(100, [1, 5], 10, () => {
    window.setTimeout(() => {  // 延迟了一秒再隐藏loading
      $loading.hide()
    }, 1000)
  })
}, 5000)
 
function progress (dist, speed, delay, callback) {
  var _dist = random(dist)
  var _delay = random(delay)
  var _speed = random(speed)
  window.clearTimeout(timer)
  timer = window.setTimeout(() => {
    if (prg + _speed >= _dist) {
      window.clearTimeout(timer)
      prg = _dist
      callback && callback()
    } else {
      prg += _speed
      progress (_dist, speed, delay, callback)
    }
 
    $progress.html(parseInt(prg) + '%')  // 留意,由于已经不是自增1,所以这里要取整
    console.log(prg)
  }, _delay)
}
 
function random (n) {
  if (typeof n === 'object') {
    var times = n[1] - n[0]
    var offset = n[0]
    return Math.random() * times + offset
  } else {
    return n
  }
}

我们直接设置了一个定时器,5s的时间来作为超时时间。这样做是可以的。

but,还是有问题,这个定时器是在js加载完毕之后才开始生效的,也就是说,我们忽略了js加载完毕之前的时间,这误差可大可小,我们设置的5s,实际用户可能等待了8s,这是有问题的。我们做用户体验,需要从实际情况去考虑,所以这个开始时间还需要再提前一些,我们在head里来记录这个开始时间,然后在js当中去做对比,如果时间差大于超时时间,那我们就可以直接执行最后的完成步骤,如果小于超时时间,则等待 剩余的时间 过后,再完成进度。

先在head里埋点,记录用户进入页面的时间loadingStartTime

XHTML

<!DOCTYPE html> <html> <head> <title>写一个网页进度loading</title> <script> window.loadingStartTime = new Date() </script> <script src="index.js"></script> </head> <body> <div class="loading" id="loading"> <div class="progress" id="progress">0%</div> </div> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html>
<head>
  <title>写一个网页进度loading</title>
  <script>
    window.loadingStartTime = new Date()
  </script>
  <script src="index.js"></script>
</head>
<body>
  <div class="loading" id="loading">
    <div class="progress" id="progress">0%</div>
  </div>
</body>
</html>

然后,我们对比 当前的时间 ,看是否超时:(为了方便复用代码,我把完成的部分封装成函数complete)

JavaScript

var $loading = $('#loading') var $progress = $('#progress') var prg = 0 var timer = 0 var now = new Date() // 记录当前时间 var timeout = 5000 // 超时时间 progress([80, 90], [1, 3], 100) window.onload = () => { complete() } if (now - loadingStartTime > timeout) { // 超时 complete() } else { window.setTimeout(() => { // 未超时,则等待剩余时间 complete() }, timeout - (now - loadingStartTime)) } function complete () { // 封装完成进度功能 progress(100, [1, 5], 10, () => { window.setTimeout(() => { $loading.hide() }, 1000) }) } function progress (dist, speed, delay, callback) { var _dist = random(dist) var _delay = random(delay) var _speed = random(speed) window.clearTimeout(timer) timer = window.setTimeout(() => { if (prg

  • _speed >= _dist) { window.clearTimeout(timer) prg = _dist callback && callback() } else { prg += _speed progress (_dist, speed, delay, callback) } $progress.html(parseInt(prg) + '%') console.log(prg) }, _delay) } function random (n) { if (typeof n === 'object') { var times = n[1] - n[0] var offset = n[0] return Math.random() * times + offset } else { return n } }
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
var $loading = $('#loading')
var $progress = $('#progress')
var prg = 0
 
var timer = 0
var now = new Date()  // 记录当前时间
var timeout = 5000  // 超时时间
 
progress([80, 90], [1, 3], 100)
 
window.onload = () => {
  complete()
}
 
if (now - loadingStartTime > timeout) {  // 超时
  complete()
} else {
  window.setTimeout(() => {  // 未超时,则等待剩余时间
    complete()
  }, timeout - (now - loadingStartTime))
}
 
function complete () {  // 封装完成进度功能
  progress(100, [1, 5], 10, () => {
    window.setTimeout(() => {
      $loading.hide()
    }, 1000)
  })
}
 
function progress (dist, speed, delay, callback) {
  var _dist = random(dist)
  var _delay = random(delay)
  var _speed = random(speed)
  window.clearTimeout(timer)
  timer = window.setTimeout(() => {
    if (prg + _speed >= _dist) {
      window.clearTimeout(timer)
      prg = _dist
      callback && callback()
    } else {
      prg += _speed
      progress (_dist, speed, delay, callback)
    }
 
    $progress.html(parseInt(prg) + '%')
    console.log(prg)
  }, _delay)
}
 
function random (n) {
  if (typeof n === 'object') {
    var times = n[1] - n[0]
    var offset = n[0]
    return Math.random() * times + offset
  } else {
    return n
  }
}

至此,我们算是完整地实现了这一功能。

然而,事情还没有结束,少年你太天真。

如果目的是为了写一个纯粹障眼法的伪loading,那跟其他loading的实现就没什么区别了,我们做事讲究脚踏实地,能实现的实现,不能实现的,为了团队和谐,我们不得已坑蒙拐骗。那么我们还能更贴近实际情况一点吗?其实是可以的。

我们来分析一个场景,假设我们想让我们的loading更加真实一些,那么我们可以选择性地对页面上几个比较大的资源的加载进行跟踪,然后拆分整个进度条,比如我们页面有三张大图a、b、c,那么我们将进度条拆成五段,每加载完一张图我们就推进一个进度:

随机初始化[10, 20] ->
图a推进20%的进度 ->
图b推进25%的进度 ->
图c推进30%的进度 ->
完成100%

这三张图要占20% + 25% + 30% = 75%的进度。

问题是,如果图片加载完成是按照顺序来的,那我们可以很简单地:10(假设初始进度是10%) -> 30 -> 55 -> 85 -> 100,但事实是,图片不会按照顺序来,谁早到谁晚到是说不准的,所以我们需要更合理的方式去管理这些进度增量,使它们不会互相覆盖。

  1. 我们需要一个能够替我们累计增量的变量next
  2. 由于我们的progress都是传目的进度的,我们需要另外一个函数add,来传增量进度。

JavaScript

var $loading = $('#loading') var $progress = $('#progress') var prg = 0 var timer = 0 var now = new Date() var timeout = 5000 var next = prg add([30, 50], [1, 3], 100) // 第一阶段 window.setTimeout(() => { // 模拟图a加载完 add(20, [1, 3], 200) }, 1000) window.setTimeout(() => { // 模拟图c加载完 add(30, [1, 3], 200) }, 2000) window.setTimeout(() => { // 模拟图b加载完 add(25, [1, 3], 200) }, 2500) window.onload = () => { complete() } if (now - loadingStartTime > timeout) { complete() } else { window.setTimeout(() => { complete() }, timeout - (now - loadingStartTime)) } function complete () { add(100, [1, 5], 10, () => { window.setTimeout(() => { $loading.hide() }, 1000) }) } function add (dist, speed, delay, callback) { var _dist = random(dist) if (next + _dist > 100) { // 对超出部分裁剪对齐 next = 100 } else { next += _dist } progress(next, speed, delay, callback) } function progress (dist, speed, delay, callback) { var _delay = random(delay) var _speed = random(speed) window.clearTimeout(timer) timer = window.setTimeout(() => { if (prg

  • _speed >= dist) { window.clearTimeout(timer) prg = dist callback && callback() } else { prg += _speed progress (dist, speed, delay, callback) } $progress.html(parseInt(prg) + '%') console.log(prg) }, _delay) } function random (n) { if (typeof n === 'object') { var times = n[1] - n[0] var offset = n[0] return Math.random() * times + offset } else { return n } }
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
var $loading = $('#loading')
var $progress = $('#progress')
var prg = 0
 
var timer = 0
var now = new Date()
var timeout = 5000
 
var next = prg
 
add([30, 50], [1, 3], 100)  // 第一阶段
 
window.setTimeout(() => {  // 模拟图a加载完
  add(20, [1, 3], 200)
}, 1000)
 
window.setTimeout(() => {  // 模拟图c加载完
  add(30, [1, 3], 200)
}, 2000)
 
window.setTimeout(() => {  // 模拟图b加载完
  add(25, [1, 3], 200)
}, 2500)
 
window.onload = () => {
  complete()
}
 
if (now - loadingStartTime > timeout) {
  complete()
} else {
  window.setTimeout(() => {
    complete()
  }, timeout - (now - loadingStartTime))
}
 
function complete () {
  add(100, [1, 5], 10, () => {
    window.setTimeout(() => {
      $loading.hide()
    }, 1000)
  })
}
 
function add (dist, speed, delay, callback) {
  var _dist = random(dist)
  if (next + _dist > 100) {  // 对超出部分裁剪对齐
    next = 100
  } else {
    next += _dist
  }
 
  progress(next, speed, delay, callback)
}
 
function progress (dist, speed, delay, callback) {
  var _delay = random(delay)
  var _speed = random(speed)
  window.clearTimeout(timer)
  timer = window.setTimeout(() => {
    if (prg + _speed >= dist) {
      window.clearTimeout(timer)
      prg = dist
      callback && callback()
    } else {
      prg += _speed
      progress (dist, speed, delay, callback)
    }
 
    $progress.html(parseInt(prg) + '%')
    console.log(prg)
  }, _delay)
}
 
function random (n) {
  if (typeof n === 'object') {
    var times = n[1] - n[0]
    var offset = n[0]
    return Math.random() * times + offset
  } else {
    return n
  }
}

我们这里为了方便,用setTimeout来模拟图片的加载,真实应用应该是使用image.onload

以上,就是我们一步步实现一个进度loading的过程了,演示代码可以戳我的codePen 写一个网页进度loading。

看似很简单的一个功能,其实仔细推敲,还是有很多细节要考虑的。

到这里,其实真的已经完成了,代码有点多有点乱是不是?你可以整理一下,封装成为插件的。

然而,好吧,其实我已经把这个进度封装成插件了。。。

没错,其实我就是来帮自己打广告的。。。

好吧,github仓库在此 ez-progress。

ez-progress 是一个web(伪)进度插件,使用 ez-progress 实现这个功能非常简单:

JavaScript

var Progress = require('ez-progress') var prg = new Progress() var $loading = $('#loading') var $progress = $('#progress') prg.on('progress', function (res) { var progress = parseInt(res.progress) // 注意进度取整,不然有可能会出现小数 $progress.html(progress + '%') }) prg.go([60, 70], function (res) { prg.complete(null, [0, 5], [0, 50]) // 飞一般地冲向终点 }, [0, 3], [0, 200]) window.onload = function () { prg.complete(null, [0, 5], [0, 50]) // 飞一般地冲向终点 }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var Progress = require('ez-progress')
var prg = new Progress()
 
var $loading = $('#loading')
var $progress = $('#progress')
 
prg.on('progress', function (res) {
  var progress = parseInt(res.progress)  // 注意进度取整,不然有可能会出现小数
  $progress.html(progress + '%')
})
 
prg.go([60, 70], function (res) {
  prg.complete(null, [0, 5], [0, 50])  // 飞一般地冲向终点
}, [0, 3], [0, 200])
 
window.onload = function () {
  prg.complete(null, [0, 5], [0, 50])  // 飞一般地冲向终点
}

木油错,94这么简单!

这可能是我目前写过最短的博文了,由此看出以前是有多么的啰嗦,哈哈哈哈!

1 赞 13 收藏 2 评论

图片 1

秋月何时了,CSS3 border-radius知多少?

2015/11/02 · CSS · border-radius

原文出处: 张鑫旭   

前言

每当来个需要既要水平排版又要设置固定高宽时,我就会想起display:inline-block,还有为了支持IE5.5/6/7的hack*display:inline;*zoom:1;。然后发现盒子间无端端多了个不可选的空白符,于是想尽办法修复这个bug。

直到一天拜读了@一丝姐、@HAX等高人的秘笈后才顿悟,原来我错了。那不是bug,是我不懂而已。

一、秋月何时了

这两个月产出有点少,为什么呢?大家都学过「产出守恒定律」,文章产少了,是因为产了其他很屌的东西:
图片 2

早就知道女朋友是技术学习的第一阻碍力,现在发现小朋友才是技术学习的Boss级阻碍力。

对了,今天是万圣节,我有必要扮鬼让大家开心一下:
图片 3

告诉大家一个秘密,我每天早上就是这么帅醒的。

不过在我们国家,万圣节显得冷冷清清凄凄惨惨戚戚,但是,第11区的人民就热闹多了:
图片 4

不知道大家的万圣节是怎么过的,尤其今年恰逢周末。想想我年轻的时候,这样的节日不是加班,就是宅在家里。如果你也是这样,别桑心,没人给你扮鬼,咱们可以自己扮鬼开心下嘛。比如说:单身鬼,穷鬼等等。哟,你突然发现自己……根本就不用扮,直接本色出演就可以了!那……真是太恭喜你了,原来你每天都在过万圣节!图片 5 那更应该开心啦! 图片 6

今天10月末,过了今天,秋天也算是走到头了,但是,对于前端的学习,路还漫长,今天就说说CSS3 border-radius更深入的一些tips. 本文属于进阶知识点,所以,下面内容不会啰嗦一些基础知识,适合有一定是要经验的小伙伴。

先行者——IE5.5中的inline-block

当我们为支持IE5.5/6/7而添加这段hack时*display:inline;*zoom:1,总以为从IE8开始才支持display:inline-block属性值。其实从IE5.5开始已经支持了,只是IE5.5/6/7支持的是IE的自定义标准,而从IE8开始则是支持CSS2.1标准而已。

The inline-block value is supported starting with Internet Explorer 5.5. You can use this value to give an object a layout without specifying the object’s height or width.

XHTML

<style type="text/css"> .bk1{ background: #06F; } .bk2{ background: #F60; } .item{ width: 100px; height: 100px; display:inline-block; } </style> <div class="bk1 item"></div> <div class="bk2 item"></div> <span class="bk1 item"></span> <span class="bk2 item"></span>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<style type="text/css">
.bk1{
  background: #06F;
}
.bk2{
  background: #F60;
}
.item{
  width: 100px;
  height: 100px;
  display:inline-block;
}
</style>
<div class="bk1 item"></div>
<div class="bk2 item"></div>
<span class="bk1 item"></span>
<span class="bk2 item"></span>

图片 7

经过CSS2.1洗礼的我们对上述内容不禁会发出两个疑问:

  1. 为啥block-level element设置了display:inline-block后还是垂直方向排列呢?
  2. 为啥inline-level element设置了display:inline-block后之间没有诡异的间隙呢?

还记得杨过是如何变成神雕大侠的吗?不就是被断右臂后发现左手才是真爱吗:)
好了,其实我的意思是抛弃过去对display:inline-block的认知,重新来理解IE5.5/6/7下的它才是硬道理啦。

对于问题1,首先上面的引用很直白地告诉我们——display:inline-block能触发hasLayout,然后就没了。所以block-level element依然是block-level element,不会一夜成了inline-level element的。结论:display:inline-block仅会触发hasLayout,而元素本该怎么排版还是怎么排版。关于hasLayout的内容可参考《CSS魔法堂:hasLayout原来是这样!》

对于问题2,我们先看看是否真的没有间隙吧!

XHTML

<style type="text/css"> .bk1{ background: #06F; } .bk2{ background: #F60; } .item{ width: 100px; height: 100px; display:inline-block; } </style> <span class="bk1 item"></span> <span class="bk2 item"></span> <br/><br/> <span class="bk1 item">bk1</span> <span class="bk2 item"></span>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<style type="text/css">
.bk1{
  background: #06F;
}
.bk2{
  background: #F60;
}
.item{
  width: 100px;
  height: 100px;
  display:inline-block;
}
</style>
<span class="bk1 item"></span>
<span class="bk2 item"></span>
<br/><br/>
<span class="bk1 item">bk1</span>
<span class="bk2 item"></span>

图片 8

见鬼了,在前一个盒子内添加些文本就出现间隙了?其实这真的和display:inline-block无关的,大家就放过他吧!来上呈堂证供!

XHTML

<style type="text/css"> .bk1{ background: #06F; } .bk2{ background: #F60; } <span class="bk1">no line break</span> <span class="bk2"> has line break </span>

1
2
3
4
5
6
7
8
9
10
11
12
13
<style type="text/css">
.bk1{
  background: #06F;
}
.bk2{
  background: #F60;
}
<span class="bk1">no line break</span>
  
  
<span class="bk2">
has line break
</span>

图片 9

可以看到蓝色块k和红色块h间存在一个空格,而红色块k后也存在一个空格。可是代码中我们看到蓝红色块间有4个&#x20HTML实体,为啥只有一个空格呢?而红色块中仅仅换了行而已,怎么就有个空格呢?

先抛结论:上面两端代码均是white space、white space collasping再作祟。

二、border-radius私有前缀拜拜图片 10

还有个把月就2016年了,00后都已经登上历史舞台了,大家都懂我说的意思,浏览器个把年前就把私有前缀给去掉了,现在完全没必要还傻傻使用-webkit-border-radius-moz-border-radius,至少我是早就不使用了,你随意~

White space不仅是空格符那么简单

初看之下以为就是空格键,其实white space是一组空白字符和换行符组成。查看unicode字符集我们会发现有一大堆空白字符(如NO-BREAK SPACE等),但HTML只把ASCII space( )ASCII tab( )ASCII form feed(&#x000C)Zero-width space(​)纳入white space囊中,另外还将line break(换行符)carriage return( )line feed( )和它俩的组合纳入white space中。

三、border-radius百分比值

border-radius支持百分比值,例如border-radius:50%. 如果大家看早些年CSS3 border-radius的文档或者文章,会发现,根本就没有提过百分比值这一茬。究其原因,是因为百分比值的支持是后来才支持的,跟数值不是一起出来的。比方说某些老版本的Android机子,border-radius:50%它就不认识。

不过,事情已经过去很多年了,现在大家可以不用在意这些细节了。

OK,大家都知道这个百分比是相对单位,但是,不同属性的百分比值相对的内容是不一样的,对吧,比方说translate是自身,width/height是父级,background-position需要尺寸差计算等。那这里border-radius的百分比值相对的属性是?

我们炒个板栗知道了:

CSS

.radius-test1 { width: 100px; height: 100px; border: 50px solid #cd0000; border-radius: 50%; }

1
.radius-test1 { width: 100px; height: 100px; border: 50px solid #cd0000; border-radius: 50%; }

JavaScript

<div class="radius-test1></div>

1
&lt;div class="radius-test1&gt;&lt;/div&gt;

图片 11

哦哦哦哦,我知道了,是相对于元素占据尺寸的百分比(类似jQuery outerWidth()/outerHeight()方法代表尺寸),也就是包含边框,padding后的尺寸。而不是单纯地相对于width/height值。

于是乎,我们要实现一个正方形元素的圆角效果(例如网站头像),一个50%就可以搞定,而无需去计算。

图片 12

border-radius还有一个大值特性,也就是值很大的时候,只会使用能够渲染的圆角大小渲染。因此,要实现一个正方形元素的圆角效果(例如网站头像),我们还可以使用一个很大的原教旨,同样是不需要计算的。例如,下面240*240像素图片,我设置圆角大小300px,跟上面效果一样。
图片 13

咦?貌似大数值border-radius值好像和50%没什么区别啊?因为上面的图片是正方形,实际上两者区别不小,我们把上面红圈圈例子的height改成200px看看两者对应效果:

CSS

.radius-test2 { width: 100px; height: 200px; border: 50px solid #cd0000; border-radius: 50%; }

1
.radius-test2 { width: 100px; height: 200px; border: 50px solid #cd0000; border-radius: 50%; }

CSS

.radius-test3 { width: 100px; height: 200px; border: 50px solid #cd0000; border-radius: 300px; }

1
.radius-test3 { width: 100px; height: 200px; border: 50px solid #cd0000; border-radius: 300px; }

XHTML

<div class="radius-test2"></div><br>

1
<div class="radius-test2"></div><br>

图片 14

XHTML

<div class="radius-test3></div>

1
<div class="radius-test3></div>

图片 15

此时,差别就很明显了。上面的长得像马桶盖子, 而后面长得像操场跑道。

图片 16

为什么呢?50%成为“马桶盖子”还好理解,宽度和高度分别50%圆角化;但是后面明明圆角300像素,比占据高度需要的圆角大小值要高出不少,为什么还是直的呢?哈哈,实际上就是因为太大了,所以才会变成的“操场跑道”。

没错,因为值大了,要弄清此问题,有必要深入下。不行了,上年纪了,困了,去洗澡睡觉了明天继续。

inter-word space——White space的用途之一

西文是以空格来分隔单词的,而汉字间则无需空格分隔,但为了统一西文、东亚和CJK的排版,于是抽象出一个名为inter-word space的概念用于分隔词义单元,white space则作为inter-word space的值域,而定义域就是语言信息。如西文以ASCII SPACE作为inter-word space,而泰文则以Zero-width space作为inter-word space,汉语则没有inter-word space,所以word-spacing属性不影响汉字间的距离,本来无一物何处惹尘埃呢。字形、单词间的水平距离

四、border-radius单值表现深入

由于我们平时使用border-radius绝大多数情况是都单值,例如border-radius: 300px,于是,久而久之可那会忽略这样一个事实,那就是border-radius单值实际上是一种简写。就跟padding:300pxborder-width:300px是一样的,是各个方位等值时候的一种简化书写形式。但是,和一般的可简写CSS属性相比,border-radius要比看上去的复杂的多,表面上是琅琊山伯爵,实际上是当年大梁的贵族少年。

我们将border-radius: 300px还原成其整容前的模样,结果是:

CSS

border-radius: 300px 300px 300px 300px/300px 300px 300px 300px;

1
border-radius: 300px 300px 300px 300px/300px 300px 300px 300px;

我勒个擦,一副把七大姑八大婆都跳出来的即视感,这么这个多~~

图片 17

虽然看上去都是300px, 长得好像一样,实际上,表示的含义各不相同,翻译成普通话就是:

CSS

border-radius: 左上角水平圆角半径大小 右上角水平圆角半径大小 右下角水平圆角半径大小 左下角水平圆角半径大小/左上角垂直圆角半径大小 右上角垂直圆角半径大小 右下角垂直圆角半径大小 左下角垂直圆角半径大小;

1
border-radius: 左上角水平圆角半径大小 右上角水平圆角半径大小 右下角水平圆角半径大小 左下角水平圆角半径大小/左上角垂直圆角半径大小 右上角垂直圆角半径大小 右下角垂直圆角半径大小 左下角垂直圆角半径大小;

也就是斜杠前的是水平方向,斜杠后面的是垂直方向。

虽然border-radiusborder-width/border-color等都是border打头的,但是,两者缩写与方位的表示确实不一样的。传统的边框属性border四个值分别表示上边框,右边框,下边框,左边框。但是,border-radius指的则是角落,所以,我们眼睛的关注点,需要移动下,从边框到角落(如下图所示)(每个方位都如此逆时针移动)。

图片 18

都是最多4个值,1~3个缩写的规则也是一样的(一个是边,一个是角),不赘述。

那上面提到的“水平/垂直”又是什么鬼呢?

对于正圆,我们基本上很少提“水平半径”和“垂直半径”,因为,半径都是一样长。但是,对于标准椭圆,那就不一样了,因为存在最长半径和最小半径。在web中,圆角的水平半径指的就是椭圆的水平半径,垂直半径就是椭圆下图所示的垂直半径:
图片 19

一个水平半径和一个垂直半径所夹起的那1/4段圆弧就是我们平时看的的圆角呈现,如下变色显示:

图片 20

demo
一例胜千图,为了方便大家感受下八大婆的具体行为,我特意紧承上面的例子,制作了个可操作的实时圆角和代码的例子。

您可以狠狠地点击这里:CSS3 border-radius圆角各个属性值作用demo

图片 21

OK, 为了演示水平垂直半径,我们现在先重置0,然后让水平1和垂直1都是300像素,如下图所示:
图片 22

大家会看到,左上角出现了圆弧,那这个圆弧是怎么来的呢?我们画个圈圈辅助下~

图片 23

图片 24

大家发现没,原本设置的是300像素*300像素,结果最后显示的却是200像素*200像素半径下的圆弧效果,这显然不符合认知啊!!

实际上是这样的,CSS3圆角除了大值特性,还有一个等比例特性,就是水平半径和垂直半径的比例是恒定不变的。

回到上面例子,由于我们的元素占据宽度200像素,高度300像素。所以,根据大值特性,水平方向的300像素只能按照200像素半径渲染;再根据等比例特性,虽然垂直方向理论上的最大半径是300像素,但是受制于当初设定的300px*300px1:1比例,垂直方向最终渲染的半径大小也是200像素。于是,我们最后得到的只是一个200像素*200像素的圆弧。

第三节末尾所提到的“反而因为值设大了”就是指的这个。

可能有人会疑问,那该如何设置才能实现等同于border-radius:50%的效果呢。哈哈,如果你理解了上面的内容,其实就很简单了,最关键的一点就是比例关系。我们的元素占据的尺寸是200像素*300像素。所以,只要让水平半径和垂直半径保持2:3的比例就可以了,然后,可以利用“大值特性”设一个你认为安全的值就可以了。

比方说2倍尺寸border-radius: 400px/600px, 如下代码和效果:

CSS

.radius-test4 { width: 100px; height: 200px; border: 50px solid #cd0000; border-radius: 400px/600px; }

1
.radius-test4 { width: 100px; height: 200px; border: 50px solid #cd0000; border-radius: 400px/600px; }

XHTML

<div class="radius-test4"></div>

1
<div class="radius-test4"></div>

图片 25

是不是搞明白原理之后,之前晕头转向的表现是不是分分钟就理解了哈!

White space collapsing的玩法

兼容性问题又来了,因为各浏览器的实现均不尽相同。

XHTML

<style type="text/css"> span{background:#F60;} </style> <div><span> before</span></div> <div><span> before</span></div> <div><span>after </span></div> <div><span>after </span></div> <div><span>after </span></div> <div><span>one two</span></div> <div><span>one two</span></div> <div><span> </span></div>

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
<style type="text/css">
  span{background:#F60;}
</style>
<div><span>
 
before</span></div>
<div><span>
 
before</span></div>
<div><span>after
 
</span></div>
<div><span>after
 
</span></div>
<div><span>after
</span></div>
<div><span>one
two</span></div>
<div><span>one
two</span></div>
<div><span> &#x000C;
</span></div>

** chrome43 **

  1. 对于起始标签与第一个non-white-space字符间的white-space字符串,以carriage return( )作为white-space合并单元的起始符,最后保留各合并单元的合并结果。
  2. 结束标签与最后一个non-white-space字符间的white-space字符串,以carriage return( )作为white-space合并单元的结束符,最后保留各合并单元的合并结果。
  3. 词义单元间的white-space字符串,以carriage return( )作为white-space合并单元的分界符,最后保留各合并单元的合并结果。
  4. 标签内仅包含white-space字符串,那么这些white-space字符串将被忽略。

图片 26
** FF5.0 **

  1. 对于起始标签与第一个non-white-space字符间和结束标签与最后一个non-white-space字符间的white-space字符串将被忽略。
  2. 词义单元间的white-space字符串,以carriage return( )作为white-space合并单元的分界符,最后保留各合并单元的合并结果。
  3. 标签内仅包含white-space字符串,那么这些white-space字符串将被忽略。

图片 27
** IE8+ **

  1. 对于起始标签与第一个non-white-space字符间和结束标签与最后一个non-white-space字符间的white-space字符串将被忽略。
  2. 词义单元间的white-space字符串,合并为1个(ASCII space)字符。
  3. 标签内仅包含white-space字符串,那么这些white-space字符串将被忽略。

图片 28

** IE5.5/6/7 **

  1. 对于起始标签与第一个non-white-space字符间的white-space字符串将被忽略。
  2. 结束标签与最后一个non-white-space字符间的white-space字符串,合并为1个(ASCII space)字符。
  3. 词义单元间的white-space字符串,合并为1个(ASCII space)字符。
  4. 标签内仅包含white-space字符串,那么这些white-space字符串将被忽略。

图片 29
合并单元:合并单元包含0到N个white-space字符串,最终合并为0到1个white-space字符
SGML描述B.3.1 Line breaks

specifies that a line break immediately following a start tag must be ignored, as must a line break immediately before an end tag. This applies to all HTML elements without exception.

XHTML

<A>My favorite Website</A> <A> My favorite Website </A>

1
2
3
4
<A>My favorite Website</A>
<A>
My favorite Website
</A>

望文生义翻译法:标签与正文间的line breaks要被忽略掉!也就是上下两种HTML格式的渲染效果应该一致。实际上除了IE5.5/6/7外其他浏览器均遵守之一规定的。也许你会说上面的实验不是已经证明chrome43不遵守这个法则吗?其实

XHTML

<A> My favorite Website </A>

1
2
3
<A>
My favorite Website
</A>

HTML格式等价于<A>#x000A;My favorite Website#x000A;</A>而不是<A>#x000D;#x000A;My favorite Website#x000D;#x000A;</A>。现在大家都清楚了吧:)

绕到这里我想大家都有点晕了,到底这个跟问题2有啥关系呢?先不要着急嘛,我们先记住两点:

  1. IE5.5/6/7中”结束标签与最后一个non-white-space字符间的white-space字符串,合并为1个(ASCII space)字符”;
  2. IE5.5/6/7中仅字符(串)可以作为词义单元,而IE8+中inline-level element也作为词义单元。
XHTML

&lt;span class="bk1 item"&gt;&lt;/span&gt; &lt;span class="bk2
item"&gt;&lt;/span&gt; &lt;br/&gt;&lt;br/&gt; &lt;span class="bk1
item"&gt;bk1&lt;/span&gt; &lt;span class="bk2 item"&gt;&lt;/span&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6d17e73c7306787940-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d17e73c7306787940-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6d17e73c7306787940-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d17e73c7306787940-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6d17e73c7306787940-5">
5
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6d17e73c7306787940-1" class="crayon-line">
&lt;span class=&quot;bk1 item&quot;&gt;&lt;/span&gt;
</div>
<div id="crayon-5b8f6d17e73c7306787940-2" class="crayon-line crayon-striped-line">
&lt;span class=&quot;bk2 item&quot;&gt;&lt;/span&gt;
</div>
<div id="crayon-5b8f6d17e73c7306787940-3" class="crayon-line">
&lt;br/&gt;&lt;br/&gt;
</div>
<div id="crayon-5b8f6d17e73c7306787940-4" class="crayon-line crayon-striped-line">
&lt;span class=&quot;bk1 item&quot;&gt;bk1&lt;/span&gt;
</div>
<div id="crayon-5b8f6d17e73c7306787940-5" class="crayon-line">
&lt;span class=&quot;bk2 item&quot;&gt;&lt;/span&gt;
</div>
</div></td>
</tr>
</tbody>
</table>


IE5.5/6/7下等价于  


XHTML

&lt;span&gt; &lt;/span&gt; &lt;br/&gt;&lt;br/&gt; &lt;span&gt;bk1
&lt;/span&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6d17e73ca280682483-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d17e73ca280682483-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6d17e73ca280682483-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d17e73ca280682483-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6d17e73ca280682483-5">
5
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6d17e73ca280682483-1" class="crayon-line">
&lt;span&gt;
</div>
<div id="crayon-5b8f6d17e73ca280682483-2" class="crayon-line crayon-striped-line">
&lt;/span&gt;
</div>
<div id="crayon-5b8f6d17e73ca280682483-3" class="crayon-line">
&lt;br/&gt;&lt;br/&gt;
</div>
<div id="crayon-5b8f6d17e73ca280682483-4" class="crayon-line crayon-striped-line">
&lt;span&gt;bk1
</div>
<div id="crayon-5b8f6d17e73ca280682483-5" class="crayon-line">
&lt;/span&gt;
</div>
</div></td>
</tr>
</tbody>
</table>


对比一下上面的规则,空隙自然就有了。  
IE8+下等价于  


XHTML

&lt;span&gt;&nbsp; &nbsp;&lt;/span&gt; &lt;br/&gt;&lt;br/&gt;
&lt;span&gt;&nbsp; &nbsp;&lt;/span&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6d17e73cd347104087-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d17e73cd347104087-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6d17e73cd347104087-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d17e73cd347104087-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6d17e73cd347104087-5">
5
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6d17e73cd347104087-1" class="crayon-line">
&lt;span&gt;&amp;nbsp;
</div>
<div id="crayon-5b8f6d17e73cd347104087-2" class="crayon-line crayon-striped-line">
&amp;nbsp;&lt;/span&gt;
</div>
<div id="crayon-5b8f6d17e73cd347104087-3" class="crayon-line">
&lt;br/&gt;&lt;br/&gt;
</div>
<div id="crayon-5b8f6d17e73cd347104087-4" class="crayon-line crayon-striped-line">
&lt;span&gt;&amp;nbsp;
</div>
<div id="crayon-5b8f6d17e73cd347104087-5" class="crayon-line">
&amp;nbsp;&lt;/span&gt;
</div>
</div></td>
</tr>
</tbody>
</table>


inline-level
element整体作为词义单元,从外部看根本不用管里面具体字符串是什么。

五、border-radius与图形构建

border-radius支持的可变值足有八个(在本文戏称为八大婆,简称八婆),基本上,每一个值的变化,都会呈现不同的图形,例如,下面这样,我东拖拖,西拖拖,拖出了个英文字母D:

图片 30

或者我们可以只留一个方向或2侧的边框,可以拉出一些惊喜的效果,如下gif截图:
图片 31

诸如很多的,就看你的脑洞和技术了。

本身CSS的border属性就可以构建三角,梯形等等,现在,再配合多变的border-radius,我们可以发挥的空间就更大了。但是,要想用得得心应手,还是需要深入理解border-radius的各个表现。

one-div上就有些图标就是利用了border-radius实现的,大家有兴趣可以瞅瞅,看看人家怎么巧妙使用border-radius的,目的在于学习理解border-radius,倒不是效果本身。知其根本自然上层信手拈来。

本文由澳门新葡亰手机版发布于web前端,转载请注明出处:秋月何时了,写一个网页进度loading

上一篇:浅谈Hybrid技术的设计与实现,浅谈Hybrid技术的设 下一篇:圣杯布局小结
猜你喜欢
热门排行
精彩图文