css秀,CSS秀起来真没JS什么事

发现了一个纯CSS实现,具有渐变倒影和3D旋转效果的栅栏动画,他的实现方式是:利用10个

元素创建10个栅条,接着再复制整份
元素,并创建一个渐变遮罩形成渐变效果,以此作为栅栏的倒影。

这听起来有点像用左脚的脚趾去抓你的右耳背部!更不用说这种渐变遮罩的方式根本不适用于非单一颜色的背景。难道没有基于CSS的更好的方法吗?

62075ef49d124e2815a2ed042098da78.png

答案是有的,我们有更好的方式可以实现这种效果!但遗憾的是,这种方式的兼容性不够好,如果我们不想使用canvas,但又希望能够兼容所有的主浏览器,上述的方法无疑还是最好的。

本文将探讨今天我们创建倒影的所有可行选择,阐述这些“相似”的解决方案,在跨浏览器问题上导致的痛苦,最后就这些问题该怎么做讨论下我的想法。

基础代码

在讨论倒影之前,我们先看看如何创建、定位和着色栅栏条,因为这部分对所有的浏览器都是通用的。

首先我们创建了一个.loader包装器并包含10个.bar元素

除了直接写HTML外,我们也可以用预处理器,比如Haml:

.loader

- 10.times do

.bar

我们从视口的中间位置开始定位这些元素。通常我们都是使用top: 50%去居中,但如果我们用bottom: 50%后面会更方便。

div {

position: absolute;

bottom: 50%; left: 50%;

}

我们给这些栅栏条定义宽度和高度,同时给它一个背景:

$bar-w: 1.25em;

$bar-h: 5 * $bar-w;

.bar {

width: $bar-w; height: $bar-h;

background: currentColor;

}

web前端开发学习Q-q-u-n: 767273102 ,分享开发工具,零基础,进阶视频教程,希望新手少走弯路

我们希望栅条的底部边缘可以跟视口的横向中轴线相重叠,通过前面我们设置bottom: 50%已经实现了这种效果。

此时,我们所有栅条是全部堆叠在一起的,他们的左边缘与视口的纵向中轴线重合,底部边缘则与横向中轴线重叠,!

定位栅栏

我们需要将这些栅栏定位为:第一条栅条左边缘和最后一条栅条右边缘与纵向中轴线之间的距离相同,这个距离总是等于条数($n)乘以条宽($bar-w)结果值的一半。最初的演示用的是普通的CSS,现在我们使用Sass来简化代码量

dee09577ce6d09accfb477ebd8d6a374.png

特别提醒,条宽$bar-w中间是连接符,不是减号,避免引起歧义,后续使用$bar_w替代

这意味着,从所有栅条的位置开始,我们需要把第一个栅条向左移动 0.5 * $n * $bar_w。左边是x轴的负方向,这意味着前面需要加一个负号,因此第一个栅条的margin-left值是 -.5 * $n * $bar_w。

第二个栅条的位置则是在第一个栅条位置上往右移动一个栅条宽度的距离,那么它的margin-left值应该是 -.5 * $n * $bar_w + $bar_w;

同理第三个栅条的margin-left值为 -.5 * $n * $bar_w + 2 * $bar_w;

那么最后一个栅条的margin-left就是:-.5 * $n * $bar-w + ($n - 1) * $bar-w.

如下图:

aa40d4c6124421ba21ae9ef4a1a0dd93.png

我们用代码表述为:

$n: 10;

@for $i from 0 to $n {

.bar:nth-child(#{$i + 1}) {

margin-left: ($i - .5 * $n) * $bar-w;

}

}

我们给它们设置下box-shadow,这样我们可以清楚地看到一个栅条的结束和下一个栅条的开始:

e8d2b1bad0073045a697d22b59226a40.png

给栅栏上色

