CSS 创意构想 - Part 1 / 2♀?♀背景本人一直对 CSS 很感兴趣,刚好我们团队有一位擅长CSS的大佬:COCO。于是我找到他, 建议做一期关于CSS的分享, 于是就有了♀?♀。分享的内容很棒,里面有很多技巧, 有的很实用, 有的很华丽。 听完之后, 我觉得十分受用, 就想结合自己的一些理解,再次整理一番, 加深印象, 二次吸收, 所以就有了今天的文章。满满的干货,也分享给大家, 希望对大家有所启发。PS: 文章内示例均来自coco的博客, 感兴趣的可以移步到这里。布局平行四边形先抛一个问题, 如何实现平行四边形布局效果?transform ?叠加三角形 ?仅仅实现形状的话, 上面两种方式都是可以的。但是, 如果图形内部还有文字,需要正常排布,transform 、叠加三角形 都不可行。那怎么办呢? 答案就是: shape-outside.shape-outside定义了一个可以是非矩形的形状,相邻的内联内容应围绕该形状进行排版clip-pathCSS 属性可以创建一个只有元素的部分区域可以显示的剪切区域clip-path 语法:{ clip-path: circle(50px at 0 100px); clip-path: ellipse(); clip-path: inset(10px 10px 10px 10px); clip-path: polygon(10px 10px, 20px 20px, 30px 30px);}图文混排 Demo:https://codepen.io/Chokcoco/p...CSS Shapes Demo:https://codepen.io/Chokcoco/p...一个适用的场景: 适配 iPhone X刘海头镂空使用阴影,可以非常简单的模拟遮罩效果, 并且,圆角也是没有问题的。box-shadow: 0 0 0 100vmax rgba(0, 0, 0, .5);垂直居中抛出个问题: 最快的水平垂直居中方法是什么?你首先想到的是不是: flex, center, center ?其实margin也可以:<div class="g-container"> <div class="g-box"></div> </div>.g-container { display: flex; } .g-box { margin: auto; }原理:在 flex 格式化上下文中,设置了 margin: auto 的元素,在通过 justify-content 和 align-self 进行对齐之前,任何正处于空闲的空间都会分配到该方向的自动 margin 中去。Live Demo:https://codepen.io/Chokcoco/p...还有这种常见的左右布局, 也可以巧用margin来实现:<ul class="g-nav"> <li>导航A</li> <li>导航B</li> <li>导航C</li> <li>导航D</li> <li class="g-login">登陆</li> <li>注册</li></ul>.g-nav { display: flex; } .g-login { margin-left: auto; }自动页脚我们经常会遇到需要放置在页脚的元素, 高度超过一屏时, 自动顶下去:这种效果也有很多种实现方式, 巧用margin可以快速实现:<div class="g-container"> <div class="g-real-box"> ... </div> <div class="g-footer"></div></div>.g-container { height: 100vh; display: flex; flex-direction: column;}.g-footer { margin-top: auto; flex-shrink: 0; height: 30px; background: deeppink;}阴影阴影分为外阴影和内阴影(inset)阴影可以是多重阴影阴影可以进行动画使用阴影可以轻松得到图片本身,并且任意改变颜色及大小.比如, 把发散半径设置为0: code:div { width: 80px; height: 80px; background: #fff; box-shadow: 80px 80px 0 0 yellow, -80px 80px 0 10px green;}使用阴影模拟多重边框代码实现:{ background: #fff; box-shadow: 0 0 0 2px red, 0 0 0 4px orange, 0 0 0 6px yellow, 0 0 0 8px green, 0 0 0 10px cyan;}使用阴影画出一朵云:其实是用不同的阴影叠加而成:.bgShadowCloud { width: 100px; height: 100px; margin: 50px auto!important; background: #fff; border-radius: 50%; box-shadow: 120px 0px 0 -10px #795548, 95px 20px 0 0px #607D8B, 30px 30px 0 -10px green, 90px -20px 0 0px #FFC107, 40px -40px 0 0px #2196F3; animation: change 6s infinite;}内阴影模拟圆月变月牙:代码实现:动态效果:https://codepen.io/Chokcoco/p...特殊阴影有的时候,CSS 的 box-shadow 无法很好去实现一些特殊阴影,可以利用一些小技巧进行模拟。长阴影借助两个伪元素的 transform: skew() 变换伪元素背景从实色到透明色的背景色变化实现代码:<div class="bgLongShadow"></div>.bgLongShadow { position: relative; width: 268px; height: 269px; background: #fff; margin: 20px auto!important; background-size: contain; background-position: center; background-repeat: no-repeat;}.bgLongShadow::before { transform-origin: 0 50%; transform: translate(100%, 0) skewY(45deg) scaleX(.3); background: linear-gradient(90deg, rgba(255, 255, 255, .3), transparent); animation: shadowMoveY 5s infinite linear alternate;}.bgLongShadow::before, .bgLongShadow::after { content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; z-index: -1;}立体投影以第一个为例, 其实是用了一点障眼法: 代码实现:<div class="bgSolidShadow"></div>div.bgSolidShadow { position: relative; width: 600px; height: 100px; margin: 50px auto; background: hsl(48, 100%, 50%); border-radius: 20px; box-shadow: 0 0 5px 2px hsl(48, 100%, 45%); cursor: pointer;}.bgSolidShadow::before { content: ""; position: absolute; top: 40%; left: 5%; right: 5%; bottom: 0; border-radius: 10px; transform: translate(0, -15%) rotate(-2deg); transform-origin: center center; box-shadow: 0 0 10px 12px hsl(0, 0%, 0%); z-index: -1;}彩色阴影其实是借助了高斯模糊滤镜{ filter: blur(10px) brightness(90%) opacity(.85);}整体阴影看下图:这个的阴影如何实现? box-shadow ?先看一下DOM结构:<div class="flecha"></div>// 三角.flecha { position: relative; margin: 50px auto!important; width: 0; height: 0; border-top: 90px solid transparent!important; border-right: 90px solid #FFC000!important; transform: rotate(10deg); box-shadow: 0px 0px 10px rgba(255, 220, 0, .8);}// 尾巴.flecha:after { content: ""; position: absolute; border: 0 solid transparent; border-top: 30px solid #FFC000!important; border-radius: 200px 0 0 0!important; top: -119px; left: -98px; width: 120px; height: 120px; transform: rotate(45deg);}此时的效果:加上box-shadow:{ box-shadow: 0px 0px 10px rgba(255, 220, 0, .8);}可见是不行的, 那该怎么办呢?答案是: 使用 drop-shadow{ filter: drop-shadow(0px 0px 10px rgba(255, 220, 0, .8)); }完美~利用drop-shadow单标签实现♀?♀ LOGO代码实现:div { position: relative; width: 37px; height: 218px; background: #fff; filter:drop-shadow(-10px -10px 0 #24f6f0) contrast(150%) brightness(110%); box-shadow: 11.6px 10px 0 0 #fe2d52; &::before { .... filter: drop-shadow(16px 0px 0 #fe2d52); } &::after { .... filter:drop-shadow(14px 0 0 #fe2d52); }}Live demo:https://codepen.io/Chokcoco/p...十分酷炫~使用阴影的扩散半径实现内切圆角Live Demo:https://codepen.io/Chokcoco/p...渐变渐变分为线性渐变、径向渐变、角向渐变(圆锥渐变)渐变可以控制各种角度渐变可以是多重渐变叠加渐变不能进行动画 (animation/transtion)线性渐变{ background: linear-gradient(45deg, #fff, #ffcc00); }合理控制颜色百分比,可以让渐变颜色变成实色{ background: linear-gradient(45deg, #fff 50%, #ffcc00 50%);}某一段的颜色可以是透明的{ background: linear-gradient(45deg, #fff 33%, transparent 33%, transparent 66%, #ffcc00 66% ); }背景重复可以利用 repeating-linear-gradient、repeating-radial-gradient 进行重复也可以利用 background-size 和 background-repeat 进行重复控制背景动画可以不去改变颜色本身,而是利用其它元素进行动画transform、filter、mix-blend-mode 等等比如, 实现一个背景色持续变化的元素:设置overflow: hidden 截断多余的部分, 使用动画不断改变背景块的位置, 即可实现效果。<div class="g-linear-gradient-5"></div>.g-linear-gradient-5 { width: 80px; height: 80px; border: 2px solid #fff!important; position: relative; overflow: hidden;}.g-linear-gradient-5::before { content: ""; position: absolute; top: -100%; left: -100%; bottom: -100%; right: -100%; background: linear-gradient(45deg, #ffc700 0%, #e91e1e 50%, #6f27b0 100%); background-size: 100% 100%; animation: bgposition 8s infinite linear alternate; z-index: -1;}利用透明色,实现切角{ background: linear-gradient(135deg, transparent 15px, #ffcc00 0) top left, linear-gradient(-135deg, transparent 15px, #ffcc00 0) top right, linear-gradient(-45deg, transparent 15px, #ffcc00 0) bottom right, linear-gradient(45deg, transparent 15px, #ffcc00 0) bottom left; background-size: 60% 60%; background-repeat: no-repeat;}实现进度条效果利用重复线性渐变 + transform 实现进度条效果https://codepen.io/Chokcoco/p...实现优惠券的边纹{ background-image: radial-gradient(circle at 1px 8px, transparent 6px, #ffcc00 6px, #ffcc00 0px), radial-gradient(circle at 199px 8px, transparent 6px, #ffcc00 6px, #ffcc00 0px); background-size: 200px 18px; background-position: 0 0, 200px 0; background-repeat-x: no-repeat;}多种渐变的组合多种渐变的组合,还能创造出各种有意思的图形, 比如:https://codepen.io/Chokcoco/p...实现气泡按钮点击效果使用了background-position+background-sizehttps://codepen.io/Chokcoco/p...圆锥渐变linear-gradient 线性渐变的方向是一条直线,可以是任何角度radial-gradient 径向渐变是从圆心点以椭圆形状向外扩散起始点是图形中心,然后以顺时针方向绕中心实现渐变效果{ background: conic-gradient(deeppink, yellowgreen); }实现颜色表盘{ background: conic-gradient(red, #ff4d00, #ff9900, #ffe600, #ccff00, #80ff00, #33ff00, #00ff1a, #00ff66, #00ffb3, cyan, #00b3ff, #0066ff, #001aff, #3300ff, #8000ff, #cc00ff, #ff00e6, #ff0099, #ff004d, red); }又或者是这种积分表盘:https://codepen.io/alphardex/...结尾文章已经很长, 为了阅读上的方便, 剩余的一部分将会在下一篇文章里。剩余内容包括:混合模式滤镜伪元素波浪效果滚动指示器滚动视差部分示例缺少代码, 需要逐个准备, 比较耗时。持续更新, 敬请期待,关注我如果你觉得这篇内容对你挺有启发,那就关注我吧~更多精彩:聊聊 ESM、Bundleless 、Vite 、Snowpack记一次 「 无限列表 」滚动优化「 面试三板斧 」之 代码分割(上)「 面试三板斧 」之缓存 (上)「 面试三板斧 」之缓存 (下)「 面试三板斧 」之 HTTP (上)「 面试三板斧 」之 HTTP (下)「 面试三板斧 」之 ?this
