新网站的站点验证,比较好的源码网站,网投网站怎么做,适合设计师的网站编辑软件目录
一、弧形边框选项卡
二、零宽字符
三、目录滚动时自动高亮
四、高亮关键字
五、文字描边
六、按钮边框的旋转动画
七、视频文字特效
八、立体文字特效让文字立起来
九、文字连续光影特效
十、重复渐变的边框
十一、磨砂玻璃效果
十二、FLIP动画
一、弧形边框…目录
一、弧形边框选项卡
二、零宽字符
三、目录滚动时自动高亮
四、高亮关键字
五、文字描边
六、按钮边框的旋转动画
七、视频文字特效
八、立体文字特效让文字立起来
九、文字连续光影特效
十、重复渐变的边框
十一、磨砂玻璃效果
十二、FLIP动画
一、弧形边框选项卡 style.tab {width: 150px;height: 40px;color: #fff;text-align: center;line-height: 40px;margin: 0 auto;background: #ed6a5e;border-radius: 10px 10px 0 0;position: relative;transform: perspective(30px) rotateX(13deg);transform-origin: center bottom; /* 以tab最下方的线为中心进行旋转 */}.tab::before,.tab::after {content: ;position: absolute;width: 10px;height: 10px;bottom: 0;background: #000;}.tab::before {left: -10px;background: radial-gradient(circle at 0 0,transparent 10px,#ed6a5e 10px); /* 左边以左上角为圆点进行径向渐变 */}.tab::after {right: -10px;background: radial-gradient(circle at 100% 0,transparent 10px,#ed6a5e 10px); /* 右边以右上角为圆点进行径向渐变 */}/style
二、零宽字符 script// 判断字符串中是否包含零宽字符function containsZeroWidthCharacter(str) {// 正则表达式匹配零宽字符const zeroWidthRegex /[\u200B\u200C\u200D\uFEFF]/g;return zeroWidthRegex.test(str);}console.log(containsZeroWidthCharacter(Hello\u200B World)); // trueconsole.log(containsZeroWidthCharacter(Hello World)); // false/script
常见的零宽字符包括 1、零宽空格【UnicodeU200B】 这是一个没有宽度的空格可以在两个字符之间插入但不会在视觉上产生间隔。 2、零宽非连接符【UnicodeU200C】 用于阻止字符连接。在阿拉伯语或印地语中用来控制哪些字符应该连接哪些不应连接。 3、零宽连接符【UnicodeU200D】 用于强制某些字符连接在一起这通常在一些复合字符或表情符号中起作用。与2相反 4、零宽非换行空格【UnicodeUFEFF】 用于文件中的字节顺序标记但也可以用作零宽空格的一种形式。作用是防止换行。 尽管零宽字符对用户不可见但它们会占用存储空间通常用于文本隐写、防止链接自动化处理、格式化和排版。比如文本处理时加上零宽字符可以防止文本被盗窃解码后是自己的名称。
三、目录滚动时自动高亮 stylebody {display: flex;margin: 0;}/* 左侧目录 */.sidebar {width: 250px;background-color: #333;color: white;padding: 20px;height: 100vh;position: fixed;top: 0;left: 0;overflow-y: auto;}.sidebar a {color: white;text-decoration: none;display: block;padding: 10px;margin: 5px 0;}.sidebar a:hover {background-color: #575757;}.highlight {background-color: #ffcc00; /* 高亮颜色 */}/* 右侧内容 */.content {margin-left: 280px; /* 留出左侧目录栏空间 */padding: 20px;width: calc(100% - 260px);}h1 {color: #333;}.section {margin-bottom: 30px;height: 750px;border: 1px solid yellowgreen;}.section h2 {color: #444;}/stylebodydiv classsidebar toch2目录/h2a href#section1部分 1/aa href#section2部分 2/aa href#section3部分 3/aa href#section4部分 4/a/divdiv classcontentdiv classsection idsection1h2部分 1/h2p第一部分内容。/p/divdiv classsection idsection2h2部分 2/h2p第二部分内容。/p/divdiv classsection idsection3h2部分 3/h2p第三部分内容。/p/divdiv classsection idsection4h2部分 4/h2p第四部分内容。/p/div/divscriptfunction highlight(id) {document.querySelectorAll(a.highlight).forEach((a) a.classList.remove(highlight));if (id instanceof HTMLElement) {id.classList.add(highlight);return;}if (id.startsWith(#)) {id id.substring(1);}document.querySelector(a[href#${id}]).classList.add(highlight);}const links document.querySelectorAll(.toc a[href^#]);const titles [];for (const link of links) {link.addEventListener(click, () {highlight(link.getAttribute(href).substring(1));});const url new URL(link.href);const dom document.querySelector(url.hash);if (dom) {titles.push(dom);}}function debounce(fn, delay 100) {let timer null;return function (...args) {clearTimeout(timer);timer setTimeout(() {fn.apply(this, args);}, delay);};}const scrollHandler debounce(() {const rects titles.map((title) title.getBoundingClientRect());const range 300;for (let i 0; i titles.length; i) {const title titles[i];const rect rects[i];// 标题区域在指定范围内就高亮if (rect.top 0 rect.top range) {highlight(title.id);break;}// 当前内容标题在展示视口之上并且下一个标题在展示视口之下此时高亮此标题if (rect.top 0 rects[i 1] rects[i 1].top document.documentElement.clientHeight) {highlight(title.id);break;}}}, 100);window.addEventListener(scroll, scrollHandler);/script/body
四、高亮关键字 style.highlight {color: red;font-weight: bold;}
/stylebodydivinput typetext classtxtKeyword /ul/ul/divscriptconst ul document.querySelector(ul);const txtKeyword document.querySelector(.txtKeyword);function setHTML(lists) {ul.innerHTML lists.map((l) {let cname l.cname;// 如果输入框有内容则进行高亮匹配if (txtKeyword.value) {const reg new RegExp(txtKeyword.value, ig);cname cname.replace(reg, function (key) {return span classhighlight${key}/span;});}return lispan${cname}/span/li;}).join(); // 使用 join 合并生成的 HTML 字符串}const NameLists [{ cname: 前端 },{ cname: 后端 },{ cname: 测试员 },{ cname: 运维师 },];// 筛选包含关键字的元素function filterList() {const keyword txtKeyword.value.trim();if (keyword) {const filtered NameLists.filter((item) item.cname.match(new RegExp(keyword, i)));setHTML(filtered);} else {setHTML(NameLists);}}setHTML(NameLists);// 给输入框添加监听事件以便动态更新txtKeyword.addEventListener(input, filterList);/script/body
五、文字描边
第一种text-shadow给8个方向即可但是连接处有瑕疵(见红色边缘部分) mixin text-stroke($color: #fff, $width: 1px) {text-shadow: 0 -#{$width} #{$color}, #{$width} 0 #{$color},0 #{$width} #{$color}, -#{$width} 0 #{$color}, #{$width} #{$width} #{$color},-#{$width} -#{$width} #{$color}, #{$width} -#{$width} #{$color},-#{$width} #{$width} #{$color};
}
p {font-size: 50px;font-weight: bold;include text-stroke(red, 2px);// color: transparent; 不支持文字透明
}
p {font-size: 50px;font-weight: bold;text-shadow: 0 -2px gold, 2px 0 gold, 0 2px gold, -2px 0 gold,/* 上、右、下、左 */ 2px 2px gold, -2px -2px gold, 2px -2px gold,-2px 2px gold; /* 四个对角线 */
}
第二种-webkit-text-stroke不仅边缘平滑并且支持透明 p {font-size: 50px;font-weight: bold;-webkit-text-stroke: 2px red;color: transparent; //支持文字透明position: relative;
}
// -webkit-text-stroke是居中描边原来字体变小了可以在画一层盖上去
p::after {content: attr(data-text);position: absolute;left: 0;top: 0;-webkit-text-stroke: 0;
}
六、按钮边框的旋转动画
原理在按钮层级下加一个矩形围绕按钮中心进行360度旋转多余矩形隐藏 stylebutton {width: 100px;height: 50px;color: white;outline: none;z-index: 1;border-radius: 10px;cursor: pointer;background: black;/* outline: 4px solid gold; */position: relative;overflow: hidden;}button::before {content: ;position: absolute;width: 200%;height: 200%;background: blue;z-index: -2;left: 50%;top: 50%;transform-origin: left top;/* 圆点在左上角 */animation: rotation 2s linear infinite;}button::after {content: ;position: absolute;--g: 4px;width: calc(100% - var(--g) * 2);height: calc(100% - var(--g) * 2);background: black;left: var(--g);top: var(--g);border-radius: inherit;z-index: -1;}keyframes rotation {to {transform: rotate(360deg);}}/style
七、视频文字特效 style.txt{position:absolute;inset: 0;background: #fff;display: flex;justify-content: center;align-items: center;mix-blend-mode: screen; /* 增强亮度使图像或元素显得更加明亮 */}/style
bodydiv classcontainervideo src./fire.mp4 autoplay muted/videodiv classtxt大前端/div/div
/body
八、立体文字特效让文字立起来
放大看是叠加出来的真正要做得建模 stylebody {background-color: brown;color: #fff;padding: 30px;}.text1 {font-size: 5em;text-shadow: -1px 1px #bbb, -2px 2px #bbb, -3px 3px #bbb, -4px 4px #bbb,-5px 5px #bbb, -10px 10px 3px #0008;}.text2 {font-weight: 700;position: relative;}.text2::after {content: DARKNESS;position: absolute;left: 0;top: 0;color: #000;transform: translate(-25px, 2px) scale(0.9) skew(50deg);z-index:-1;filter: blur(2px);mask:linear-gradient(transparent,#000)}/stylebodyh1 classtext1立体文字/h1h1 classtext2DARKNESS/h1/body
九、文字连续光影特效 span {color: #faebd7;animation: colorChange 1s infinite alternate;
}
keyframes colorChange {to {color: #ff0266;}
}
for $i from 1 through 7 {span:nth-child(#{$i}) {animation-delay: ($i - 1) * 0.1s;}
}
十、重复渐变的边框 style.card {width: 217px;margin: 0 auto;color: #333;line-height: 1.8;border-radius: 10px;background: repeating-linear-gradient(-45deg,#e8544d 0 10px,#fff 10px 20px,#75adf8 20px 30px,#fff 30px 40px) -20px -20px/200% 200%;padding: 5px;transition: 0.5s;}.card:hover {background-position: 0 0;}.container {background: #fff;border-radius: inherit;}/stylebodydiv classcarddiv classcontainer重复渐变的边框原理br/设置背景为重复的线性渐变。渐变角度为-45度包含四个颜色区块。/div/div/body
十一、磨砂玻璃效果 style.wrap {text-align: center;color: white;}.modal {background: rgba(255, 255, 255, 0.4); /* 半透明背景 */backdrop-filter: blur(10px); /* 模糊背景 */border-radius: 15px; /* 圆角 */padding: 40px;width: 300px;box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); /* 增加阴影 */font-size: 24px;}/stylebodydiv classwrapdiv classmodal磨砂玻璃效果/div/div/body
十二、各种FLIP动画
参考https://zhuanlan.zhihu.com/p/712766286 style.box {width: 60px;height: 60px;background-color: skyblue;color: white;font-size: 30px;margin: 10px;}/stylebodydiv classcontainer styledisplay: flexdiv classbox key11/divdiv classbox key22/divdiv classbox key33/divdiv classbox key44/divdiv classbox key55/div/divbutton onclickshuffle()打乱/buttonscriptfunction shuffle() {const container document.querySelector(.container);const boxes Array.from(container.children);// First: 记录每个盒子的起始位置const startPositions boxes.reduce((result, box) ({...result,[box.getAttribute(key)]: box.getBoundingClientRect(),}),{});// 随机打乱盒子顺序然后把打乱好的盒子放回 DOMboxes.sort(() Math.random() - 0.5);boxes.forEach((box) container.appendChild(box));// Last: 记录每个盒子的最终位置const endPositions boxes.reduce((result, box) ({...result,[box.getAttribute(key)]: box.getBoundingClientRect(),}),{});// Invert: 计算 “反向” 偏移量boxes.forEach((box) {const key box.getAttribute(key);const start startPositions[key];const end endPositions[key];// 注意此时 DOM 已经处于最终位置所以它的 translate 是 “反向” 的// 所以要用 first 来减去 lastconst deltaX start.left - end.left;const deltaY start.top - end.top;// 如果元素 “原地不动”那么跳过后续流程if (deltaX 0 deltaY 0) {return;}// 让元素通过 transform 偏移回到起点box.style.transition null; // 暂时屏蔽掉过渡实际生产此处需完善box.style.transform translate(${deltaX}px, ${deltaY}px);// Play: 在重绘之前撤掉 transform 偏移播放 “归位” 过渡动画requestAnimationFrame(() {box.style.transition transform 2s;box.style.transform ;});// FLIP 动画完成后清理残余样式box.addEventListener(transitionend,() {box.style.transition null;box.style.transform null;},{ once: true });});}/script/body
其中的“Invert” 和 “Play” 步骤可以使用 Web Animation API 进行简化 style.box {width: 60px;height: 60px;color: white;font-size: 30px;margin: 10px;box-sizing: border-box;background-color: skyblue;border: 2px black solid;transition: width 500ms, height 500ms;}.scale {position: absolute;top: 90px;left: 10px;width: 120px;height: 120px;z-index: 10;}/stylebodydiv classcontainer styledisplay: flexdiv classbox key11/divdiv classbox key22/divdiv classbox key33/divdiv classbox key44/divdiv classbox key55/div/divscriptconst container document.querySelector(.container)const boxes Array.from(container.children)boxes.forEach(box {box.addEventListener(click, () {// First: 记录每个盒子的起始位置const startPositions boxes.reduce((result, box) ({...result,[box.getAttribute(key)]: box.getBoundingClientRect(),}),{})box.classList.toggle(scale)// Last: 记录每个盒子的最终位置const endPositions boxes.reduce((result, box) ({...result,[box.getAttribute(key)]: box.getBoundingClientRect(),}),{})// Invert: 计算 “反向” 偏移量boxes.forEach(box {const key box.getAttribute(key)const start startPositions[key]const end endPositions[key]// 注意此时 DOM 已经处于最终位置所以它的 transform 是 “反向” 的// 所以要用 first 来减去 lastconst deltaX start.left - end.leftconst deltaY start.top - end.top// 如果元素 “原地不动”那么跳过后续流程if (deltaX 0 deltaY 0) {return}// 将盒子通过 transform 移至初始位置box.style.transition box.style.transform translate(${deltaX}px, ${deltaY}px)// Play: 播放动画应用变换requestAnimationFrame(() {box.style.transition all 500msbox.style.transform })// FLIP 动画完成后清理残余样式box.addEventListener(transitionend,() {box.style.transition nullbox.style.transform null},{ once: true })})})})/script/body
Vue 内置组件 TransitionGroup 已经实现了 FLIP 动画
templateTransitionGroup styledisplay: flex nameflip tagdivdiv classbox v-foritem of list :keyitem{{ item }}/div/TransitionGroupbutton clickshuffle打乱/button
/template
script setup
import { reactive } from vue
const list reactive([1, 2, 3, 4, 5])
const shuffle () void list.sort(() Math.random() - 0.5)
/script
style scoped
.box {width: 60px;height: 60px;background-color: skyblue;color: white;font-size: 30px;margin: 10px;
}
.flip-move {transition: all 2s;
}
/style
react-flip-toolkit 工具是一个用于实现组件 FLIP 动画的 React 库。