. 黑白图像
这段代码会让你的彩色照片显示为黑白照片,是不是很酷?
img.desaturate { filter: grayscale(100%); -webkit-filter: grayscale(100%); -moz-filter: grayscale(100%); -ms-filter: grayscale(100%); -o-filter: grayscale(100%); }
2. 使用 :not() 在菜单上应用/取消应用边框
先给每一个菜单项添加边框
/* add border */ .nav li { border-right: 1px solid #666; }
然后再除去最后一个元素
// remove border / .nav li:last-child { border-right: none; }
可以直接使用 :not() 伪类来应用元素:
.nav li:not(:last-child) { border-right: 1px solid #666; }
这样代码就干净,易读,易于理解了。
当然,如果你的新元素有兄弟元素的话,也可以使用通用的兄弟选择符(~):
.nav li:first-child ~ li { border-left: 1px solid #666; }
3. 页面顶部阴影
下面这个简单的 CSS3 代码片段可以给网页加上漂亮的顶部阴影效果:
body:before { content: ""; position: fixed; top: -10px; left: 0; width: 100%; height: 10px; -webkit-box-shadow: 0px 0px 10px rgba(0,0,0,.8); -moz-box-shadow: 0px 0px 10px rgba(0,0,0,.8); box-shadow: 0px 0px 10px rgba(0,0,0,.8); z-index: 100; }
4. 给 body 添加行高
你不需要分别添加 line-height 到每个p,h标记等。只要添加到 body 即可:
body { line-height: 1; }
这样文本元素就可以很容易地从 body 继承。
5. 所有一切都垂直居中
要将所有元素垂直居中,太简单了:
html, body { height: 100%; margin: 0; } body { -webkit-align-items: center; -ms-flex-align: center; align-items: center; display: -webkit-flex; display: flex; }
看,是不是很简单。
注意:在IE11中要小心flexbox
6. 逗号分隔的列表
让HTML列表项看上去像一个真正的,用逗号分隔的列表:
ul > li:not(:last-child)::after { content: ","; }
对最后一个列表项使用 :not() 伪类。
7. 使用负的 nth-child 选择项目
在CSS中使用负的 nth-child 选择项目1到项目n。
li { display: none; } /* select items 1 through 3 and display them */ li:nth-child(-n+3) { display: block; }
8. 对图标使用 SVG
我们没有理由不对图标使用SVG:
.logo { background: url("logo.svg"); }
SVG对所有的分辨率类型都具有良好的扩展性,并支持所有浏览器都回归到IE9。这样可以避开.png、.jpg或.gif文件了。
9. 优化显示文本
有时,字体并不能在所有设备上都达到最佳的显示,所以可以让设备浏览器来帮助你:
html { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
注:请负责任地使用 optimizeLegibility。此外,IE /Edge没有 text-rendering 支持。
10. 对纯 CSS 滑块使用 max-height
使用 max-height 和溢出隐藏来实现只有CSS的滑块:
.slider ul { max-height: 0; overlow: hidden; } .slider:hover ul { max-height: 1000px; transition: .3s ease; }
11. 继承 box-sizing
让 box-sizing 继承 html:
html { box-sizing: border-box; } *, *:before, *:after { box-sizing: inherit; }
这样在插件或杠杆其他行为的其他组件中就能更容易地改变 box-sizing 了。
12. 表格单元格等宽
表格工作起来很麻烦,所以务必尽量使用 table-layout: fixed 来保持单元格的等宽:
.calendar { table-layout: fixed; }
13. 用 Flexbox 摆脱外边距的各种 hack
当需要用到列分隔符时,通过flexbox的 space-between 属性,你就可以摆脱nth-,first-,和 last-child 的hack了:
.list { display: flex; justify-content: space-between; } .list .person { flex-basis: 23%; }
现在,列表分隔符就会在均匀间隔的位置出现。
14. 使用属性选择器用于空链接
当a元素没有文本值,但 href 属性有链接的时候显示链接:
a[href^="http"]:empty::before { content: attr(href); }
相当方便。
15. 检测鼠标双击
HTML:
<div class="test3"> <span><input type="text" value=" " readonly="true" /> <a href="http://renpingjun.com">Double click me</a></span> </div>
CSS:
.test3 span { position: relative; } .test3 span a { position: relative; z-index: 2; } .test3 span a:hover, .test3 span a:active { z-index: 4; } .test3 span input { background: transparent; border: 0; cursor: pointer; position: absolute; top: -1px; left: 0; width: 101%; /* Hacky */ height: 301%; /* Hacky */ z-index: 3; } .test3 span input:focus { background: transparent; border: 0; z-index: 1; }
16. CSS 写出三角形
/* create an arrow that points up */ div.arrow-up { width:0px; height:0px; border-left:5px solid transparent; /* left arrow slant */ border-right:5px solid transparent; /* right arrow slant */ border-bottom:5px solid #2f2f2f; /* bottom, add background color here */ font-size:0px; line-height:0px; } /* create an arrow that points down */ div.arrow-down { width:0px; height:0px; border-left:5px solid transparent; border-right:5px solid transparent; border-top:5px solid #2f2f2f; font-size:0px; line-height:0px; } /* create an arrow that points left */ div.arrow-left { width:0px; height:0px; border-bottom:5px solid transparent; /* left arrow slant */ border-top:5px solid transparent; /* right arrow slant */ border-right:5px solid #2f2f2f; /* bottom, add background color here */ font-size:0px; line-height:0px; } /* create an arrow that points right */ div.arrow-right { width:0px; height:0px; border-bottom:5px solid transparent; /* left arrow slant */ border-top:5px solid transparent; /* right arrow slant */ border-left:5px solid #2f2f2f; /* bottom, add background color here */ font-size:0px; line-height:0px; }
17. CSS3 calc() 的使用
calc() 用法类似于函数,能够给元素设置动态的值:
/* basic calc */ .simpleBlock { width: calc(100% - 100px); } /* calc in calc */ .complexBlock { width: calc(100% - 50% / 3); padding: 5px calc(3% - 2px); margin-left: calc(10% + 10px); }
18. 文本变渐
文本渐变效果很流行,使用 CSS3 能够很简单就实现:
h2[data-text] { position: relative; } h2[data-text]::after { content: attr(data-text); z-index: 10; color: #e3e3e3; position: absolute; top: 0; left: 0; -webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,0)), color-stop(50%, rgba(0,0,0,1)), to(rgba(0,0,0,0)));}
19. 禁用鼠标事件
CSS3 新增的 pointer-events 让你能够禁用元素的鼠标事件,例如,一个连接如果设置了下面的样式就无法点击了。
.disabled { pointer-events: none; }
20. 模糊文本
简单但很漂亮的文本模糊效果,简单又好看!
家好,今天我们聊一下现代应用中常见的一种交互验证方式:滑块验证。滑块验证也被称为拼图验证码,是一种用于验证用户是否为人类而不是机器人的常见方法。用户需要完成验证后才能继续往下操作,而机器人通常很难模拟这种人类行为。也因为这样,滑块验证已经成为了网站注册、登录、商品防爬以及其他交互过程中的一种重要安全措施。
滑块验证的核心思路是要求用户完成一个任务来验证其非机器人的身份。大多数应用通常包括将一个滑块拖动到正确的位置,使其与一个缺口图像对齐。用户需要通过鼠标或手指触摸滑动来完成。在这个过程中,应用会检测用户的行为数据,并且判断是否是机器人操作。
准备两张图片,一张是背景图,一张是从背景图上截的一块:
下面我们实现一个简单的滑块验证示例,通过简单的HTML、CSS和JavaScript来实现一个完整的拼图验证码。
创建HTML结构,包括一个背景图和一个滑块,以及一个包含缺口的小图块。代码非常简单:
<div class="slider-container">
<div class="slider-background">
<div class="gap-fixed"></div> <!-- 固定缺口位置 -->
<div class="slider">
<div class="gap"></div> <!-- 缺口图放置在滑块内部 -->
</div>
<div class="slider-trabecula"></div>
</div>
</div>
我们需要为HTML元素添加样式,包括背景图、滑块、缺口等。样式可以通过CSS来定义,以下是一些基本样式的示例:
/* 样式 */
.slider-container {
width: 500px; /* 背景图宽度 */
height: 300px; /* 背景图高度 */
margin: 20px auto;
position: relative;
}
.slider-background {
width: 100%;
background: url('https://files.mdnice.com/user/1107/739c3c4b-0082-4719-a5fd-f17506e9ea01.png'); /* 背景图URL */
background-size: 100% 100%; /* 背景图铺满 */
border-radius: 5px;
height: 300px;
position: relative;
overflow-x: hidden;
}
.slider {
width: 80px; /* 滑块宽度 */
height: 50px;
background-color: #3498db;
border-radius: 5px;
position: absolute;
cursor: pointer;
user-select: none; /* 禁止文本选中 */
bottom: 10px; /* 滑块位于底部 */
z-index: 2;
transition: transform 0.2s ease; /* 添加平滑动画效果 */
}
.slider-trabecula {
bottom: 10px;
width: 100%;
height: 50px;
position: absolute;
z-index: 1;
background: rgb(204 204 204 / 50%);
}
.gap {
width: 75px; /* 缺口图的宽度 */
height: 50px; /* 缺口图的高度 */
background-image: url('https://files.mdnice.com/user/1107/b835a241-5a0d-40ac-9b95-23f7e283dc03.png'); /* 缺口图的URL */
background-size: 100% 100%;
position: absolute;
top: -112px;
box-shadow: 0px 0px 5px 1px #ccc;
}
.gap-fixed {
width: 75px; /* 缺口图的宽度 */
height: 50px; /* 缺口图的高度 */
position: absolute;
bottom: 122px;
left: 358px;
box-shadow: 0px 0px 5px 1px #ff0000;
}
最后一步也是最重要的部分JS交互。我们需要处理滑块的拖动、验证逻辑以及用户与滑块的交互。这里展示核心部分:
// 模拟横轴滑动位置
const mockPositionX=360;
// JavaScript
const slider=document.querySelector('.slider');
let isDragging=false;
let startPositionX=0;
slider.addEventListener('mousedown', (e)=> {
isDragging=true;
startPositionX=e.clientX;
});
document.addEventListener('mousemove', (e)=> {
if (!isDragging) return;
let offsetX=e.clientX - startPositionX;
slider.style.transform=`translateX(${offsetX}px)`;
});
document.addEventListener('mouseup', ()=> {
if (!isDragging) return;
const transformX=Math.abs(parseInt(slider.style.transform.slice(11)));
if (transformX < mockPositionX + 10 && transformX > mockPositionX - 10) {
// 验证通过
document.querySelector('.slider-trabecula').style.background='rgb(12 160 18 / 50%)';
// 关闭滑块
// 此处可以触发后续操作,如登录、列表加载等
} else {
// 验证失败
document.querySelector('.slider-trabecula').style.background='rgb(249 2 2 / 50%)';
setTimeout(()=> {
document.querySelector('.slider-trabecula').style.background='rgb(204 204 204 / 50%)';
slider.style.transform='translateX(0)';
}, 1500);
}
isDragging=false;
});
这样我们就完成了一个简单的滑块验证码了,来看下效果:
当然在实际应用中,我们可能需要添加更复杂的验证逻辑,以确保安全性。业内有一些常用的方案和最佳实践,以下是一些业内常用的方案,我在后续的文章中详细讨论,可以关注我及时了解后续。
为了增加滑块验证的难度,滑块的位置和缺口的位置应该是随机的,不能是固定的。用户在每次验证时都需要滑动不同位置的滑块,进而防止攻击者根据固定的位置进行攻击。
有些滑块验证方案会在缺口图像上添加旋转变换,使缺口不仅需要水平滑动,还需要旋转以匹配背景图。这增加了攻击的难度,因为攻击者需要模拟用户旋转滑块。
监视用户的行为模式,例如鼠标移动、点击速度和拖动路径等。通过分析这些行为可以更好地区分人类用户和机器人。例如,机器人通常会以直线移动滑块,而用户的移动路径可能会更加曲线和随机。
这个很重要了,前端进行验证永远是不可靠的,需要在后端进行二次验证。前端验证可以提供用户友好的反馈,但最终的验证应该由后端来完成,防止攻击者绕过前端验证,采用后端验证可以确保只有经过验证的请求才能被处理。
允许用户有一定的容错空间,即使滑块没有完美对齐,也可以通过验证。这可以减少误报。容错机制可以通过在验证时允许一定范围的误差来实现,可参考示例代码,容错10像素 transformX < mockPositionX + 10 && transformX > mockPositionX - 10。
定期监控滑块验证的性能和安全性,根据具体情况进行调整。分析攻击常用的模式并采取相应的反制措施。持续的监控可以帮助我们及时发现和应对新的威胁。
这些方案可以根据具体的需求和威胁模型进行定制。滑块验证作为一种反机器人的工具,也会不断发展和演进,以适应不断变化的威胁。希望本文提供的思路和实现步骤能够帮助大家更好地理解和应用滑块验证技术,喜欢点个关注吧。
.使用CSS复位
CSS复位可以在不同的浏览器上保持一致的样式风格。您可以使用CSS reset 库Normalize等,也可以使用一个更简化的复位方法:
*,*::before,*::after { box-sizing: border-box; margin: 0; padding: 0;}
现在元素的 margin 和padding 已为0,box-sizing可以管理您的CSS盒模型布局。
注意:如果你遵循接下来继承 box-sizing讲解的这个技巧, 你不需要在以上代码中添加 box-sizing 属性。
2.继承 box-sizing
从 html 元素继承box-sizing :
html { box-sizing: border-box;} *,*::before,*::after { box-sizing: inherit;}
如此在插件或其它组件里改变 box-sizing 变得简单。
3.使用unset而不是重置所有属性
重置元素的属性时,不需要重置每个单独的属性:
button { background: none; border: none; color: inherit; font: inherit; outline: none; padding: 0;}
你可以用all简写來指定所有元素的属性。 将该值设置为unset会将元素的属性更改为其初始值:
button { all: unset;}
注意: 所有速记在IE11中不被支持,目前正在考虑Edge的支持。 IE11不支持unset。
4.使用 :not() 选择器来决定表单是否显示边框
先为元素添加边框
/* 添加边框 */.nav li { border-right: 1px solid #666;}
为最后一个元素去除边框
/* 去掉边框 */.nav li:last-child { border-right:none;}
不过不要这么做,使用 :not() 伪类来达到同样的效果:
.nav li:not(:last-child) { border-right: 1px solid #666;}
当然,你也可以使用 .nav li + li,但是 :not() 更加清晰,具有可读性。
5.为 body 元素添加行高
不必为每一个 <p>,<h*>元素逐一添加 line-height,直接添加到 body 元素:
body { line-height: 1.5;}
文本元素可以很容易地继承 body 的样式。
6.为表单元素设置:focus
有视力的键盘用户依靠焦点来确定键盘事件在页面中的位置。 使表单元素的焦点脱颖而出,然后与浏览器的默认实现保持一致:
a:focus,button:focus,input:focus,select:focus,textarea:focus { box-shadow: none; outline: #000 dotted 2px; outline-offset: .05em;}
7.垂直居中任何元素
不!这绝不是黑魔法,真的可以垂直居中任何元素:
html,body { height: 100%; margin: 0;} body { -webkit-align-items: center; -ms-flex-align: center; align-items: center; display: -webkit-flex; display: flex;}
...還有CSS Grid:
body { display: grid; height: 100vh; margin: 0; place-items: center center;}
这还不够?垂直方向,水平方向?任何元素,任何时间,任何地点?CSS-Tricks 有篇好文讲到了各种居中的技巧。
注意: IE11 对 flexbox 的支持有点 bug。
8.逗号分隔列表
使列表的每项都由逗号分隔:
ul > li:not(:last-child)::after { content: ",";}
因最后一项不加逗号,可以使用 :not() 伪类。
注意: 这一技巧对于无障碍,特别是屏幕阅读器而言并不理想。而且复制粘贴并不会带走CSS生成的内容,需要注意。
9.使用负的 nth-child 来选择元素
使用负的 nth-child 可以选择1 至 n 个元素。
li { display: none;} /* 选择第 1 至第 3 个元素并显示出来 */li:nth-child(-n+3) { display: block;}
或许你已经掌握了如何使用 :not()这个技巧,试下这个:
/* 选择除前3个之外的所有项目,并显示它们 */li:not(:nth-child(-n+3)) { display: none;}
如此简单!
10.使用 SVG 图标
没有理由不使用 SVG 图标:
.logo { background: url("logo.svg");}
SVG 在所有分辨率下都可以良好缩放,并且支持所有 IE9 以后的浏览器,丢掉你的 .png, .jpg, 或 .gif-jif-whatev 文件吧。
注意: 针对仅有图标的按钮,如果 SVG 没有加载成功的话,以下样式对无障碍有所帮助:
.no-svg .icon-only::after { content: attr(aria-label);}
11.使用 “形似猫头鹰” 的选择器
这个名字可能比较陌生,不过通用选择器 (*) 和 相邻兄弟选择器 (+) 一起使用,效果非凡:
* + * { margin-top: 1.5em;}
在此示例中,文档流中的所有的相邻兄弟元素将都将设置 margin-top: 1.5em的样式。
更多 “形似猫头鹰” 的选择器,可参考 A List Apart 上面 Heydon Pickering 的文章
12.使用 max-height 来建立纯 CSS 的滑块
max-height 与overflow hidden 一起来建立纯 CSS 的滑块:
.slider { max-height: 200px; overflow-y: hidden; width: 300px;} .slider:hover { max-height: 600px; overflow-y: scroll;}
鼠标移入滑块元素时增大它的 max-height 值,便可以显示溢出部分。
13.创造格子等宽的表格
table-layout: fixed 可以让每个格子保持等宽:
.calendar { table-layout: fixed;}
无痛的 table 布局。
14.利用 Flexbox 去除多余的外边距
与其使用 nth-, first-,和 last-child 去除列之间多余的间隙,不如使用 flexbox 的 space-between 属性:
.list { display: flex; justify-content: space-between;} .list .person { flex-basis: 23%;}
列之间的间隙总是均匀相等。
15.利用属性选择器来选择空链接
当 <a> 元素没有文本内容,但有 href 属性的时候,显示它的 href 属性:
a[href^="http"]:empty::before { content: attr(href);}
相当简便。
16.给 “默认” 链接定义样式
给 “默认” 链接定义样式:
a[href]:not([class]) { color: #008000; text-decoration: underline;}
通过 CMS 系统插入的链接,通常没有class 属性,以上样式可以甄别它们,而且不会影响其它样式。
17.一致垂直节奏
通用选择器 (*) 跟元素一起使用,可以保持一致的垂直节奏:
.intro > * { margin-bottom: 1.25rem;}
一致的垂直节奏可以提供视觉美感,增强内容的可读性。
18.固定比例盒子
要创建具有固定比例的一个盒子,所有你需要做的就是给 div 设置一个 padding:.container { height: 0; padding-bottom: 20%; position: relative;} .container div { border: 2px dashed #ddd; height: 100%; left: 0; position: absolute; top: 0; width: 100%;}
使用20%的padding-bottom使得框等于其宽度的20%的高度。与视口宽度无关,子元素的div将保持其宽高比(100%/ 20%=5:1)。
19.为破碎图象定义样式
只要一点CSS就可以美化破碎的图象:
img { display: block; font-family: sans-serif; font-weight: 300; height: auto; line-height: 2; position: relative; text-align: center; width: 100%;}
以添加伪元素的法则来显示用户信息和URL的引用:
img::before { content: "We're sorry, the image below is broken :("; display: block; margin-bottom: 10px;} img::after { content: "(url: " attr(src) ")"; display: block; font-size: 12px;}
了解更多关于这类样式的技巧 Ire Aderinokun的 原帖.
20.用 rem 来调整全局大小;用 em 来调整局部大小
在根元素设置基本字体大小后 (html { font-size: 100%; }), 使用 em 设置文本元素的字体大小:
h2 { font-size: 2em;} p { font-size: 1em;}
然后设置模块的字体大小为 rem:
article { font-size: 1.25rem;} aside .module { font-size: .9rem;}
现在,每个模块变得独立,更容易、灵活的样式便于维护。
21.隐藏没有静音、自动播放的影片
这是一个自定义用户样式表的不错的技巧。避免在加载页面时自动播放。如果没有静音,则不显示视频:
video[autoplay]:not([muted]) { display: none;}
再次,我们利用了 :not() 的优点。
22.使用选择器:root来控制字体弹性
在响应式布局中,字体大小应需要根据不同的视口进行调整。你可以计算字体大小根据视口高度的字体大小和宽度,这时需要用到:root:
:root { font-size: calc(1vw + 1vh + .5vmin);}
现在,您可以使用 root em
body { font: 1rem/1.6 sans-serif;}
23.为更好的移动体验,为表单元素设置字体大小
当触发<select>的下拉列表时,为了避免表单元素在移动浏览器(IOS Safari 等等)上的缩放,加上font-size:
input[type="text"],input[type="number"],select,textarea { font-size: 16px;}:dancer:
24.使用指针事件來控制鼠标事件
指针事件允許您指定鼠标如何与其触摸的元素进行交互。 要禁用按钮上的默认指针事件,例如:
.button-disabled { opacity: .5; pointer-events: none;}
就这么简单。
*请认真填写需求信息,我们会在24小时内与您取得联系。