37

第五届CSS大会主题分享之CSS创意与视觉表现

 4 years ago
source link: https://www.tuicool.com/articles/vYNB3iZ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

byzhangxinxu from https://www.zhangxinxu.com/wordpress/?p=8708

本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

BnMJvmY.jpg!web

今年4月份的时候有幸被邀请到深圳在中国第五届CSS开发者大会上做了名为“CSS创意与视觉表现”的主题分享,这里把分享内容整理成文,希望可以帮到需要的小伙伴。

总共分享了10个CSS创意与视觉表现案例,全部都是纯CSS实现的视觉表现效果。

一、布局:平行四边形

如何实现下图所示的平行四边形布局效果?

VnAbeaJ.png!web

如果我们盯着四边形本身,是实现不了我们的效果的。

需要逆向思维,我们要实现的可能不是平行四边形本身,而是借助CSS Shapes布局实现左上方以及右下方的两个三角。

HTML和CSS代码如下:

<!-- 左三角 -->
<div class="shape-left"></div>
<!-- 右三角 -->
<div class="shape-right"></div>
<content class="content">
   ...内容...
</content>
.shape-left {
    float: left;
    width: 200px; height: 500px;
    /* 倒三角 */
    shape-outside: polygon(0 0, 100% 0, 0% 100%);
}
.shape-right {
    float: right;
    width: 200px; height: 500px;
    /* 正三角 */
    shape-outside: polygon(100% 0, 100% 100%, 0 100%);
}

布局高亮示意如下:

7RruInU.png!webnaeIFvB.png!web

更具体的介绍可以参见之前写的这篇文章:“ CSS实现平行四边形布局效果 ”。

二、图形:透明方格的绘制

例如要CSS实现下图所示的PS中的透明背景效果:

mmemAnY.png!web

我们视觉上都是一个一个的正方形,如果是一个方格,我们很好绘制,宽高一致,设置个背景色即可,但是这里是平铺的,而且还是深浅相间的,那该如何实现呢?

如果我们遇到规律的平铺图形,99%的概率的使用CSS background属性实现,天然平铺。但是问题又来了,CSS background只能会是一个单独的正方形,但是如果是4个格子交错呈现,似乎无能为力啊?

就是我们要开拓思路,曲线救国,我想的不应该是绘制正方形,而是绘制三角色带,然后错误进行组合,因为CSS background可以任意多个背景图像重复。

HTML和CSS代码如下:

<div class="square"></div>
.square {
    display: inline-block;
    padding: 300px;
    background-color: #fff;
    background-image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%), linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%);
    background-size: 16px 16px;
    background-position: 0 0, 8px 8px;
}

下图是一个平铺单元效果:

vu6Jrem.png!web

然后下图示意的是两个平铺单元1/4错误重叠的GIF示意:

BJFzMnm.gif

可以看到两个小三角重叠之后,在中心区域正好形成了一个正方形。

如果我们把平铺单元的数量进一步放大,就可以看到完整的深浅相间的透明方格图形效果,如下GIF演示:

FfMBBza.gif

您可以狠狠地点击这里:透明方格CSS绘制demo

三、图形:镂空

下图是一个图像剪裁效果常见的UI界面:

m26ZF3r.png!web

如何实现这个中间镂空四周黑色半透明的效果呢?

人总是习惯于拿现实世界隐射代码世界。上图这种镂空效果非常像一个窗户,所以很多人第一反应是上下左右找几个色块拼一下,如果你真的这么做了,那真的是实现太复杂了,其实有很简单的方法,就是使用 outline 属性。

中间的方框框元素直接下面一行CSS就可以了:

.square-shape {
    outline: 9999px solid rgba(0,0,0,.5);
}

直接弄一个尺寸很大很大很大的黑色半透明 outline 轮廓即可,完整代码如下:

<div class="clip-img-x">
    <div class="clip-shape"></div>
    <img src="./mm.jpg" class="clip-img">
</div>
.clip-img-x {
    display: inline-block;
    overflow: hidden;
    position: relative;
}
.clip-img {
    display: block;
}
.clip-shape {
    width: 150px; height: 150px;
    outline: 9999px solid rgba(0,0,0,.5);
    position: absolute;
    left: 0; right: 0; top: 0; bottom: 0;
    margin: auto;
    cursor: move;
}

