你值得收藏的66个实用的css开发技巧之行为技巧
在上篇文章《你值得收藏的 66 个实用的 css 开发技巧之布局技巧》我们讲了 Layout Skill 布局技巧知识,本篇文章接着为大家讲有关 Behavior Skill 行为技巧知识,赶紧搬好小板凳坐下学习起来。
Behavior Skill
使用 overflow-scrolling 支持弹性滚动
要点:iOS 页面非 body 元素的滚动操作会非常卡(Android 不会出现此情况),通过 overflow-scrolling:touch 调用 Safari 原生滚动来支持弹性滚动,增加页面滚动的流畅度
场景:iOS 页面滚动
兼容:iOS 自带-webkit-overflow-scrolling
实例代码:
body { -webkit-overflow-scrolling: touch; } .elem { overflow: auto; }
使用 transform 启动 GPU 硬件加速
要点:有时执行动画可能会导致页面卡顿,可在特定元素中使用硬件加速来避免这个问题
场景:动画元素(绝对定位、同级中超过 6 个以上使用动画)
兼容:transform
实例代码:
.elem { transform: translate3d(0, 0, 0); /* translateZ(0)亦可 */ }
使用 attr()抓取 data-*
要点:在标签上自定义属性 data-*,通过 attr()获取其内容赋值到 content 上
场景:提示框
兼容:data-*、attr()
实例代码:
HTML
<div class="bruce flex-ct-y"> <a class="tooltips" href="https://www.baidu.com" data-msg="Hello World">提示框</a> <a class="tooltips" href="https://www.baidu.com"></a> </div>
CSS
.tooltips { position: relative; margin-top: 10px; padding: 0 20px; border-radius: 10px; height: 40px; background-color: $purple; line-height: 40px; color: #fff; &::after { position: absolute; left: 0; top: 0; border-radius: 5px; width: 100%; height: 100%; background-color: rgba(#000, .5); opacity: 0; text-align: center; font-size: 12px; content: attr(data-msg); transition: all 300ms; } &:first-child { margin-top: 0; } &:hover::after { left: calc(100% + 20px); opacity: 1; } &[href]:empty::before { content: attr(href); } &[href]:empty:hover::after { display: none; } }
效果展示:
使用:valid 和:invalid 校验表单
要点:使用伪类:valid 和:invalid 配合 pattern 校验表单输入的内容
场景:表单校验
兼容:pattern、:valid、:invalid
实例代码:
HTML
<div class="bruce flex-ct-x"> <form class="form-validation"> <div> <label>名字</label> <input type="text" placeholder="请输入你的名字(1 到 10 个中文)" pattern="^[\u4e00-\u9fa5]{1,10}$" required> </div> <div> <label>手机</label> <input type="text" placeholder="请输入你的手机" pattern="^1[3456789]\d{9}$" required> </div> <div> <label>简介</label> <textarea required></textarea> </div> </form> </div>
CSS
.form-validation { width: 500px; div { margin-top: 10px; &:first-child { margin-top: 0; } } label { display: block; padding-bottom: 5px; font-weight: bold; font-size: 16px; } input, textarea { display: block; padding: 0 20px; outline: none; border: 1px solid #ccc; width: 100%; height: 40px; caret-color: $blue; transition: all 300ms; &:valid { border-color: $green; box-shadow: inset 5px 0 0 $green; } &:invalid { border-color: $red; box-shadow: inset 5px 0 0 $red; } } textarea { height: 122px; resize: none; line-height: 30px; font-size: 16px; } }
效果展示:
使用 pointer-events 禁用事件触发
要点:通过 pointer-events:none 禁用事件触发(默认事件、冒泡事件、鼠标事件、键盘事件等),相当于<button>的 disabled
场景:限时点击按钮(发送验证码倒计时)、事件冒泡禁用(多个元素重叠且自带事件、a 标签跳转)
兼容:pointer-events
实例代码:
HTML
<div class="bruce flex-ct-x"> <a class="disabled-trigger" href="https://mybj123.com">点我</a> </div>
CSS
.disabled-trigger { padding: 0 20px; border-radius: 10px; height: 40px; background-color: $purple; pointer-events: none; line-height: 40px; color: #fff; }
JS
document.getElementsByClassName("disabled-trigger")[0].addEventListener("click", () => alert("Hello World"));
效果展示:
使用+或~美化选项框
要点:
场景:选项框美化、选中项增加选中样式
兼容:+、~
实例代码:
HTML
<div class="bruce flex-ct-x"> <ul class="beauty-selection"> <li> <input type="radio" name="radioName" id="fed-engineer" hidden> <label for="fed-engineer"></label> <span>前端工程师</span> </li> <li> <input type="radio" name="radioName" id="bed-engineer" hidden> <label for="bed-engineer"></label> <span>后端工程师</span> </li> <li> <input type="radio" name="radioName" id="fsd-engineer" hidden> <label for="fsd-engineer"></label> <span>全栈工程师</span> </li> </ul> </div>
CSS
.beauty-selection { display: flex; li { display: flex; align-items: center; margin-left: 20px; &:first-child { margin-left: 0; } } input:checked + label { background-color: $orange; } label { margin-right: 5px; padding: 2px; border: 1px solid $orange; border-radius: 100%; width: 18px; height: 18px; background-clip: content-box; cursor: pointer; transition: all 300ms; &:hover { border-color: $blue; background-color: $blue; box-shadow: 0 0 7px $blue; } } span { font-size: 16px; } }
效果展示:
使用:focus-within 分发冒泡响应
要点:表单控件触发 focus 和 blur 事件后往父元素进行冒泡,在父元素上通过:focus-within 捕获该冒泡事件来设置样式
场景:登录注册弹框、表单校验、离屏导航、导航切换
兼容::focus-within、:placeholder-shown
实例代码:
HTML
<div class="bruce flex-ct-x"> <form class="bubble-distribution"> <h3>注册</h3> <div class="accout"> <input type="text" placeholder="请输入手机或邮箱" pattern="^1[3456789]\d{9}$|^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$" required> <img src="https://b-gold-cdn.xitu.io/v3/static/img/greeting.1415c1c.png"> </div> <div class="password"> <input type="password" placeholder="请输入密码(6 到 20 位字符)" pattern="^[\dA-Za-z_]{6,20}$" required> <img src="https://b-gold-cdn.xitu.io/v3/static/img/blindfold.58ce423.png"> </div> <div class="code"> <input type="text" placeholder="请输入邀请码(6 位数字)" pattern="^[\d]{6}$" maxLength="6" required> <button type="button">查询</button> <img src="https://b-gold-cdn.xitu.io/v3/static/img/greeting.1415c1c.png"> </div> <img src="https://b-gold-cdn.xitu.io/v3/static/img/normal.0447fe9.png"> <ul> <li> <input type="radio" name="sex" id="male"> <label for="male">Boy</label> </li> <li> <input type="radio" name="sex" id="female"> <label for="female">Girl</label> </li> </ul> <button type="button">注册</button> </form> </div>
CSS
.bruce { background-color: #999; } .bubble-distribution { position: relative; margin-top: 50px; padding: 25px; border-radius: 2px; width: 320px; background-color: #fff; h3 { font-weight: bold; font-size: 16px; color: #333; } div { margin-top: 10px; } img { position: absolute; left: 50%; bottom: 100%; margin: 0 0 -20px -60px; width: 120px; } ul { display: flex; justify-content: space-between; align-items: center; margin-top: 10px; height: 30px; line-height: 30px; } li { position: relative; width: 45%; transition: all 300ms; &:focus-within { background: linear-gradient(90deg, $blue 50%, transparent 0) repeat-x, linear-gradient(90deg, $blue 50%, transparent 0) repeat-x, linear-gradient(0deg, $blue 50%, transparent 0) repeat-y, linear-gradient(0deg, $blue 50%, transparent 0) repeat-y; background-position: 0 0, 0 100%, 0 0, 100% 0; background-size: 8px 1px, 8px 1px, 1px 8px, 1px 8px; animation: move 500ms infinite linear; } } input[type=text], input[type=password] { padding: 10px; outline: none; border: 1px solid #e9e9e9; border-radius: 2px; width: 100%; height: 40px; transition: all 300ms; &:focus:valid { border-color: $blue; } &:focus:invalid { border-color: $red; } } input[type=radio] { position: absolute; width: 0; height: 0; &:checked + label { border: 3px solid transparent; background-color: $blue; color: #fff; } } label { display: block; border-bottom: 1px solid #ccc; width: 100%; background-clip: padding-box; cursor: pointer; text-align: center; transition: all 300ms; } button { overflow: hidden; margin-top: 10px; outline: none; border: none; border-radius: 2px; width: 100%; height: 40px; background-color: $blue; cursor: pointer; color: #fff; transition: all 300ms; } } .accout, .password, .code { img { display: none; margin-bottom: -27px; } &:focus-within { img { display: block; } & ~ img { display: none; } } } .code { display: flex; justify-content: space-between; button { margin-top: 0; } input { &:not(:placeholder-shown) { width: 70%; & + button { width: 25%; } } &:placeholder-shown { width: 100%; & + button { width: 0; opacity: 0; } } } } @keyframes move { to { background-position: 6% 0, -6% 100%, 0 -6%, 100% 6%; } }
效果展示:
使用:hover 描绘鼠标跟随
要点:将整个页面等比划分成小的单元格,每个单元格监听:hover,通过:hover 触发单元格的样式变化来描绘鼠标运动轨迹
场景:鼠标跟随轨迹、水波纹、怪圈
兼容::hover
实例代码:点击运行
效果展示:
使用 max-height 切换自动高度
要点:通过 max-height 定义收起的最小高度和展开的最大高度,设置两者间的过渡切换
场景:隐藏式子导航栏、悬浮式折叠面板
兼容:max-height
实例代码:
HTML
<div class="bruce flex-ct-x"> <ul class="auto-height"> <li> <h3>列表 1</h3> <p>内容 1<br>内容 2<br>内容 3<br>内容 4</p> </li> <li> <h3>列表 2</h3> <p>内容 1<br>内容 2<br>内容 3<br>内容 4</p> </li> <li> <h3>列表 3</h3> <p>内容 1<br>内容 2<br>内容 3<br>内容 4</p> </li> </ul> </div>
CSS
.auto-height { width: 300px; li { margin-top: 5px; cursor: pointer; &:first-child { margin-top: 0; } &:hover p { border-bottom-width: 1px; max-height: 600px; } } h3 { padding: 0 20px; height: 40px; background-color: $red; cursor: pointer; line-height: 40px; font-size: 16px; color: #fff; } p { overflow: hidden; padding: 0 20px; border: 1px solid $red; border-top: none; border-bottom-width: 0; max-height: 0; line-height: 30px; transition: all 500ms; } }
效果展示:
使用 transform 模拟视差滚动
要点:通过 background-attachment:fixed 或 transform 让多层背景以不同的速度移动,形成立体的运动效果
场景:页面滚动、视差滚动文字阴影、视差滚动文字虚影
兼容:background-attachment、transform
实例代码:
HTML
<div class="bruce"> <ul class="parallax-scrolling"> <li>translateZ(-1px)</li> <li>translateZ(-2px)</li> <li>translateZ(-3px)</li> </ul> <p>内容</p> <ul class="parallax-scrolling"> <li>translateZ(-1px)</li> <li>translateZ(-2px)</li> <li>translateZ(-3px)</li> </ul> </div>
CSS
$bg: "/static/codepen/bg.jpg"; .bruce { overflow: auto; perspective: 1px; transform-style: preserve-3d; p { height: 300px; line-height: 300px; text-align: center; font-size: 20px; color: $red; } } .parallax-scrolling { display: flex; justify-content: center; align-items: center; height: 1000px; background: url($bg) no-repeat center fixed; li { width: 500px; text-align: center; font-weight: bold; font-size: 60px; &:nth-child(1) { color: $red; transform: translateZ(-1px); } &:nth-child(2) { color: $blue; transform: translateZ(-2px); } &:nth-child(3) { color: $green; transform: translateZ(-3px); } } }
效果展示:
使用 animation-delay 保留动画起始帧
要点:通过 transform-delay 或 animation-delay 设置负值时延保留动画起始帧,让动画进入页面不用等待即可运行
场景:开场动画
兼容:transform、animation
实例代码:
HTML
<div class="bruce flex-ct-x"> <ul class="initial-keyframe"> <li></li> <li></li> <li></li> </ul> </div>
CSS
.initial-keyframe { position: relative; width: 100px; height: 100px; li { position: absolute; border-radius: 100%; width: 100%; height: 100%; background-color: $green; transform: rotate(0) translate(-80px, 0); animation: rotate 3s linear infinite; &:nth-child(2) { animation-delay: -1s; } &:nth-child(3) { animation-delay: -2s; } } } @keyframes rotate { to { transform: rotate(1turn) translate(-80px, 0); } }
效果展示:
使用 resize 拉伸分栏
要点:通过 resize 设置横向自由拉伸来调整目标元素的宽度
场景:富文本编辑器、分栏阅读
兼容:resize
实例代码:
HTML
<div class="bruce flex-ct-x"> <div class="stretching-column"> <div class="left"> <div class="resize-bar"></div> <div class="resize-line"></div> <div class="resize-text">ABCDEFGHIJKLMNOPQRSTUVWXYZ</div> </div> <div class="right">ABCDEFGHIJKLMNOPQRSTUVWXYZ</div> </div> </div>
CSS
.stretching-column { overflow: hidden; border: 1px solid $blue; width: 600px; height: 300px; line-height: 20px; font-size: 16px; color: $orange; .left { overflow: hidden; float: left; position: relative; height: 100%; } .right { overflow: hidden; padding: 10px; height: 100%; background-color: #f0f0f0; word-break: break-all; } } .resize-bar { overflow: scroll; width: 200px; height: 100%; opacity: 0; resize: horizontal; &::-webkit-scrollbar { width: 200px; height: 100%; } &:hover, &:active { & ~ .resize-line { border-left: 1px dashed $blue; } } } .resize-line { position: absolute; right: 0; top: 0; bottom: 0; border-left: 1px solid #ccc; border-right: 2px solid #f0f0f0; pointer-events: none; } .resize-text { overflow-x: hidden; position: absolute; left: 0; right: 5px; top: 0; bottom: 0; padding: 10px; word-break: break-all; }
效果展示:
未完待续。。。请看《你值得收藏的 66 个实用的 css 开发技巧之色彩技巧》
码云笔记 » 你值得收藏的66个实用的css开发技巧之行为技巧