本文来自「心谭博客」的 《动画设计·输入框特效》,更多文章放在了 Github欢迎交流和Starcss
划线动态:html
动态边框:git
:before
和 :after
伪元素指定了一个元素文档树内容以前和以后的内容。因为input
标签不是可插入内容的容器。因此这里下划线没法经过伪元素来实现。须要借助其余 dom 节点。github
<div> <input type="text" /> <span></span> </div>
包裹在外的父元素div
应该设置成inline-block
,不然宽度会满屏。dom
div { position: relative; display: inline-block; }
input
标签须要禁用默认样式:字体
input { outline: none; border: none; background: #fafafa; }
span
标签实现「左进右出」的动态,须要改变transform-origin
方向。为了不回流重绘,经过scaleX
来实现宽度变化的视觉效果。动画
input ~ span { position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background-color: #262626; transform: scaleX(0); transform-origin: right center; transition: transform 0.3s ease-in-out; } input:focus ~ span { transform: scaleX(1); transform-origin: left center; }
如动态图所示,有 4 条边框。因此除了input
元素外,还须要准备其余 4 个 dom。为了方便定位,嵌套一个父级元素。spa
<div> <input type="text"> <span class="bottom"></span> <span class="right"></span> <span class="top"></span> <span> </div>
和「划线动态」相似,input 和 div 的样式基本同样。为了好看,改一下 padding 属性。设计
div { position: relative; display: inline-block; padding: 3px; } input { outline: none; border: none; background: #fafafa; padding: 3px; }
对于其余 4 个 span 元素,它们的位置属性,动画属性,以及颜色都是相同的:code
.bottom, .top, .left, .right { position: absolute; background-color: #262626; transition: transform 0.1s ease-in-out; }
对于.bottom 和.top,它们的变化方向是水平;对于.left 和.right,它们的变化方向是垂直。
.bottom, .top { left: 0; right: 0; height: 1px; transform: scaleX(0); } .left, .right { top: 0; bottom: 0; width: 1px; transform: scaleY(0); }
下面就是处理延时的特效。动态图中,动画按照下、右、上、左的顺序依次变化。借助的是transition-delay
属性,来实现动画延迟。
.bottom { bottom: 0; transform-origin: right center; } input:focus ~ .bottom { transform: scaleX(1); transform-origin: left center; } .top { top: 0; transform-origin: left center; transition-delay: 0.2s; } input:focus ~ .top { transform: scaleX(1); transform-origin: right center; } .right { transform-origin: top center; right: 0; transition-delay: 0.1s; } input:focus ~ .right { transform: scaleY(1); transform-origin: bottom center; } .left { left: 0; transform-origin: bottom center; transition-delay: 0.3s; } input:focus ~ .left { transform: scaleY(1); transform-origin: top center; }