如果我们的镂空效果是圆角怎么办呢?例如新手帮助引导效果:

QfAvIva.png!web

outline 轮廓不支持圆角轮廓,因此,我们需要换一个CSS属性,那就是 box-shadowbox-shadow 属性则第4个参数可以实现扩展效果,因此:

.overlay-shape {
    border-radius: 50%;
    box-shadow: 0 0 0 9999px rgba(0,0,0,.75);
}

完整代码可以参见demo:圆角镂空demo

圆角镂空的实现除了 box-shadow ,CSS radial-gradient 径向渐变也是非常常用的属性。

例如我们要实现一个下图所示的圆角选项卡图形效果:

qQbU7bU.png!web

就可以使用CSS radial-gradient 径向渐变实现。

完整代码可以参见demo:外圆角选项卡demo

最后,如果我们想要实现任意形状的镂空效果,则可以使用CSS mask遮罩。

例如要实现一个五角星遮罩效果,则关键CSS如下:

.shape-hollow {
    /* 实际开发需要-webkit- */
    mask: no-repeat center;
    mask-image: linear-gradient(black, black), url(./star.svg);
    mask-size: cover, 120px 120px;
    /* firefox */
    mask-composite: exclude;
    /* Chrome */
    mask-composite: source-out;
}

设置遮罩合成模式为剔除,于是如果遮罩图形发生重叠,则这块区域的内容给删除,表现为镂空。因此,我们只要使用渐变绘制一个满屏的黑色图像,则此时和任意的PNG或者SVG图形应用“剔除”遮罩就能实现任意图形的镂空效果。

上面CSS可以实现类似下图的镂空效果:

AFFnUn7.png!web

我们还可以借助 mask-size 实现有意思的过场动画效果,具体可以参见该demo:任意图形镂空demo

四、图形:图像处理

在过去,两个长相类似,但风格不同的图片一定会使用两张图片,但是,随着CSS技术的不断发展,记住CSS滤镜和混合模式,我们可以让一张图片实现多种风格的效果。

例如下面这个我实际项目中遇到的案例,有一张图片素材,如下:

uu2Mvya.jpg!web

图片中呈现的是一张白天书房效果,这个时候产品经理提了个需求,希望这张白天的图片能够也能实现类似晚上的效果,就像下图这样:

EjUNvqj.png!web

在过去我们一定会使用两张图片,但是现在我们只需要一张白天的图,然后配合一点CSS代码即可:

.night {
    width: 256px; height: 256px;
    background: rgba(0,40,140,.6) url(./house-bed.jpg);
    background-size: 100%;
    background-blend-mode: darken;
    filter: brightness(80%) grayscale(20%) contrast(1.2);
}

滤镜参数是设计师站在背后一点一点调试出来的。

由于滤镜和混合模式可以非常方便的实现各种图像处理效果,因此,就有开发者专门弄了一个CSS库,可以方便的实现多种图像处理效果,比方说CSSgram: https://github.com/una/CSSgram

ARb6b2z.jpg!web

更多内容可以参见之前的这篇文章:“ 纯CSS图片滤镜项目CSSgram简介 ”。

然后还有更高级的图像处理,可以把图像变成水彩或是彩铅效果:

bYreemv.png!web

例如素描效果CSS代码:

.sketch {
    width: 256px; height: 192px;
    background: url(./example.jpg) -2px -2px, url(./example.jpg);
    background-size: 258px 194px;
    background-blend-mode: difference;
    filter: brightness(3) invert(1) grayscale(1);
}

本小节所有案例源代码参见这里: 滤镜与混合模式下的图像demo

五、动画:饼图

例如下图是使用纯CSS绘制饼图效果,饼图的百分占比比可以根据外部CSS变量自动变化:

jeee6jy.png!web

实现原理

实现原理和很多年前写的这篇“ CSS3实现鸡蛋饼饼图loading ”类似,如下:

  1. 正方形视区分左右两个半区,溢出隐藏;
  2. 进度前50%左半区隐藏,右半区旋转;
  3. 进度后50%左半区显示并旋转,右半区完整覆盖;

GIF示意如下(点击播放):

u26NBja.png!web

