下划线绘制
鼠标悬停时下划线从左到右绘制展开,离开时反向收回,经典的导航链接交互效果。
交互预览
动效定义与代码
{
"slug": "underline-draw",
"name": "下划线绘制",
"nameEn": "Underline Draw",
"description": "鼠标悬停时下划线从左到右绘制展开,离开时反向收回,经典的导航链接交互效果。",
"descriptionEn": "Underline draws from left to right on hover and retracts on leave. A classic navigation link interaction.",
"category": "hover",
"tags": [
"hover",
"underline",
"draw",
"link",
"navigation"
],
"trigger": "on-hover",
"difficulty": "beginner",
"duration": "300ms",
"easing": "cubic-bezier(0.4, 0, 0.2, 1)",
"cssProperties": [
"transform",
"transform-origin"
],
"isGPUAccelerated": true,
"previewBg": "light",
"keywords": [
"underline",
"draw",
"hover link",
"navigation",
"text decoration",
"line animation"
],
"useCases": [
"Navigation link hover",
"Footer link interaction",
"Text link emphasis",
"Menu item hover state"
],
"relatedAnimations": [
"hover-glow",
"hover-lift"
],
"recommendedStyles": [
"minimalist-flat",
"editorial",
"corporate-clean"
],
"codeSnippets": [
{
"label": "CSS Keyframes",
"language": "css",
"code": ".underline-draw {\n position: relative;\n display: inline-block;\n}\n\n.underline-draw::after {\n content: \"\";\n position: absolute;\n left: 0;\n bottom: -2px;\n width: 100%;\n height: 2px;\n background: currentColor;\n transform: scaleX(0);\n transform-origin: right;\n transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.underline-draw:hover::after {\n transform: scaleX(1);\n transform-origin: left;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .underline-draw::after {\n transition: none;\n }\n}"
},
{
"label": "Tailwind CSS",
"language": "css",
"code": "@utility underline-draw {\n position: relative;\n display: inline-block;\n\n &::after {\n content: \"\";\n position: absolute;\n left: 0;\n bottom: -2px;\n width: 100%;\n height: 2px;\n background: currentColor;\n transform: scaleX(0);\n transform-origin: right;\n transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n &:hover::after {\n transform: scaleX(1);\n transform-origin: left;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .underline-draw::after {\n transition: none;\n }\n}"
},
{
"label": "Framer Motion",
"language": "tsx",
"code": "import { motion } from \"framer-motion\";\n\nfunction UnderlineLink({ children }: { children: React.ReactNode }) {\n return (\n <span className=\"relative inline-block\">\n {children}\n <motion.span\n className=\"absolute left-0 -bottom-0.5 h-0.5 w-full bg-current\"\n initial={{ scaleX: 0, originX: 1 }}\n whileHover={{ scaleX: 1, originX: 0 }}\n transition={{ duration: 0.3, ease: [0.4, 0, 0.2, 1] }}\n />\n </span>\n );\n}"
}
]
}