栅栏的背景颜色从最左边的深蓝色(#1e3f57)过度到最右边的浅蓝色(#63a6c1),这听起来像是Sass的mix()函数做的事情。mix()的第一个参数是淡蓝色,第二个参数是深蓝色,第三个参数(称为相对权重,以%为单位)是最终混合结果中淡蓝色包含的量。

对于第一个栅条,淡蓝色的量应该为 0% - 0%,因此最终结果仅为深蓝色;

相同地,对于最后一个栅条,淡蓝色的量应该为100% -100%,背景色的构成就是淡蓝色;

对于剩下的栅条,我们需要让中间值均匀分布。假设我们有$n个栅条,第一个是0%,最后一个是100%,然后我们需要把它们分成$n - 1个等距间隔。如下图:

6e0982289ef22e14d1eefdaff67c659d.png

一般来说,编号$i的栅条的相对权重为: $i * 100% / ($n - 1),我们添加如下代码:

$c: #63a6c1 #1e3f57; // 1st = light 2nd = dark

@for $i from 0 to $n {

// list of mix() arguments for current bar

$args: append($c, $i * 100% / ($n - 1));

.bar:nth-child(#{$i + 1}) {

background: mix($args...);

}

}

web前端开发学习Q-q-u-n: 767273102 ,分享开发工具,零基础,进阶视频教程,希望新手少走弯路

现在,这些栅栏看起来跟最初演示的一样:

9fd5c6a27807f1a930c43e9de4d4ebcb.png

-webkit-box-reflect

box-reflect仍然是一个非标准属性,许多主流浏览器尚未对其进行支持,幸运的是,它可以在webkit浏览器中很好地运行,只需要加上浏览器的私有属性就可以了。

让我们看一下它是怎么工作的,他的值有三部分:

-webkit-box-reflect:none | ? ?

:倒影的方向,可以是below, left, above, right中的任意值

:倒影与原像的距离,取值可以是固定像素值或百分比

:设置倒影的遮罩效果,可以是背景图片或渐变图像

在我们的例子中,首先想到的是在.loader中添加这个:

.loader {

-webkit-box-reflect: below 0 linear-gradient(rgba(#fff, 0), rgba(#fff, .7));

}

其次我们还需要给.loader设置尺寸,因为它包含的栅栏都是绝对定位的,此时.loader的实际尺寸是0px X 0px。我们将其宽度定义为所有栅栏宽度之和,高度则与栅栏高度一致:

$loader-w: $n * $bar-w;

.loader {

width: $loader-w; height: $bar-h;

box-shadow: 0 0 0 1px red;

}

添加上面的代码后,在webkit浏览器中会看到下面的效果:在线查看

c37babbe57fa9a9a6dab9150ffed9e19.png

我们已经可以看到加载器的边界和一些倒影,但它们的位置不再正确了。我们需要将加载器左移居中,同时让栅栏底部与它们父元素的底部重合:

.loader { margin-left: -.5 * $loader-w; }

.bar { bottom: 0; }

这样就解决了定位的问题,效果如:

68c3806a20b2ed8cb7a6acdf2a66769f.png

// 这里省略一堆关于Firefox的兼容方案:element()+svg的mask …

动画

最初在CodePen实现的动画非常简单,只是一个3D旋转栅栏:

@keyframes bar {

0% {

transform: rotate(-.5turn) rotateX(-1turn);

}

75%, 100% { transform: none; }

}

将动画应用在所有的栅栏上:

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

接着为每个栅条添加不同的延时:

animation-delay: $i*50ms;

由于我们是3D旋转栅栏,因此我们还需要在loader元素上添加perspective属性:.

.loader {

perspective: 62.5em;

}

web前端开发学习Q-q-u-n: 767273102 ,分享开发工具,零基础,进阶视频教程,希望新手少走弯路

但这只在webkit浏览器中使用-webkit-box-reflect时有效。最终实现的效果:

185f707e61eed92c92640ee98d060bc6.png

最后一点思考

算了,这段不用翻译了!

大意讲作者对-webkit-box-reflect和element()+mask(svg的mask标签)解决跨浏览器实现倒影问题上的看法,不影响我们理解box-reflect的优秀,有兴趣的读者可以去看看原文,感恩~

打开App,阅读手记

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值