下面关键的问题是如何实现前50%进度左半去隐藏,后50%进度右半区一直显示呢?

如果是JavaScript,这样的逻辑实现上非常简单,我们只要写一个if语句就好了, if (percent < 50) {} else {} 这样,但是CSS目前还没有支持复杂的逻辑语法,怎么办呢?

这里给大家介绍一个非常具有意思的实现方法,可以让CSS也具有类似if语句的效果。

CSS中的 opacity 属性有个很有意思的特性,那就是 opacity负数浏览器按照0解析;opacity大于1,浏览器按照1解析

.example {
  opacity: -2;    /* 解析为 0, 完全透明 */
  opacity: -1;    /* 解析为 0, 完全透明 */
  opacity: 2;     /* 解析为 1, 完全不透明 */
  opacity: 100;   /* 解析为 1, 完全不透明 */
}

所以,这里的饼图左右区域的隐藏就可以利用这种特性配合CSS calc计算实现,CSS代码如下(红色高亮部分是实现亮点):

.pie-left,
.pie-right {
    width: 50%; height: 100%;
    float: left;
    position: relative;
    overflow: hidden;
}
.pie-left::before,
.pie-right::before,
.pie-right::after {
    content: '';
    position: absolute;
    width: 100%; height: 100%;
    background-color: teal;
}
.pie-left::before {
    left: 100%;
    transform-origin: left;
    transform: rotate(calc(3.6deg * (var(--percent) - 50)));
    /* 左半区前50%进度不显示 */
    opacity: calc(99999 * (var(--percent) - 50));
}
.pie-right::before {
    right: 100%;
    transform-origin: right;
    transform: rotate(calc(3.6deg * var(--percent)));
}
.pie-right::after {
    /* 右半区覆盖层后50%进度显示 */
    opacity: calc(99999 * (var(--percent) - 50));
}

拿饼图进度80%举例说明:

<div style="--percent: 80;">
   <div class="pie-left"></div>
   <div class="pie-right"></div>
</div>

此时 --percent 是80,于是 calc(99999 * (var(--percent) - 50)) 的计算结果就是 99999 * 30 ,远远大于 1 ,因此此时 pie-right::after ,也就是右半区覆盖层一直处于显示状态,也就是右半圆一直是满的,左半圈只要安心旋转即可。

opacity 的这种边界特性不仅可智能控制元素显隐,还可以智能控制色彩的显示,我博客铁粉应该还记得我之前写过一篇文章做过介绍:“ CSS前景背景自动配色技术简介 ”,非常推荐大家看看。

如果我们静态饼图效果都能自由控制,那实现动画更不在话下,您可以狠狠地点击这里:饼图图形与动画demo

底部还有3D原理示意。

六、动画:打点

实现类似下图的打点效果:

AVV3Y3.gif

这种效果对于文字loading提示很有用,例如QQ登录时候的提示:

yYFf2yb.png!web

如果模拟这种打点效果呢?

最简单的方法就是直接使用 content 生成,如下:

正在加载中<dot></dot>
dot::before {
    content: '...';
    position: absolute;
    animation: dot2 3s infinite step-start both;
}
dot:after {
    content: '...';
    color: transparent;
}
@keyframes dot2 {
    33% { content: '.'; }
    66% { content: '..'; }
}

不过这个方法IE和Safari浏览器并不支持。

这里分享一个我所知道的最佳实践:

正在加载中<dot></dot>
dot {
    display: inline-block;
    height: 1em; line-height: 1;
    text-align: left;
    vertical-align: -.25ex;
    overflow: hidden;
}
dot::before {
    display: block;
    content: '...\A..\A.';
    white-space: pre-wrap;
    animation: dot1 3s infinite step-start both;
}
@keyframes dot1 {
    33% { transform: translateY(-2em); }
    66% { transform: translateY(-1em); }
}

使用 \A 让打点字符,换行通过控制垂直位置,实现点点点效果,只要是支持CSS animation 的浏览器都支持这种打点效果。

更深入内容可以参见这篇文章:“ CSS content换行实现字符点点点loading效果

七、动画:流动

这里有一个彩条水平流动的效果:

如果你来实现,你会如何实现?

如果按照我们传统的思路,我们会使用CSS background 绘制一个200%尺寸的渐变,然后使用 background-position 动画控制流动,因为CSS animation 不支持 background-image

那有没有更简单的方法实现呢?

有!其实很简单,下面这几行CSS即可,通俗易懂:

.flow-colorful {
    max-width: 600px;
    height: 150px;
    background: linear-gradient(to right, red, orange, yellow, green, cyan, blue, purple);
    animation: hue 6s linear infinite;
}
@keyframes hue {
    from { filter: hue-rotate(0deg); }
    to   { filter: hue-rotate(360deg); }
}

也就是所谓的颜色水平流动,只是视觉上的假象,我们其实只需要让我们的图形色调发生变化,就会自然而然在视觉上产生水平流动的效果,这样的时间要比 background-position 动画控制要简单的多。

其他流动动画

本次分享还展示了其他两个流动相关动画,一个是条纹记录条:

源码参见这里:斜纹进度条demo

还有一个是波浪线动画:

YbqE3m2.gif

这个有专门写文章介绍,参见这里:“ CSS实现文字下面波浪线动画效果 ”,展示了两种不同的实现方法。

八、行为:滚动指示器

效果如下GIF录屏,注意观察上边缘:

vumq6ze.gif

纯CSS实现指示网页的滚动进度。

这个创意实现我前两天专门写了文章做介绍,详见这里“ 更好的纯CSS滚动指示器技术实现 ”。

长久以来业界所提到的滚动指示器实现都是有致命缺陷的,因此在实际项目中几乎没有任何实用价值,这里借助一些CSS新特性进行了改造升级,使这种CSS技术可以在项目中使用,有兴趣可以了解下,这里就不重复展开说明了。

九、行为:视差滚动

纯CSS实现视差滚动效果,如下GIF图所示(434K,点击播放):

qArui2V.png!web

借助CSS 3D transform变换中的 perspective 视角实现。

.container {
    /* 滚动容器 */
    perspective: 1px; 
    padding: 0; height: calc(100vh - 300px); overflow: auto;
}
.box {
    /* 视差元素的父级需要3D视角 */
    height: 1280px;
    transform-style: preserve-3d;
    position: relative;
}
.background {
    /* 滚动比较慢的背景元素 */
    position: absolute; left: 50%;
    transform: translate3D(-50%, -120px, -1px) scale(2);
}

视角示意图如下:

v2myEvm.png!web

更详细深入的介绍可以参见这篇文章:“ 纯CSS实现视差滚动效果

这里就不重复说明了。

十、行为:分栏宽度拉伸

纯CSS实现如下GIF图所示的多栏拉伸效果:

EjY3YjV.gif

实现原理

CSS中有一个 resize 属性,如果一个元素的 overflow 属性值不是 visible ,则通过设置 resize 属性可以拉伸这个元素尺寸。

但是,这种拉伸却有一个问题,那就是拖拽的区域太小了,就右下角那么一丢丢地方:

67zIbiB.png!web

那有什么办法可以把这个拖拽区域变大呢?

后来经过我的研究发现,resize属性的拖拽bar和滚动条的拖拽bar是一个体系里面的东西,只需要对滚动条进行自定义,就能间接设置resize bar的尺寸。

例如:

.resize-bar::-webkit-scrollbar {
    width: 200px; height: 200px;
}

此时,拉伸区域就很大了:

yiUveqy.png!web

接下来做的事情就是把这个拖拽区域藏在某一栏布局的后面,然后透出部分宽度可以用来拖拽,如下图所示:

bmaM3mQ.png!web

最后,我们的左右分栏采用自适应布局就能实现我们想要的效果。

您可以狠狠地点击这里: 纯CSS实现分栏宽度拉伸demo

十一、完整实例以及分享PPT

“CSS创意与视觉表现”有完整的配套demo页面(上面展示的都是分散的),这里是完整的页面: CSS创意与视觉表现完整demo

分享PPT参见这里:

链接: https://share.weiyun.com/52PfXDZ 密码:vmpevj

以上~

EvINneJ.png!web

本文为原创文章,欢迎分享,勿全文转载,如果内容你实在喜欢,可以加入收藏夹,永不过期,而且还会及时更新知识点以及修正错误,阅读体验也更好。

本文地址: https://www.zhangxinxu.com/wordpress/?p=8708

(本篇完)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK