
三十课(30ke.cn) 编程,学习,分享,记录生活的点点滴滴,保持热情42度。
1 概述 1.1 前言 使用一个或多个图像相关的CSS属性(background-blend-mode, mix-blend-mode, or filter)可以实现许多特殊的图片显示效果。本文转载自Bennett Feely的个人网站,文中共列举了20种图片显示效果。 详细代码及英文原文请访问Bennett Feely的主页。 2 效果列表 2.1 铅笔画效果 效果示例 SCSS代码 .pencil-effect { $url : url(photo.jpg); background-image: $url; background-size: cover; background-position: center; @supports (filter: invert(1)) and (background-blend-mode: difference) { background-image: $url, $url; background-blend-mode: difference; background-position: calc(50% - 1px) calc(50% - 1px), calc(50% + 1px) calc(50% + 1px); filter: brightness(2) invert(1) grayscale(1); box-shadow: inset 0 0 0 1px black; } } 查看示例程序 2.2 水彩效果 效果示例 SCSS代码 .watercolor-effect { $url : url(photo.jpg); background-image: $url; background-size: cover; background-position: center; @supports (filter: blur(2px)) and (mix-blend-mode: multiply) { position: relative; overflow: hidden; &:before, &:after { display: block; content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-size: cover; } &:before { background-image: $url, $url; background-blend-mode: difference; background-position: calc(50% - 1px) calc(50% - 1px), calc(50% + 1px) calc(50% + 1px); filter: brightness(2) invert(1) grayscale(1); box-shadow: inset 0 0 0 1px black; } &:after { background-image: $url; background-position: center; mix-blend-mode: multiply; filter: brightness(1.3) blur(2px) contrast(2); } } } 查看示例程序 2.3 浮雕效果 效果示例 SCSS代码 .emboss-effect { $url : url(photo.jpg); background-image: $url; background-size: cover; background-position: center; @supports (filter: invert(1)) and (background-blend-mode: difference, screen) { background-image: $url, $url, $url; background-blend-mode: difference, screen; background-position: calc(50% - 1px) calc(50% - 1px), calc(50% + 1px) calc(50% + 1px), center; filter: brightness(2) invert(1) grayscale(1); } } 查看示例程序 2.4 彩铅效果 效果示例 SCSS代码 .colored-pencil-effect { $url : url(photo.jpg); background-image: $url; background-size: cover; background-position: center; @supports (filter: invert(1)) and (mix-blend-mode: color) { position: relative; &:before, &:after { display: block; content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-size: cover; box-shadow: inset 0 0 0 1px black; } &:before { background-image: $url, $url; background-blend-mode: difference; background-position: calc(50% - 1px) calc(50% - 1px), calc(50% + 1px) calc(50% + 1px); filter: brightness(2) invert(1) grayscale(1); } &:after { background: inherit; mix-blend-mode: color; } } } 查看示例程序 2.5 黑板效果 效果示例 SCSS代码 .chalkboard-effect { $url : url(photo.jpg); background-image: $url; background-size: cover; background-position: center; @supports (filter: grayscale(1)) and (background-blend-mode: difference) { background-image: $url, $url; background-blend-mode: difference; background-position: calc(50% - 1px) calc(50% - 1px), calc(50% + 1px) calc(50% + 1px); filter: brightness(1.5) grayscale(1); } } 查看示例程序 2.6 彩色黑板效果 效果示例 SCSS代码 .colored-chalkboard-effect { $url : url(photo.jpg); background-image: $url; background-size: cover; background-position: center; @supports (filter: brightness(2)) and (background-blend-mode: color, difference) { background-image: $url, $url, $url; background-size: cover; background-position: calc(50% - 1px) calc(50% - 1px), calc(50% + 1px) calc(50% + 1px), center; background-blend-mode: color, difference; filter: brightness(2); } } 查看示例程序 2.7 喷枪效果 效果示例 SCSS代码 .airbrush-effect { $url : url(photo.jpg); background-image: $url; background-size: cover; background-position: center; @supports (filter: blur(5px) contrast(5)) and (mix-blend-mode: multiply) { position: relative; overflow: hidden; &:after { display: block; content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: inherit; filter: brightness(1.5) saturate(100) blur(5px) contrast(5); mix-blend-mode: multiply; } } } 查看示例程序 2.8 绚烂效果 效果示例 SCSS代码 .hallucination-effect { $url : url(photo.jpg); $offset : 5px; background-image: $url; background-size: cover; background-position: center; @supports (mix-blend-mode: multiply) { position: relative; overflow: hidden; background-color: magenta; background-blend-mode: screen; &:before, &:after { display: block; content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: inherit; mix-blend-mode: multiply; transform: scale(1.05); } &:before { background-color: yellow; background-blend-mode: screen; transform-origin: top left; } &:after { background-color: cyan; background-blend-mode: screen; transform-origin: bottom right; } } } 查看示例程序 2.9 绒布效果 效果示例 SCSS代码 .flannel-effect { $url : url(photo.jpg); background-image: $url; background-size: cover; background-position: center; @supports (background-blend-mode: overlay) { background-image: $url, $url, $url; background-position: center; background-size: 100%, 100000% 100%, 100% 100000%; background-blend-mode: overlay; } } 查看示例程序 2.10 水平低墨 效果示例 SCSS代码 .low-ink-x-effect { $url : url(photo.jpg); background-image: $url; background-size: cover; background-position: center; @supports (background-blend-mode: screen, overlay) { background-image: $url, $url, $url; background-size: 100% 100%, 10000% 100%; background-blend-mode: screen, overlay; } } 查看示例程序 2.11 垂直低墨效果 效果示例 SCSS代码 .low-ink-y-effect { $url : url(photo.jpg); background-image: $url; background-size: cover; background-position: center; @supports (background-blend-mode: screen, overlay) { background-image: $url, $url, $url; background-size: 100% 100%, 100% 1000%; background-blend-mode: screen, overlay; } } 查看示例程序 2.12 拼贴效果 效果示例 SCSS代码 .collage-effect { $url : url(photo.jpg); background-image: $url; background-size: cover; background-position: center; @supports (background-blend-mode: overlay) { background-image: $url, $url, $url, $url, $url, $url; background-size: 200%, 80%, 60%, 50%, 40%, 100%; background-position: 50%, 80%, 30%, 0; background-blend-mode: overlay; background-repeat: no-repeat; } } 查看示例程序 2.13 马赛克效果 效果示例 SCSS代码 .mosaic-effect { $url : url(photo.jpg); background-image: $url, $url; background-size: cover, 5% 5%; background-position: center; background-blend-mode: overlay; } 查看示例程序 2.14 图片边框效果 效果示例 SCSS代码 .photo-border-effect { $url : url(photo.jpg); background-image: $url, $url; background-position: center; background-size: 60%, 20%; background-repeat: no-repeat, repeat; } 查看示例程序 2.15 红外效果 效果示例 SCSS代码 .infrared-effect { $url : url(photo.jpg); background-image: $url; background-size: cover; background-position: center; filter: hue-rotate(180deg) saturate(2); } 查看示例程序 2.16 夜视效果 效果示例 SCSS代码 .night-vision-effect { $url : url(photo.jpg); $line-width: 5px; background-image: $url , radial-gradient( #0F0, #000 ), repeating-linear-gradient( transparent 0, rgba(0,0,0,0.1) $line-width/2, transparent $line-width ); background-size: cover; background-position: center; background-blend-mode: overlay; } 查看示例程序 2.17 沃霍尔效果 效果示例 SCSS代码 .warhol-effect { $url : url(photo.jpg); background-image: $url; background-size: cover; background-position: center; @supports (background-blend-mode: color) { background-image: linear-gradient( #14EBFF 0, #14EBFF 50%, #FFFF70 50%, #FFFF70 100% ), linear-gradient( #FF85DA 0, #FF85DA 50%, #AAA 50%, #AAA 100% ), $url; background-size: 50% 100%, 50% 100%, 50% 50%; background-position: top left, top right; background-repeat: no-repeat, no-repeat, repeat; background-blend-mode: color; } } 查看示例程序 2.18 颜色校正效果 效果示例 SCSS代码 .selective-color-effect { $url : url(photo.jpg); background-image: $url; background-size: cover; background-position: center; @supports (filter: brightness(3)) and (mix-blend-mode: color) { position: relative; &:before, &:after { display: block; content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: inherit; background-color: red; background-blend-mode: screen; mix-blend-mode: color; filter: brightness(3); } } } 查看示例程序 2.19 水平镜像效果 效果示例 SCSS代码 .mirror-x-effect { $url : url(photo.jpg); background-image: $url; background-size: cover; background-position: center; @supports (transform: scaleX(-1)) { position: relative; &:before, &:after { display: block; content: ""; position: absolute; top: 0; bottom: 0; background: inherit; } &:before { left: 0; right: 50%; transform: scaleX(-1); } &:after { left: 50%; right: 0; } } } 查看示例程序 2.20 垂直镜像效果 效果示例 SCSS代码 .mirror-y-effect { $url : url(photo.jpg); background-image: $url; background-size: cover; background-position: center; @supports (transform: scaleY(-1)) { position: relative; &:before, &:after { display: block; content: ""; position: absolute; left: 0; right: 0; background: inherit; } &:before { top: 0; bottom: 50%; transform: scaleY(-1); } &:after { top: 50%; bottom: 0; } } } 查看示例程序 3 结尾 3.1 结语 详细代码及英文原文请访问Bennett Feely的主页。 本文转载自Bennett Feely的个人网站,只做学习和交流使用。
1 概述 1.1 前言 本文中简要罗列了JavaScript操作Dom的基本方法,其中包括元素查询、文档结构遍历、属性及内容操作、创建节点、插入节点及删除节点等内容。虽然JQuery更便利,但我还是喜欢用原生的API。 2 文档元素选取 2.1 ID选择器 通过ID选取元素是最简单和常用的选取元素的方法,ID选择器性能优于其它选择器。 var title = document.getElementById("title"); ID不存在,返回 null 。 查看示例程序 2.2 名称选择器 基于name属性的值选取元素区别于ID选择器。其一,name属性值 不是必须唯一,多个元素可能有同样的名称;其二,name属性只在少数HTML元素中有效,包括表单、表单元素、iframe 及 img 元素。 var sports = document.getElementsByName("sports"); 查看示例程序 2.3 标签选择器 利用HTML元素的标签名称选取指定类型的元素。 var h1 = document.getElementsByTagName("h1"); 查看示例程序 2.4 类选择器 通过HTML的 class 属性值选择元素。 var title = document.getElementsByClassName("title"); 查看示例程序 2.5 CSS单元素选择器 通过CSS样式表选择器的强大语法,来选择元素。返回第一个匹配的元素。 var title = document.querySelector("#title"); // CSS ID选择 var h1 = document.querySelector("h1"); //选取第一个h1元素 查看示例程序 2.6 CSS多元素选择器 这是最强大的终极选择器 var h1s = document.querySelectorAll("h1"); //返回所有h1标签元素 查看示例程序 3 DOM遍历 3.1 节点相关 3.1.1 父节点-parentNode 返回父节点,如果 document 对象调用则返回 null。 var parent = node.parentNode; 查看示例程序 3.1.2 子节点-childNodes 返回所有子节点,即NodeList对象。 var children = node.childNodes; 查看示例程序 3.1.3 首子节点-firstChild 返回第一个子节点。 var first = node.firstChild; 查看示例程序 3.1.4 尾子节点-lastChild 返回最后一个子节点。 var last = node.lastChild; 查看示例程序 3.1.5 下一兄弟节点-nextSibling 返回下一个兄弟节点。 var next = node.nextSibling; 查看示例程序 3.1.6 前一兄弟节点-previousSibling 返回前一个兄弟节点。 var previous = node.previousSibling; 查看示例程序 3.1.7 节点类型-nodeType 返回节点类型的数字表示。 1代表 Element 节点 3代表 Text 节点 8代表 Comment 节点 9代表 Document 节点 11代表 DocumentFragment 节点 查看示例程序 3.1.8 节点值-nodeValue 返回 Text 节点 或 Comment 节点的值。 var value = node.nodeValue; 查看示例程序 3.1.9 节点名-nodeName 返回元素的标签名,以大写形式表示。 var name = node.nodeName; 查看示例程序 3.2 元素相关 3.2.1 子元素-children 返回所有子元素。 var children = node.children; 查看示例程序 3.2.2 首子元素-firstElementChild 元素是节点的一种。 返回所有子元素中的第一个。 var first = node.firstElementChild; 查看示例程序 3.2.3 尾子元素-lastElementChild 返回所有子元素中的最后一个。 var last= node.lastElementChild; 查看示例程序 3.2.4 下一兄弟元素-nextElementSibling 返回下一个兄弟元素。 var next = node.nextElementSibling; 查看示例程序 3.2.5 前一兄弟元素-previousElementSibling 返回前一兄弟元素。 var previous = node.previousElementSibling; 查看示例程序 3.2.6 子元素数量 返回子元素的数量。 var count = node.childElementCount; 查看示例程序 4 属性 4.1 标准属性 表示HTML文档元素的 HTMLElement 对象定义了读/写属性,它们对应于元素的HTML属性。HTMLElement 定义了通用的HTML属性,包括id、lang、dir、事件处理程序 onclick 及表单相关属性等。 form.action = "http://30ke.cn"; form.method = "post"; 查看示例程序 4.2 非标准属性 4.2.1 获取属性值-getAttribute 返回非标准的HTML属性的值。 var width = img.getAttribute("width"); 查看示例程序 4.2.2 属性值设置-setAttribute 设置非标准的HTML属性的值。 img.setAttribute("width","400px"); 查看示例程序 4.2.3 属性存在检测-hasAttribute 返回布尔值,用来检测属性是否存在。 var result = img.hasAttribute("width"); 查看示例程序 4.2.4 删除属性-removeAttribute 删除某一属性。 img.removeAttribute("width"); 查看示例程序 4.3 数据集属性-dataset 在HTML5文档中,任意以 data- 为前缀的小写的属性名字都是合法的。这些 “数据集属性” 定义了一种标准的、附加额外数据的方法。 var x = img.dataset.x; 查看示例程序 4.4 元素属性-attributes Node节点定义了 attributes 属性,针对 Element 对象,attributes 是元素所有属性的类数组对象。 var attributes = img.attributes; 索引 attributes 对象得到的值是 Attr 对象。Attr 的 name 和 value 返回该属性的名字和值。 查看示例程序 5 元素内容 5.1 元素内容-innerHTML innerHTML 属性以字符串形式返回这个元素的内容。也可以用来替换元素当前内容。 var innerHTML = parent.innerHTML; // 获取节点的内容 parent.innerHTML = "<h1>三十课</h1>"; //替换节点的内容 查看示例程序 5.2 元素及内容-outerHTML outerHTML 属性以字符串形式返回这个元素及内容。也可以用来替换当前元素及内容。 var outerHTML = parent.outerHTML; // 获取节点及内容 parent.outerHTML= "<h1>三十课</h1>"; //替换节点及其内容 查看示例程序 5.3 纯文本元素内容-textContent 查询或替换纯文本元素内容的标准方法是用Node的textContent属性来实现。在IE中,可以用 Element 的 innerText 属性来代替。 console.log(title.textContent); title.textContent = "三十课2"; 查看示例程序 6 创建节点 6.1 创建元素节点-createElement 使用 document 对象的 createElement() 方法创建新的 Element节点。 var h1 = document.createElement("h1"); 查看示例程序 6.2 创建文本节点-createTextNode 创建纯文本节点。 var txt = document.createTextNode("三十课"); 查看示例程序 6.3 创建文档片段-createDocumentFragment 使用文档片段通常会带来更好的性能。因为文档片段存在于内存中,并不在DOM树中,所以将子元素插入到文档片段时不会引起页面回流(对元素位置和几何上的计算)。 var fragment = document.createDocumentFragment(); 查看示例程序 6.4 创建注释节点-createComment 创建注释节点不经常使用。 var comment = document.createComment("Created by 毛瑞"); 查看示例程序 6.5 节点克隆-cloneNode 通过复制已存在的节点来创建新的文档节点。传参数 true 表示深克隆,false表示浅复制。 var title2 = title.cloneNode(true); 查看示例程序 7 插入节点 7.1 插入子节点-appendChild 在指定元素上插入子节点,并使其成为该节点的最后一个子节点。 parent.appendChild(h2); 查看示例程序 7.2 节点前插入-insertBefore 在父节点上调用本方法 第一参数表示待插入的节点 第二参数是父节点中已经存在的子节点,新节点插入到该节点的前面 parent.insertBefore(h1,h2); // h1插入到h2之前。 查看示例程序 8 删除和替换 8.1 删除子节点-removeChild 在父节点上调用 参数是待删除的节点 parent.removeChild(h2); 查看示例程序 8.2 替换子节点-replaceChild 在父节点上调用 第一个参数是新节点 第二个参数是需要替换的节点 parent.replaceChild(h2n , h2); 查看示例程序 9 结尾 9.1 结语 本人知识水平有限,在汇编的过程中时有错误发生,如发现请不吝指正!多谢。
1 概述 1.1 前言 JavaScript数组方法速查手册极简版中共收了32个数组的常用方法和属性,并根据方法的用途进行重新排序和分类,在文中简要的介绍了方法作用和用例说明。收藏备用吧! 文中介绍的过于简单,想更更多理解相关内容还是要多多动手实践! 2 数组属性 2.1 length-长度属性 每个数组都有一个length属性。针对稠密数组,length属性值代表数组中元素的个数。当数组是稀疏数组时,length属性值大于元素的个数。 var array1 = [ 'a', 'b', 'c' ]; console.log(array1.length); // 输出 3 array1.length = 2; console.log(array1); // 输出 [ "a", "b" ] 查看示例程序 3 数组方法 3.1 Array.isArray-类型判定 Array.isArray() 数组类型判定。 console.log(Array.isArray([1, 2, 3])); // 输出 true console.log(Array.isArray({num: 123})); //输出 false 查看示例程序 3.2 Array.of-创建数组 Array.of() 从可变数量的参数创建数组,不管参数的数量或类型如何。 console.log(Array.of(3)); // 输出 [3] console.log(Array.of(1,2,3)); // 输出 [1,2,3] 查看示例程序 3.3 Array.from-创建数组 Array.from() 用类数组或可迭代对象创建新数组。 console.log(Array.from('abcd')); // 输出 [ "a", "b", "c", "d" ] console.log(Array.from([1, 2, 3], x => x + 1)); // 输出 [ 2, 3, 4 ] 查看示例程序 4 数组原型方法 4.1 查找元素 4.1.1 find-按函数查找 Array.prototype.find() 找到第一个满足检测函数条件的元素,并返回该元素,没找到则返回 undefined。 var array1 = [1, 2, 3, 4, 5]; console.log(array1.find(x => x > 3)); // 输出 4 查看示例程序 4.1.2 findIndex-按函数查找 Array.prototype.findIndex() 找到第一个满足检测函数条件的元素,并返回该元素索引。找不到返回-1。 var array1 = [6, 7, 8, 9, 10]; console.log(array1.findIndex(x => x > 8)); // 输出 3 查看示例程序 4.1.3 indexOf-按元素值查找 Array.prototype.indexOf() 查找元素并返回元素索引值,找不到返回-1。 var arr= [1, 2, 3, 4]; console.log(arr.indexOf(3)); // 输出 2 console.log(arr.indexOf(6)); // 输出 -1 console.log(arr.indexOf(2, 2)); // 输出 -1 第二个参数表示查找的起始位置。 查看示例程序 4.1.4 lastIndexOf-按元素值查找 Array.prototype.lastIndexOf() 从后向前查找元素并返回元素索引值,找不到返回 -1。 var arr = ['a', 'b', 'c', 'd']; console.log(arr.lastIndexOf('b')); // 输出 1 console.log(arr.lastIndexOf('e')); // 输出 -1 查看示例程序 4.2 添加元素 4.2.1 push-尾部添加 Array.prototype.push() 在尾部添加一个或多个元素,返回数组的新长度。 var array1= ['a', 'b', 'c']; console.log(array1.push('d')); // 输出 4 console.log(array1); // 输出 [ "a", "b", "c", "d" ] 查看示例程序 4.2.2 unshift-头部添加 Array.prototype.unshift() 在头部添加一个或多个元素,并返回数组的新长度。 var array1 = [ 4, 5, 6 ]; console.log(array1.unshift(3)); // 输出 4 console.log(array1); // 输出 [ 3, 4, 5, 6 ] console.log(array1.unshift(1, 2)); // 输出 6 console.log(array1); // 输出 [ 1, 2, 3, 4, 5, 6 ] 查看示例程序 4.3 删除元素 4.3.1 pop-尾部删除 Array.prototype.pop() 从尾部删除一个元素,并返回该元素。 var array1= ['a', 'b', 'c', 'd']; console.log(array1.pop()); // 输出 d console.log(array1); // 输出 [ "a", "b", "c" ] 查看示例程序 4.3.2 shift-头部删除 Array.prototype.shift() 从头部删除一个元素,并返回该元素。 var array1 = [1, 2, 3]; console.log(array1.shift()); // 输出 1 console.log(array1); // 输出 [ 2, 3 ] 查看示例程序 4.4 替换元素 4.4.1 splice-添加替换删除 Array.prototype.splice() 添加、替换、删除元素。会改变原数组。 var array1 = [ 'a', 'c', 'd' ]; array1.splice( 1, 0, 'b'); console.log(array1); // 输出 [ "a", "b", "c", "d" ] array1.splice(1,1); console.log(array1); // 输出 [ "a", "c", "d" ] array1.splice(1,1,'bb','cc'); console.log(array1); // 输出 [ "a", "bb", "cc", "d" ] array.splice(start[, deleteCount[, item1[, item2[, ...]]]]) 参数 start:表示替换的位置 参数 deleteCount :表示删除元素的数量 参数 item1... : 表示添加的元素 查看示例程序 4.5 顺序相关 4.5.1 sort-排序 Array.prototype.sort() 数组排序,改变原数组。 var array1 = [ 4, 3, 10, 2 ]; console.log(array1.sort()); // 输出 [ 10, 2, 3, 4 ] console.log(array1.sort((x1, x2) => x1 > x2)); // 输出 [ 2, 3, 4, 10 ] 查看示例程序 4.5.2 reverse-反序 Array.prototype.reverse() 倒置数组,并返回新数组。会改变原数组。 var sourceArray= [ 'a', 'b', 'c' ]; var reverseArray = sourceArray.reverse(); console.log(reverseArray); // 输出 [ "c", "b", "a" ] console.log(sourceArray == reverseArray); // 输出 true 查看示例程序 4.6 遍历迭代 4.6.1 keys-键迭代器 Array.prototype.keys() 数组的键迭代器。 var array1 = ['a', 'b', 'c']; for (let key of array1.keys()) { console.log(key); // 输出 0, 1, 2 } 查看示例程序 4.6.2 values-值迭代器 Array.prototype.values() 数组的值迭代器。 const array1 = ['a', 'b', 'c']; const iterator = array1.values(); for (const value of iterator) { console.log(value); // 输出 a b c } 查看示例程序 4.6.3 entries-键/值对迭代器 Array.prototype.entries() 数组的键/值对迭代器。 var array1 = ['a', 'b', 'c']; var iterator1 = array1.entries(); console.log(iterator1.next().value); // 输出 Array [0, "a"] console.log(iterator1.next().value); // 输出 Array [ 1, "b" ] 查看示例程序 4.6.4 forEach-遍历 Array.prototype.forEach() 遍历数组中的元素,并执行回调函数。 var arr = [1, 2, 3, 4]; arr.forEach(function (x) { console.log(x + 1); // 输出 2 3 4 5 }); 查看示例程序 4.7 检测 4.7.1 includes-值包含检测 Array.prototype.includes() 值包含检测,如包含返回 true,不包含返回false。 var array1 = [1, 2, 3]; console.log(array1.includes(2)); // 输出 true console.log(array1.includes(4)); // 输出 false 查看示例程序 4.7.2 some-函数包含检测 Array.prototype.some() 检测数组中是否有元素可以通过检测函数验证。 var array1 = [ 1, 2, 3, 4 ]; console.log(array1.some(x => x >3)); // 输出 true console.log(array1.some(x => x > 5)); // 输出 false 查看示例程序 4.7.3 every-函数完全检测 Array.prototype.every() 检测数组中是否所有元素都可以通过检测函数验证。 var array1 = [ 1, 2, 3, 4, 5 ]; console.log(array1.every(x => x < 8)); //输出 true console.log(array1.every(x => x < 4)); //输出 false 查看示例程序 4.8 合并 4.8.1 join-合并成字符串 Array.prototype.join() 合并数组中所有元素成为字符串并返回。 var array1= [ 'a', 'b', 'c' ]; console.log(array1.join()); // 输出 a,b,c console.log(array1.join("-")); // 输出 a-b-c 查看示例程序 4.8.2 concat-合并成数组 Array.prototype.concat() 合并两个或多个数组,返回一个全新数组,原数组不变。 var array1 = [ 'a', 'b' ]; var array2 = [ 'c', 'd' ]; console.log(array1.concat(array2)); // 输出 [ "a", "b", "c", "d" ] 该方法可以有多个参数。 查看示例程序 4.9 累计 4.9.1 reduce-左侧累计 Array.prototype.reduce() 从左至右按 reducer 函数组合元素值,并返回累计器终值。 const array1 = [1, 2, 3, 4]; const reducer = (accumulator, currentValue) => accumulator + currentValue; // 1 + 2 + 3 + 4 console.log(array1.reduce(reducer)); // 输出 10 // 5 + 1 + 2 + 3 + 4 console.log(array1.reduce(reducer, 5)); // 输出 15,其中5是累计器初始值。 查看示例程序 4.9.2 reduceRight-右侧累计 Array.prototype.reduceRight() 从右至左按 reducer 函数组合元素值,并返回累计器终值。 const array1 = [1, 2, 3, 4]; const reducer = (accumulator, currentValue) => accumulator.concat(currentValue); console.log(array1.reduceRight(reducer)); // 输出 [ 4, 3, 2, 1 ] console.log(array1.reduceRight(reducer, 5)); // 输出 [ 5, 4, 3, 2, 1 ] 查看示例程序 4.10 copyWithin-内部复制 Array.prototype.copyWithin() 数组内部复制,不改变原数组长度。 var array1 = ['a', 'b', 'c', 'd', 'e','f']; console.log(array1.copyWithin(0, 3, 5)); // 输出 [ "d", "e", "c", "d", "e", "f" ] console.log(array1.copyWithin(1, 3)); // 输出 [ "d", "d", "e", "f", "e", "f" ] arr.copyWithin(target[, start[, end]]) 参数target : 表示要复制到的索引位置,如为负值则从后向前计数。 参数start : 表示要复制序列的起始索引位置,如为负值则从后向前计数。如省略该值,则从索引0开始。 参数end : 表示要复制序列的结束位置,如为负值则从后向前计数。如省略该值,则复制到结尾位置。 查看示例程序 4.11 fill-填充函数 Array.prototype.fill() 用固定值填充起始索引到终止索引区间内的全部元素值,不包括终止索引。 var array1 = [1, 2, 3, 4]; console.log(array1.fill(9, 2, 4)); // 输出 [ 1, 2, 9, 9 ] console.log(array1.fill(8, 1)); // 输出 [ 1, 8, 8, 8 ] console.log(array1.fill(7)); // 输出 [ 7, 7, 7, 7 ] 查看示例程序 4.12 filter-过滤函数 Array.prototype.filter() 生成由通过检测函数验证元素组成的新数组并返回。 var arr = [ 9 , 8 , 7 , 6]; console.log(arr.filter(x => x >7)); //输出 [ 9, 8 ] 查看示例程序 4.13 flat-数组扁平化 Array.prototype.flat() 按指定深度递归遍历数组,并返回包含所有遍历到的元素组成的新数组。不改变原数组。 var arr1 = [ 1, 2, [ 3, 4 ] ]; console.log(arr1.flat()); // 输出 [ 1, 2, 3, 4 ] var arr2 = [ 1, 2, [3, 4, [ 5, 6 ] ] ]; console.log(arr2.flat()); // 输出 [ 1, 2, 3, 4, [ 5, 6 ] ] var arr3 = [1, 2, [ 3, 4, [ 5, 6 ] ] ]; console.log(arr3.flat(2)); // 输出 [ 1, 2, 3, 4, 5, 6 ] 查看示例程序 4.14 map-映射 Array.prototype.map() 创建一个新数组,该数组中的元素由原数组元素调用map函数产生。 var array1 = [1, 2, 3, 4]; console.log(array1.map(x => x * 2)); // 输出 [ 2, 4, 6, 8 ] 查看示例程序 4.15 slice-截取数组 Array.prototype.slice() 按参数begin 和 end 截取数组,不改变原数组。 var array1 = [ 1, 2, 3, 4, 5]; console.log(array1.slice( 2, 4 )); //输出 [ 3, 4 ] console.log(array1); //输出 [ 1, 2, 3, 4, 5 ] 查看示例程序 5 结尾 5.1 结语 文中介绍的过于简单,想更多理解相关内容还是要多多动手实践! 因时间不足,能力有限等原因,存在文字阐述不准及代码测试不足等诸多问题。如发现错误请不吝指正!谢谢。
1 概述 1.1 前言 目前收集整理了21个常用的javaScript正则表达式,其中包括用户名、密码强度、整数、数字、电子邮件地址(Email)、手机号码、身份证号、URL地址、 IP地址、 十六进制颜色、 日期、 微信号、车牌号、中文正则等。表单验证处理必备,赶紧收藏吧! 还会陆续加入新的正则进来,大家多提宝贵意见! 2 正则列表 2.1 用户名正则 2.1.1 基本用户名正则 在做用户注册时,都会用到用户名正则校验。 定义基本用户名命名规则如下: 最短4位,最长16位 {4,16} 可以包含小写大母 [a-z] 和大写字母 [A-Z] 可以包含数字 [0-9] 可以包含下划线 [ _ ] 和减号 [ - ] 首字母只能是大小写字母 var pattern = /^[a-zA-Z][a-zA-Z0-9_-]{3,15}$/; //输出 true console.log("ifat3 : "+pattern.test('ifat3')); //输出 true console.log("Ifat3 : "+pattern.test('Ifat3')); //输出 true console.log("ke30 : "+pattern.test('ke30')); //输出 false console.log("30ke : "+pattern.test('30ke')); //输出 false console.log("ke3 : "+pattern.test('ke3')); 输出 false console.log("ke30@ : "+pattern.test('ke30@')); //输出 false console.log("ke30ke30ke30ke30ke30 : "+pattern.test('ke30ke30ke30ke30ke30')); 查看示例程序 2.1.2 中文用户名正则 如果规则中加入允许中文用户名,则变更正则表达式如下: var pattern = /^[a-zA-Z\u4E00-\u9FA5][a-zA-Z0-9\u4E00-\u9FA5_-]{3,15}$/; //输出 true console.log("ifat3 : "+pattern.test('ifat3')); //输出 true console.log("Ifat3 : "+pattern.test('Ifat3')); //输出 true console.log("三十课毛瑞 : "+pattern.test('三十课毛瑞')); //输出 false console.log("30ke : "+pattern.test('30ke')); //输出 false console.log("ke3 : "+pattern.test('ke3')); //输出 false console.log("ke30@ : "+pattern.test('ke30@')); //输出 false console.log("ke30ke30ke30ke30ke30 : "+pattern.test('ke30ke30ke30ke30ke30')); 其中[\u4E00-\u9FA5]是汉字的正则匹配,包括基本汉字2万多个,其中\u4E00表示汉字“一”,具体请参见《汉字unicode编码范围》。 查看示例程序 2.2 密码强度正则 //密码强度正则,最少6位,包括至少1个大写字母,1个小写字母,1个数字,1个特殊字符 var pPattern = /^.*(?=.{6,})(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*? ]).*$/; //输出 true console.log("iFat3#:"+pPattern.test("iFat3#")); 上述正则表达式只能对用户密码强度进行基本的通过性判定,关于密码强度验证更多的内容可参见:基于规则评分的密码强度检测算法分析及实现 。 查看示例程序 2.3 数字相关正则 2.3.1 整数正则 //正整数正则 var posPattern = /^\d+$/; //负整数正则 var negPattern = /^-\d+$/; //整数正则 var intPattern = /^-?\d+$/; //输出 true console.log("30:"+posPattern.test("30")); //输出 true console.log("-30:"+negPattern.test("-30")); //输出 true console.log("-30:"+intPattern.test("-30")); 查看示例程序 2.3.2 浮点数正则 //正浮点数正则 var posPattern = /^\d*\.\d+$/; //负浮点数正则 var negPattern = /^-\d*\.\d+$/; //两位小数正则 var twoPattern = /^-?\d*\.\d{2}$/; //输出 true console.log("30.2:"+posPattern.test("30.2")); //输出 true console.log("-30.2:"+negPattern.test("-30.2")); //输出 true console.log("-30.22:"+twoPattern.test("-30.22")); 查看示例程序 2.3.3 整数浮点数正则 可以是整数也可以是浮点数 //正数正则 var posPattern = /^\d*\.?\d+$/; //负数正则 var negPattern = /^-\d*\.?\d+$/; //数字正则 var numPattern = /^-?\d*\.?\d+$/; //输出 true console.log("30.2:"+posPattern.test("30.2")); //输出 true console.log("-30.2:"+negPattern.test("-30.2")); //输出 true console.log("-30.2:"+numPattern.test("-30.2")); 查看示例程序 2.4 日期正则 2.4.1 出生日期正则 var pattern = /^((19[2-9]\d{1})|(20((0[0-9])|(1[0-8]))))\-((0?[1-9])|(1[0-2]))\-((0?[1-9])|([1-2][0-9])|30|31)$/; //输出 true console.log(pattern.test("1923-3-18")); //输出 true console.log(pattern.test("1923-4-31")); //输出 true console.log(pattern.test("1923-2-29")); //输出 true console.log(pattern.test("2016-2-29")); 上述正则验证还不完善,主要是2,4,6,9,11月份的天数问题。 查看示例程序 2.4.2 通用日期正则 //日期正则,复杂判定 var dP2 = /^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$/; //输出 true console.log(dP2.test("2017-02-11")); //输出 false console.log(dP2.test("2017-15-11")); //输出 false console.log(dP2.test("2017-02-29")); 查看示例程序 2.5 Email正则 2.5.1 基本Email正则 var pattern = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/; //输出 true console.log(pattern.test('cn30ke@163.com')); //输出 true console.log(pattern.test('ifat3@sina.com.cn')); //输出 true console.log(pattern.test('ifat3.it@163.com')); //输出 true console.log(pattern.test('ifat3_-.@30ke.cn')); //输出 false console.log(pattern.test('ifat3@30ke.online')); //输出 false console.log(pattern.test('毛瑞@30ke.cn')); 基本Email正则是最常用的验证方式,也适合大多数的应用场景。从以上测试可以看出,该表达式不支持.online及.store结尾的域名。如需兼容这类域名(大于4位),调整正则结尾{2,4}的限制部分即可(例:{2,8})。另一个问题是Email用户名不能包括中文。 查看示例程序 2.5.2 中文名Email正则 根据前一正则中的问题,追加两条规则如下: 用户名可以包括中文 [\u4e00-\u9fa5] 域名结尾最长可为8位 {2,8} var pattern = /^([A-Za-z0-9_\-\.\u4e00-\u9fa5])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,8})$/; //输出 true console.log(pattern.test('cn30ke@163.com')); //输出 true console.log(pattern.test('ifat3@sina.com.cn')); //输出 true console.log(pattern.test('ifat3.it@163.com')); //输出 true console.log(pattern.test('ifat3_-.@30ke.cn')); //输出 true console.log(pattern.test('ifat3@30ke.online')); //输出 true console.log(pattern.test('毛瑞@30ke.cn')); 查看示例程序 2.5.3 特定域名Email正则 在手机验证码出现之前,差不多邮箱验证是保证用户唯一性的唯一条件。而临时邮箱(也称10分钟邮箱或一次性邮箱)的出现,则使得邮箱验证及帐户激活这种机制失去了意义。而临时邮箱的地址是不可枚举的,我们只能才采取白名单的方式,只允许有限的邮箱域名通过验证。 var pattern = /^([A-Za-z0-9_\-\.])+\@(163.com|qq.com|30ke.cn)$/; //输出 true console.log(pattern.test('cn30ke@163.com')); //输出 false console.log(pattern.test('ifat3@sina.com.cn')); //输出 true console.log(pattern.test('ifat3.it@163.com')); //输出 true console.log(pattern.test('ifat3_-.@30ke.cn')); //输出 false console.log(pattern.test('ifat3@30ke.online')); //输出 false console.log(pattern.test('毛瑞@30ke.cn')); 此方法虽然能保证验证安全性,但是如果白名单太长会造成模式字符串太长。这时可以将邮箱域名白名单写成数组,利用正则表达式做初步验证,用白名单做域名的二次验证。 常用域名白名单数组: var domains= ["qq.com","163.com","vip.163.com","263.net","yeah.net","sohu.com","sina.cn","sina.com","eyou.com","gmail.com","hotmail.com"]; 上述白名单只列举了常用的11种邮箱域名,大家可以根据需要适当补充或删减。 查看示例程序 2.6 手机号码正则 //手机号正则 var mPattern = /^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\d{8}$/; //输出 true console.log(mPattern.test("18600000000")); 查看示例程序 2.7 身份证号正则 //身份证号(18位)正则 var cP = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/; //输出 true console.log(cP.test("11010519880605371X")); 上述正则只能对身份证号进行基本的通过性判定,关于公民身份号码判定的更多内容可参见文档:公民身份号码正确性判定及程序实现 查看示例程序 2.8 URL正则 //URL正则 var urlP= /^((https?|ftp|file):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/; //输出 true console.log(urlP.test("http://30ke.cn")); 查看示例程序 2.9 IP地址 2.9.1 IPv4地址正则 //ipv4地址正则 var ipP = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; //输出 true console.log(ipP.test("115.28.47.26")); 查看示例程序 2.9.2 IPv6地址正则 //IPV6正则 var pattern = /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/; //输出 true console.log(pattern.test("fe80:0000:0000:0000:0204:61ff:fe9d:f156")); 查看示例程序 2.10 十六进制颜色正则 //RGB Hex颜色正则 var cPattern = /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/; //输出 true console.log(cPattern.test("#b8b8b8")); 查看示例程序 2.11 QQ号码正则 //QQ号正则,5至11位 var qqPattern = /^[1-9][0-9]{4,10}$/; //输出 true console.log(qqPattern.test("65974040")); 查看示例程序 2.12 微信号正则 //微信号正则,6至20位,以字母开头,字母,数字,减号,下划线 var wxPattern = /^[a-zA-Z]([-_a-zA-Z0-9]{5,19})+$/; //输出 true console.log(wxPattern.test("RuilongMao")); 查看示例程序 2.13 车牌号正则 //车牌号正则 var cPattern = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$/; //输出 true console.log(cPattern.test("京K39006")); 查看示例程序 2.14 包含中文正则 //包含中文正则 var cnPattern = /[\u4E00-\u9FA5]/; //输出 true console.log(cnPattern.test("30课")); 查看示例程序 3 结尾 3.1 结语 本人水平有限,如有错误,请不吝指正!谢谢。
1 概述 1.1 前言 选择器是CSS的核心组件。本文依据W3C的Selectors Level 4规范,概括总结了Level1-Level4中绝大多数的选择器,并做了简单的语法说明及示例演示。希望对程序员有所助益。 2 元素选择器 2.1 类型选择器-h1 类型选择器也可以称为标签名选择器,会选中文档中该类型元素的实例。 h1 { color: red; } 将文档中元素类型为h1的颜色设置成红色。 查看示例程序 2.2 通配选择器-* 通用选择器是一种特殊类型选择器,表示任何元素类型的元素。 * { color: red; } 设置文档中所有元素的颜色为红色。 3 属性选择器 3.1 属性存在选择器-[name] h1[name] { color: red; } 选中元素 h1 中具有属性 name 的元素。 查看示例程序 3.2 属性值选择器 3.2.1 确切匹配-[title='cool'] h1[title='cool'] { color: red; } 匹配元素 h1 中包含属性 title 并且属性值是 cool 的元素。 查看示例程序 3.2.2 包含匹配-[title|='cool'] h1[title~='cool'] { color: red; } 匹配元素 h1 中包含属性 title 并且属性值中包含 cool 的元素。 查看示例程序 3.2.3 头部匹配-[title^='cool'] h1[title|='cool'] { color: red; } 匹配元素 h1 中包含属性 title ,并且属性值是 cool 的元素 或以 cool- 开头的元素。 查看示例程序 3.3 属性值子串选择器 3.3.1 头部匹配-[title^='cool'] h1[title^='cool'] { color: red; } 匹配元素 h1 中包含属性 title ,并且属性值串以 cool 开头的元素。 查看示例程序 3.3.2 尾部匹配-[title$='cool'] h1[title$='cool'] { color: red; } 匹配元素 h1 中包含属性 title ,并且属性值串以 cool 结尾的元素。 查看示例程序 3.3.3 部分匹配-[title*='cool'] h1[title*='cool'] { color: red; } 匹配元素 h1 中包含属性 title ,并且属性值串包含 cool 子串的元素。 查看示例程序 3.4 类选择器-.class .red { color: red; } 匹配文档中 class 属性为 red 的元素并设置其颜色为红色。 查看示例程序 3.5 ID选择器-#id #title { color: red; } 匹配文档中 id 属性为 title 的元素并设置其颜色为红色。 查看示例程序 4 语言学伪类 4.1 方向性伪类:dir dir() 主要用于匹配符合某个方向性的元素,例如 :dir(ltr) 和 :dir(rtl),其中ltr是left to right简写,表示从左向右,而rtl是right to left,表示从右向左。 :dir(ltr) { color: red; } 匹配文字方向为从左到右的元素。 查看示例程序 4.2 语言伪类:lang :lang(fr) { color: red; } 匹配语言为法语的元素并设置其颜色为红色。 查看示例程序 5 位置伪类 5.1 超链接伪类:any-link 匹配带有 href 属性的 <a>、<link>、<area>等元素。 :any-link { color: red; } 匹配任意超链接,并设置其颜色为红色。 查看示例程序 5.2 超链接伪类:link :link { color: red; } 匹配未被访问的超链接,并设置其颜色为红色。 5.3 超链接伪类:visited :visited { color: blue; } 匹配访问过的超链接,并设置其颜色为蓝色。 查看示例程序 5.4 超链接伪类:local-link :local-link { color: red; } 匹配本地超链接,并设置其颜色为红色。 5.5 目标伪类:target <h1><a href="#content">三十课</a></h1> <p id="content">程序员的笔记本</p> <p id="content2">程序员的笔记本2</p> :target { color: red; } 点击 html 代码中的内部链接,链接的目标对象 id 为 content 的 p元素颜色变为红色。 6 用户行为伪类 6.1 用户行为伪类:hover 用户指针设备悬停于指定元素时,匹配该元素。 :hover { color: red; } 用户指针悬停于某元素,匹配该元素并将其设置其颜色为红色。 查看示例程序 6.2 用户行为伪类:active :active { background: red; } 当特定元素处于激活状态时,设置元素背景色为红色。 查看示例程序 6.3 用户行为伪类:focus :focus { background: red; } 当特定元素获得焦点,设置元素背景色为红色。 查看示例程序 6.4 用户行为伪类:focus-within div:focus-within { border : 1px solid blue; } 当div中的子元素获得输入焦点时,设置div元素边框为1象素值的蓝色边框。 查看示例程序 7 时间轴伪类 7.1 时间伪类:current 在文档的语音渲染或是显示字幕期间,常会用到时间轴伪类。 :current(p) { color: red; } 以上规则定义了当前语音渲染段落的颜色为红色。 7.2 时间伪类:past :past(p) { color: red; } 以上规则定义了以完成语音渲染段落的颜色为蓝色。 7.3 时间伪类:future :future(p) { color: yellow; } 以上规则定义了以未进行语音渲染段落的颜色为黄色。 8 资源状态伪类 8.1 资源状态伪类:playing :playing { border : 1px solid red; } 匹配当前播放状态的元素,并为其添加1象素的红色边框。 8.2 资源状态伪类:paused :playing { border : 1px solid grey; } 匹配当前播放状态的元素,并为其添加1象素的灰色边框。 9 输入伪类 9.1 输入状态控制伪类:enabled :enabled { color: red; } 匹配启用状态的元素并设置其颜色为红色。 9.2 输入状态控制伪类:disabled :disabled{ color: yellow; } 匹配禁用状态的元素并设置其颜色为黄色。 查看示例程序 9.3 只读伪类:read-only :read-only { color: red; } 匹配只读状态的元素并设置其颜色为红色。 9.4 读写伪类:read-write :read-write { color: yellow; } 匹配读写状态的元素并设置其颜色为黄色。 查看示例程序 9.5 伪类:placeholder-shown :placeholder-shown { background: red; } 选中占位符为显示状态的元素并设置其背景色为红色。 查看示例程序 9.6 缺省项伪类:default :default { color: red; } 匹配缺省的元素并设置其颜色为红色。 查看示例程序 9.7 选中项伪类:checked :checked { height: 4em; } 匹配选中的元素并将其高度设成 4em。 查看示例程序 9.8 不确定值伪类:indeterminate 不确定值伪类 :indeterminate 适用于其值处在不确定状态的元素。例如 : radio 元素组在未被初始选择的情况下就为不确定值状态。 :indeterminate { height: 4em; } 匹配不确定值元素并设置高度为 4em。 查看示例程序 9.9 空值伪类:blank 空值伪类 :blank 用来匹配输入值为空的输入框,如 textarea 或 input 框。 :blank { background: red; } 目前该伪类兼容性较差。 9.10 合规性验证伪类:valid :valid { color: red; } 匹配输入值合法的元素并设置其颜色为红色。 9.11 合规性验证伪类:invalid :valid { color: blue; } 匹配输入值不合法的元素并设置其颜色为蓝色。 查看示例程序 9.12 范围伪类:in-range :in-range { color: red; } 匹配输入值在定义范围内的元素并设置其颜色为红色。 9.13 范围伪类:out-of-range :out-of-range { color: blue; } 匹配输入值不在定义范围内的元素并设置其颜色为蓝色。 查看示例程序 9.14 必填项伪类:required :required { color: red; } 匹配定义为必填项的元素并设置其颜色为红色。 9.15 选填项伪类:optional :optional { color: blue; } 匹配定义为选填项的元素并设置其颜色为蓝色。 查看示例程序 10 树形结构伪类 10.1 根结点伪类:root 伪类 :root 表示文档的根元素。例如,在DOM文档中,伪类 :root 与Document对象的根元素匹配。 在HTML中,就表示html元素。 :root { color: red; } 匹配文档根元素并定义其颜色为红色。 查看示例程序 10.2 空伪类:empty :empty { color : red; } 匹配为空的元素并设置其颜色为红色。 查看示例程序 10.3 元素索引伪类:nth-child p:nth-child(3n+1) { color: red; } 匹配第1,4,7,10等 p 元素并设置其颜色为红色。 查看示例程序 10.4 元素索引伪类:nth-last-child p:nth-child(3n+1) { color: red; } 匹配倒数第1,4,7,10等 p 元素并设置其颜色为红色。 查看示例程序 10.5 首元素伪类:first-child p:first-child { color: red; } 匹配第一个 p 元素并设置其颜色为红色。 查看示例程序 10.6 尾元素伪类:last-child p:last-child { color: red; } 匹配最后一个 p 元素并设置其颜色为红色。 查看示例程序 10.7 唯一子元素伪类:only-child p:only-child { color: red; } 匹配父元素只包含唯一子元素的元素 p 并设置其颜色为红色。 查看示例程序 10.8 类型索引伪类:nth-of-type p:nth-of-type(3n+1) { color: red; } 匹配类型为 p 的第1,4,7,10等索引位置的元素并设置其颜色为红色。 查看示例程序 10.9 类型索引伪类:nth-last-of-type p:nth-last-of-type(3n+1) { color: red; } 匹配类型为 p 的倒数第1,4,7,10等索引位置的元素并设置其颜色为红色。 查看示例程序 10.10 类型首元素伪类:first-of-type p:first-of-type { color: red; } 匹配第一个类型为 p 的元素并设置及颜色为红色。 查看示例程序 10.11 类型尾元素伪类:last-of-type p:last-of-type { color: red; } 匹配倒数第一个类型为 p 的元素并设置及颜色为红色。 查看示例程序 10.12 唯一类型元素伪类:only-of-type p:only-of-type { color: red; } 匹配父元素只包含唯一类型为 p 子元素并设置其颜色为红色。 查看示例程序 11 逻辑组合选择器 11.1 分组选择器 h1 { color: red } h2 { color: red } h3 { color: red } h4 { color: red } 利用分组选则器,可以将上述CSS规则简写成下面的形式。 h1,h2,h3,h4 { color: red } 上述两种写法效果相同。 11.2 逻辑组合伪类:is 伪类 :is() 是一个以多个选择器做为参数的函数,匹配由其参数表示的元素。 目前兼容性较差。 *:is(:hover, :focus) { color: red; } 匹配伪类 hover 和 focus 的元素并设置其颜色为红色。 11.3 逻辑组合伪类:not 负向逻辑组合伪类 :not() 是一个以多个选择器做为参数的函数,匹配不在其参数表中的元素。 目前兼容性较差。 button:not([DISABLED]) { color : red; } 匹配不包含 DISABLED 属性的 button 元素并设置其颜色为红色。 11.4 逻辑组合伪类:has 目前兼容性较差。 a:has(> img) { border : 1px solid red; } 匹配包含 img 子元素的超链接并设置其边框为1象素红色。 12 组合选择器 12.1 后代选择器 h1 em { color: red; } 匹配 h1 的后代的 em 元素并设置其颜色为红色。 查看示例程序 12.2 子元素选择器-> h1 > em { color: red; } 匹配 h1 的子元素 em 并设置其颜色为红色。 查看示例程序 12.3 相邻兄弟选择器-+ h1 + h2 { color: red; } 匹配 h1 的相邻兄弟元素 h2 并设置其颜色为红色。 查看示例程序 12.4 兄弟选择器-~ h1 ~ h2 { color: red; } 匹配 h1 的后面的同级结点 h2 并设置其颜色为红色。 查看示例程序 13 结尾 13.1 参考文献 W3C Working Draft : Selectors Level 4 - 21 November 2018 W3scool : CSS 选择器参考手册 菜鸟教程 :CSS 选择器 MDN : CSS Selectors 13.2 结语 本文是@毛瑞依据CSS选择器规范4择取的部分CSS选择器内容编写而成。因本人水平有限,理解和翻译时难免有偏差和错误,还请程序员朋友多多指正! 文中一些选择器兼容性还很差,只能做为学习储备,不适用于实际产品中运用。 费力原创十分不易,请大家转载时一定要明确注明出处来自【三十课】!
引言 对我来说,table 有一个非常有用,支持性也很好的 CSS 属性,但它却很少为人所知。它改变了表格的渲染方式,并生成一个更加稳定可靠的布局。 它就是: table { table-layout: fixed; } table-layout的缺省值是 auto,这个属性值及其效果大家十分熟悉。对我来说其效果十分的怪异,具体见如下演示: 查看演示效果 fixed属性值 应用 table-layout: fixed之后,查看演示效果,可以得出如下结论: 给单元格指定的宽度值生效 overflow 属性生效 text-overlfow 属性生效 查看演示效果 用例及分析 我们以一个用户信息表格为例子进行演示。该表格的列宽是固定的,不根据内容的多少而变化;表格内容不折行显示,超出行宽部分加省略号部分显示。 查看演示效果 上述表格的显示效果已经很好了,也比较接近实际项目的需要。 固定列宽的表格算法效果更容易预见,便于使用,同时渲染速度明显更快。因为表格的内容并不会影响单元格的宽度,所以在页面加载过程中,表格不需要频繁重绘。相信我们都对页面加载过程中表格不断重新调整列宽的恐怖情景记忆犹新。对于固定列宽的表格来说,这种情况就不会发生了。 本文主要汇编自 Chris Coyier 的一篇博客。但是因为本人水平有限,文中难免存在描述不清,代码不完善等问题,还请大家多多予以批评指正! 参考文献 Fixed Table Layouts MDN table-layout CSS-trick table-layout
前言 设计师可以分为如下两类: 先做好设计,然后将内容放入静态框架中 优秀的设计师充分考虑内容的各个方面及其上下文,并创建适合于内容的设计 HTML原生就是响应式的(HTML内容在视口内流式的分布)。随着CSS的广泛应用,设计者创建了许多固定布局的“盒子”并把内容强制的放在盒子之中,这有悖于HTML原生响应的特性。 过去几年出现了一场革命,包括自适应设计,响应式设计,移动优先设计等。所有这些思想最根本部分就是优先考虑内容。CSS3也因此定义和实现一些新的属性。其中就包括内在和外在的宽度(intrinsic and extrinsic width values)。 引入问题 我们以一个常规的 WEB 页面设计问题(figure 元素内的图片)来引出问题并加以说明。 <figure> <img src="o4iaq1g8nr.jpg" /> <figcaption>www.30ke.cn</figcaption> <p>三十客 - 一个专注于前端学习和分享的网站。</p> </figure> 因为figure是块级标记,所以元素一直延伸到至整个容器中。 在以内容优先的设计中,我们通常希望容器 (本例中为 figure元素) 尽可能小。 到目前为止,有几种方法可以实现。 figure { float: left; } 通过设置浮动,可以实现 figure 元素折叠。但是如果 figure 中的 p (段落)元素宽于图片宽度,则figure元素会收缩至最宽的子元素,而不是图片的宽度。使用display: inline-block 或 table-cell 同样有上述问题。 figure { width: 500px; } 将 figure 元素写死一个宽度,但这使得元素固定并失去响应特性。 用 min-width 来帮忙 我们最终就是要找到最优的图片容器的宽度以最达到最好的适应内部图片的目的。如果内部的文本换行显示也没关系。 我们可以通过 min-content 来达到目的。尽管该值 2006 年就出现了,但还处在实验阶段,因此需要添加不同浏览器前缀。 figure { border: 2px solid black; background: #cae9b8; margin: 0; width: -moz-min-content; width: -webkit-min-content; width: min-content; } 上述代码,很好的解决了上述问题。而且 margin 和 padding 在图片容器内部仍然有效。 min-content 是内在和外在的宽高系列值中的一个,其它还包括 max-content , fit-content等。这些值和 flexbox ,grid 和其它布局系统,使得WEB设计更优秀更灵活。min-content 的支持性很好,所有现代主流浏览器都支持该值,但是 Internet Explorer and Opera Mini 并不支持。 因此我们借助 max-widht 实现了回退的方案。 figure { max-width: 500px; max-width: min-content; } 完整的带回退的显示方案见如下演示程序: 在线演示程序 原文地址 本文主要汇编自 Dudley Storey 的一篇博客,并加入了针对Internet Explorer and Opera Mini 的回退方案。但是因为本人水平有限,文中难免存在描述不清,代码不完善等问题,还请大家多多予以批评指正! 参考文献 CSS Intrinsic & Extrinsic Sizing Module Level 3Design From the Inside Out With CSS Min-Contentplay.csssecrets.io/
简言 CSS居中是前端工程师经常要面对的问题,也是基本技能之一。今天有时间把CSS居中的方案汇编整理了一下,目前包括水平居中,垂直居中及水平垂直居中方案共15种。如有漏掉的,还会陆续的补充进来,算做是一个备忘录吧。 1 水平居中 1.1 内联元素水平居中 利用 text-align: center 可以实现在块级元素内部的内联元素水平居中。此方法对内联元素(inline), 内联块(inline-block), 内联表(inline-table), inline-flex元素水平居中都有效。 核心代码: .center-text { text-align: center; } 演示程序: 演示代码 1.2 块级元素水平居中 通过把固定宽度块级元素的margin-left和margin-right设成auto,就可以使块级元素水平居中。 核心代码: .center-block { margin: 0 auto; } 演示程序: 演示代码 1.3 多块级元素水平居中 1.3.1 利用inline-block 如果一行中有两个或两个以上的块级元素,通过设置块级元素的显示类型为inline-block和父容器的text-align属性从而使多块级元素水平居中。 核心代码: .container { text-align: center; } .inline-block { display: inline-block; } 演示程序: 演示代码 1.3.2 利用display: flex 利用弹性布局(flex),实现水平居中,其中justify-content 用于设置弹性盒子元素在主轴(横轴)方向上的对齐方式,本例中设置子元素水平居中显示。 核心代码: .flex-center { display: flex; justify-content: center; } 演示程序: 演示代码 2 垂直居中 2.1 单行内联(inline-)元素垂直居中 通过设置内联元素的高度(height)和行高(line-height)相等,从而使元素垂直居中。 核心代码: #v-box { height: 120px; line-height: 120px; } 演示程序: 演示代码 2.2 多行元素垂直居中 2.2.1 利用表布局(table) 利用表布局的vertical-align: middle可以实现子元素的垂直居中。 核心代码: .center-table { display: table; } .v-cell { display: table-cell; vertical-align: middle; } 演示程序: 演示代码 2.2.2 利用flex布局(flex) 利用flex布局实现垂直居中,其中flex-direction: column定义主轴方向为纵向。因为flex布局是CSS3中定义,在较老的浏览器存在兼容性问题。 核心代码: .center-flex { display: flex; flex-direction: column; justify-content: center; } 演示程序: 演示代码 2.2.3 利用“精灵元素” 利用“精灵元素”(ghost element)技术实现垂直居中,即在父容器内放一个100%高度的伪元素,让文本和伪元素垂直对齐,从而达到垂直居中的目的。 核心代码: .ghost-center { position: relative; } .ghost-center::before { content: " "; display: inline-block; height: 100%; width: 1%; vertical-align: middle; } .ghost-center p { display: inline-block; vertical-align: middle; width: 20rem; } 演示程序: 演示代码 2.3 块级元素垂直居中 2.3.1 固定高度的块级元素 我们知道居中元素的高度和宽度,垂直居中问题就很简单。通过绝对定位元素距离顶部50%,并设置margin-top向上偏移元素高度的一半,就可以实现垂直居中了。 核心代码: .parent { position: relative; } .child { position: absolute; top: 50%; height: 100px; margin-top: -50px; } 演示程序: 演示代码 2.3.2 未知高度的块级元素 当垂直居中的元素的高度和宽度未知时,我们可以借助CSS3中的transform属性向Y轴反向偏移50%的方法实现垂直居中。但是部分浏览器存在兼容性的问题。 核心代码: .parent { position: relative; } .child { position: absolute; top: 50%; transform: translateY(-50%); } 演示程序: 演示代码 3 水平垂直居中 3.1 固定宽高元素水平垂直居中 通过margin平移元素整体宽度的一半,使元素水平垂直居中。 核心代码: .parent { position: relative; } .child { width: 300px; height: 100px; padding: 20px; position: absolute; top: 50%; left: 50%; margin: -70px 0 0 -170px; } 演示程序: 演示代码 3.2 未知宽高元素水平垂直居中 利用2D变换,在水平和垂直两个方向都向反向平移宽高的一半,从而使元素水平垂直居中。 核心代码: .parent { position: relative; } .child { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } 演示程序: 演示代码 3.3 利用flex布局 利用flex布局,其中justify-content 用于设置或检索弹性盒子元素在主轴(横轴)方向上的对齐方式;而align-items属性定义flex子项在flex容器的当前行的侧轴(纵轴)方向上的对齐方式。 核心代码: .parent { display: flex; justify-content: center; align-items: center; } 演示程序: 演示代码 3.4 利用grid布局 利用grid实现水平垂直居中,兼容性较差,不推荐。 核心代码: .parent { height: 140px; display: grid; } .child { margin: auto; } 演示程序: 演示代码 3.5 屏幕上水平垂直居中 屏幕上水平垂直居中十分常用,常规的登录及注册页面都需要用到。要保证较好的兼容性,还需要用到表布局。 核心代码: .outer { display: table; position: absolute; height: 100%; width: 100%; } .middle { display: table-cell; vertical-align: middle; } .inner { margin-left: auto; margin-right: auto; width: 400px; } 演示程序: 演示代码 4 说明 文中所述文字及代码部分汇编于网络。因时间不足,能力有限等原因,存在文字阐述不准及代码测试不足等诸多问题。因此只限于学习范围,不适用于实际应用。 文中所述方案只是居中方案其中的一部分,并不是全部。另代码中涉及CSS3的flex,transform,grid等内容都存在兼容性问题。 5 引用参考 Centering in CSS: A Complete Guide w3.org centering things How To Center Anything With CSS 如何使DIV在屏幕上水平垂直居中显示?
简言 用正则表达式做用户密码强度的通过性判定,过于简单粗暴,不但用户体验差,而且用户帐号安全性也差。那么如何准确评价用户密码的强度,保护用户帐号安全呢?本文分析介绍了几种基于规则评分的密码强度检测算法,并给出了相应的演示程序。大家可以根据自己项目安全性需要,做最适合于自己的方案选择。 1 方案1 (简单) 方案1算法通过密码构成分析,结合权重分派,统计得出密码强度得分。得分越高,表示密码强度越大,也就越安全。方案1算法思想简单,实现容易。 1.1 方案1评分标准 一、密码长度: 5 分: 小于等于4 个字符 10 分: 5 到7 字符 25 分: 大于等于8 个字符 二、字母: 0 分: 没有字母 10 分: 全都是小(大)写字母 20 分: 大小写混合字母 三、数字: 0 分: 没有数字 10 分: 1 个数字 20 分: 大于1 个数字 四、符号: 0 分: 没有符号 10 分: 1 个符号 25 分: 大于1 个符号 五、奖励: 2 分: 字母和数字 3 分: 字母、数字和符号 5 分: 大小写字母、数字和符号 1.2 方案1等级划分 根据密码评分,将密码划分成以下7个等级: >= 90: 非常安全(VERY_SECURE) >= 80: 安全(SECURE) >= 70: 非常强(VERY_STRONG) >= 60: 强(STRONG) >= 50: 一般(AVERAGE) >= 25: 弱(WEAK) >= 0: 非常弱( VERY_WEAK) 该评分标准及等级划分,实际使用时,可小做调整,但不建议做大的变动。 1.3 方案1演示程序 演示程序 1.4 方案1测试分析 // 评分 25,纯小写字母无法通过验证 console.log("aaaaaaaa".score()); // 评分 45,纯数字无法通过验证 console.log("11111111".score()); // 评分 47,小写+数字无法通过验证 console.log("aa111111".score()); // 评分 45,小写+大写无法通过验证 console.log("aaaaAAAA".score()); // 评分 50,4位密码不可能通过验证 console.log("11!!".score()); // 评分 70,5位密码可通过验证 console.log("0aA!!".score()); // 评分 67,小写+大写+数字可通过验证(8位) console.log("aA000000".score()); // 评分 70,数字+符号可通过验证 console.log("000000!!".score()); 从以上测试结果中,我们可以看出算法是十分的有效的,基本能够保证密码具有一定的安全性。但是存在的问题也很明显,其中最主要的问题是对重复或连续的字符评分过高。以测试用例中最后一个为例: 000000!! 可以得到70分,但显然并不是一个非常强壮的密码。 另外,方案1最高可以得到95分,也就是说没有100分(绝对安全)的密码,这一点也是很有智慧的设计。 2 方案2 针对方案1中的不足,方案2中引入了减分机制。对于重复出现,连续出现的字符给予适当的减分,以使得密码评分更准确。同时在方案2中密码的评分基数及计算过程都十分的复杂,要想理解其中每一步的含义,请保持足够的耐心。 2.1 方案2加分项 一、密码长度: 公式 :+(n*4),其中n表示密码长度 二、大写字母: 公式:+((len-n)*2),其中n表示大写字母个数,len表示密码长度 三、小写字母: 公式:+((len-n)*2),其中n表示小写字母个数,len表示密码长度 四、数字: 公式:+(n*4),其中n表示数字个数 条件:满足n < len,才能得到加分,len表示密码长度 五、符号: 公式:+(n*6),其中n表示符号个数 六、位于中间的数字或符号: 公式:+(n*2),其中n表示位于中间的数字或符号个数 七、最低条件得分: 公式:+(n*2),其中n表示满足的最低条件条目数 条件:只有满足最低条件,才能得到加分 其中最低条件的条目如下: 1.密码长度不小于8位 2.包含大写字母 3.包含小写字母 4.包含数字 5.包含符号 最低条件要求满足条目1并至少满足条目2-5中的任意三条。 2.2 方案2减分项 一、只有字母: 公式:-n,其中n表示字母个数 二、只有数字: 公式:-n,其中n表示数字个数 三、重复字符数(大小写敏感): 该项描述复杂,具体计算方法见如下示例程序: var pass = "1111aaDD"; //示意密码 var repChar = 0; var repCharBonus = 0; //得分 var len = pass.length; for(var i = 0; i < len; i++) { var exists = false; for (var j = 0; j < len; j++) { if (pass[i] == pass[j] && i != j) { exists = true; repCharBonus += Math.abs(len/(j-i)); } } if (exists) { repChar++; var unqChar = len - repChar; repCharBonus = (unqChar) ? Math.ceil(repCharBonus/unqChar) : Math.ceil(repCharBonus); } } 四、连续大写字母: 公式:-(n*2),其中n表示连续大写字母出现的次数 举例:如输入AUB,则n=2 五、连续小写字母: 公式:-(n*2),其中n表示连续小写字母出现的次数 举例:如输入aub,则n=2 六、连续数字: 公式:-(n*2),其中n表示连续数字出现的次数 举例:如输入381,则n=2 七、正序或逆序字母: 公式:-(n*3),其中n表示连续发生的次数 正序或逆序是指字母表中的顺序 不区分大小写 条件:只有连续3个字母或以上,才会减分, 例1:如输入ABC,则n=1 例2:如输入dcBA,则n=2 八、正序或逆序数字: 公式:-(n*3),其中n表示连续发生的次数 条件:只有连续3个数字或以上,才会减分 例1:如输入123,则n=1, 例2:如输入4321,则n=2 例3:如输入12,则不会减分 九、正序或逆序符号: 公式:-(n*3),其中n表示连续发生的次数 条件:只有连续3个符号或以上,才会减分 2.3 方案2等级划分 根据密码评分,将密码划分成以下5个等级: >= 80: 非常强(VERY_STRONG) >= 60: 强(STRONG) >= 40: 好(GOOD) >= 20: 弱(WEAK) >= 0: 非常弱( VERY_WEAK) 2.4 方案2演示程序 演示程序 2.5 方案2测试分析 // 评分 0 console.log("11111111".score()); // 评分 2 console.log("aa111111".score()); // 评分 38 console.log("000000!!".score()); // 评分 76 console.log("Asdf2468".score()); // 评分 76 console.log("Mary2468".score()); // 评分 60 console.log("@dmin246".score()); 从以上测试可以看出方案2较方案1有了比较大的改进和提升,尤其是对连续或重复字符上表现出色。但是方案2也存在明显的不足,主要缺点包括对人名(Mary)、单词(Story)、键盘上相连的键(Asdf)、L33T(@dmin)没法识别。 L33T:是指把拉丁字母换成数字或是特殊符号的书写形式。例如把E写成3、A写成@、to写成2、for写成4。 3 方案3 zxcvbn 3.1 简要说明 针对方案2中的不足,引入了方案3,进一步的提长密码强度。方案3完全引入一个第三方检验工具zxcvbn。 zxcvbn是一个受密码破解启发而来的密码强度估算器。它通过模式匹配和保守估计,大概可以识别大约30K左右的常规密码。主要基于美国人口普查数据,维基,美国电影,电视流行词以及其它一些常用模式,像日期,重复字符,序列字符,键盘模式和L33T会话等。 从算法的设计思想上,该方案完全秒杀基于构成的统计分析方法(前两种方法)。同时zxcvbn支持多种开发语言。因其模式的复杂及字典的存在,当前版本的zxcvbn.js大约有800多K。 要了解项目的详情及算法见zxcvbn官网: github zxcvbn 3.2 方案3演示程序 演示程序 以上是三胖对密码强度检测算法和方案的理解和分析,不足之处还请大家多多指正! 原文链接
简言 目前最优雅地实现多重边框的方案是利用CSS3 的 box-shadow属性,但如果要兼容老的浏览器,则需要选择其它的方案。本文简要地列举了几种多重边框的实现方案,大家可以根据项目实际及兼容性要求等情况,选择最适合的实现方案。 1 利用描边(outline)属性 方案1利用描边(outline)属性结合border属性实现双重边框。此方案实现简单,兼容性好,能兼容除IE6,7以外的浏览器。 1.1 核心代码 .borders { border: solid 6px #fff; outline: solid 6px #888; } 1.2 演示程序 演示程序 1.3 说明 只能实现双重边框 边框样式灵活,可以实现虚线等样式的边框 描边在盒模型之外,会与外部元素发生重叠 2 利用额外的DIV 方案2利用额外的DIV嵌套的方式实现多重边框。这也是唯一不存在兼容性问题的方案。 2.1 核心代码 .outer { border: solid 6px #888; background: #fff; } .inner { background: #222; margin: 6px; } 2.2 演示程序 演示程序 2.3 说明 兼容性好 可以实现多重边框,虚线边框等样式 需要额外的DIV元素,增加了代码复杂性 3 利用伪元素 方案3利用伪元素(:before)的方式实现双重边框。实现代码略复杂,属于hack的实现方式,不推荐。 3.1 核心代码 .borders { border: solid 6px #fff; position: relative; } .borders:before { content: ""; position: absolute; top: -12px; left: -12px; right: -12px; bottom: -12px; border: solid 6px #888; } 3.2 演示程序 演示程序 3.3 说明 IE6,7,8不兼容 用:after也可以 同时应用:before和:after可以实现三重边框 4 利用border-image属性 方案4利用CSS3的border-image属性实现多重边框。实现方法简单,但需要制做一个额外的边框图片,兼容性较差。 4.1 核心代码 .borders { border: solid 12px transparent; border-image: url('borders.jpg') 12 12 12 12 repeat; } 4.2 演示程序 演示程序 4.3 说明 本例中,利用border-image-slice将边框图片分成如下图所示的9个区域: 其中包括四个角(1,2,3,4),四条边(5,6,7,8)以及中间区域(9)。repeat表示四条边都在相应的边框上重复的平铺。 5 利用box-shadow属性 方案5利用box-shadow属性实现多重边框。方案5是最简单,最直接的实现多重边框的方式。只有一行代码就可以实现多重边框效果。利用了阴影(box-shadow)实现边框多少有一些hack的味道。 5.1 核心代码 .borders { box-shadow: 0 0 0 6px #fff, 0 0 0 12px #888; } 5.2 演示程序 演示程序 5.3 说明 为了用阴影模拟边框,本例中使用了两个阴影效果,设置偏移值和模糊值为0,并适当地设置阴影的尺寸,从而实现了双重边框的效果。因为一个阴影重叠在另一个阴影之上,第二个阴影的尺寸要设置成第一个阴影尺寸的两倍。关键部分是将模糊值设成0,从而产生像边框一样的纯色阴影,看起来和边框一样。 和描边(outline)属性一样,box-shadow属性可能会和周边元素发生重叠,因此要适当地设置元素的外边距。box-shadow兼容性一般。 6 参考 MDN border-image MDN box-shadow Multiple Borders with CSS CSS-tricks Multiple Borders 7 结语 本文简述了5种多重边框的实现方式,各有优缺点,大家要根据实际情况进行取舍。 文中所述部分文字及代码汇编于网络。因时间不足,能力有限等原因,存在文字阐述不准及代码测试不足等诸多问题。
简言 在做用户实名验证时,常会用到身份证号码的正则表达式及校验方案。本文列举了两种验证方案,大家可以根据自己的项目实际情况,选择适合的方案。 身份证号码说明 居民身份证号码,正确、正式的称谓应该是“公民身份号码”。根据【中华人民共和国国家标准 GB 11643-1999】中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。 以北京市朝阳区一女性身份证号码为例,身份证号码所表示的含义如下图所示: 注:该身份证号码来源于国标【GB 11643-1999】。 下面我们就从零开始完成一个完整的身份证号码校验过程。 方案1 (简单) 1.1 分部规则 我们首先提出方案1,并分步做如下规则定义: 1.1.1 地址码规则: 地址码长6位 以数字1-9开头 后5位为0-9的数字 根据以上规则,写出地址码的正则表达式: /^[1-9]\d{5}/ 1.1.2 年份码规则: 年份码长4位 以数字18,19或20开头 剩余两位为0-9的数字 根据以上规则,写出年份码的正则表达式: /(18|19|20)\d{2}/。如果不需要18开头的年份,可以去掉18。 1.1.3 月份码规则: 月份码长2位 第一位数字为0,第二位数字为1-9 或者第一位数字为1,第二位数字为0-2 根据以上规则,写出月份码的正则表达式: /((0[1-9])|(1[0-2]))/。 1.1.4 日期码规则: 日期码长2位 第一位数字为0-2,第二位数字为1-9 或者是10,20,30,31 根据以上规则,写出日期码的正则表达式 :/(([0-2][1-9])|10|20|30|31)/。 1.1.5 顺序码规则: 顺序码长3位 顺序码是数字 根据以上规则,写出顺序码的正则表达式 :/\d{3}/。 1.1.6 校验码规则: 校验码长1位 可以是数字,字母x或字母X 根据以上规则,写出校验码的正则表达式 :/[0-9Xx]/。 1.2 方案1正则表达式 综合以上6条规则,给出完整的正则表达式及测试程序如下: var p = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/; //输出 true console.log(p.test("11010519491231002X")); //输出 false 不能以0开头 console.log(p.test("01010519491231002X")); //输出 false 年份不能以17开头 console.log(p.test("11010517491231002X")); //输出 false 月份不能为13 console.log(p.test("11010519491331002X")); //输出 false 日期不能为32 console.log(p.test("11010519491232002X")); //输出 false 不能以a结尾 console.log(p.test("11010519491232002a")); 演示代码 1.3 方案1分析 方案1只是做了基本的格式判定,存在三个主要的不足: 地址码判定不够精确。例:我国并不存在16,26开头的地区,却可通过验证 日期判定不够精确。例:19490231也可通过验证,而2月并不存在31日 校验码是由17位本体码计算得出,方案1并未校验此码 方案2 (全面) 根据方案1的不足,引入方案2进而改进方案1的不足。 2.1 省级地址码校验 华北:北京11,天津12,河北13,山西14,内蒙古15 东北: 辽宁21,吉林22,黑龙江23 华东: 上海31,江苏32,浙江33,安徽34,福建35,江西36,山东37 华中: 河南41,湖北42,湖南43 华南: 广东44,广西45,海南46 西南: 四川51,贵州52,云南53,西藏54,重庆50 西北: 陕西61,甘肃62,青海63,宁夏64,新疆65 特别:台湾71,香港81,澳门82 根据上述地址码做身份证号码的前两位校验,进一步的提高准确率。当前的地址码以2013版的行政区划代码【GB/T2260】为标准。由于区划代码的历史演变,使得地址码后四位校验变得不太可能。以三胖的身份证号为例,本人号码是2321开头,而当前行政区划代码表中并无此代码。因此本文只做前两位省级地址码的校验。 也有说法表述91开头是外国人取得中国身份证号码的前两位编码,但本人并未得到证实。如有持91开头身份证或认识马布里的,请帮忙确认相关信息。 根据以上分析,给出省级地址码校验及测试程序如下: var checkProv = function (val) { var pattern = /^[1-9][0-9]/; var provs = {11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江 ",31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北 ",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏 ",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门"}; if(pattern.test(val)) { if(provs[val]) { return true; } } return false; } //输出 true,37是山东 console.log(checkProv(37)); //输出 false,16不存在 console.log(checkProv(16)); 演示代码 2.2 出生日期码校验 出生日期码的校验不做解释,直接给出如下函数及测试程序: var checkDate = function (val) { var pattern = /^(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)$/; if(pattern.test(val)) { var year = val.substring(0, 4); var month = val.substring(4, 6); var date = val.substring(6, 8); var date2 = new Date(year+"-"+month+"-"+date); if(date2 && date2.getMonth() == (parseInt(month) - 1)) { return true; } } return false; } //输出 true console.log(checkDate("20180212")); //输出 false 2月没有31日 console.log(checkDate("20180231")); 演示代码 2.3 校验码校验 校验码的计算略复杂,先给出如下公式: 其中 ai 表示身份证本体码的第 i 位值,而 Wi 表示第 i 位的加权因子值。 加权因子表 【表1】: i 1 2 3 4 5 6 7 8 Wi 7 9 10 5 8 4 2 1 9 10 11 12 13 14 15 16 17 6 3 7 9 10 5 8 4 2 X与校验码换算表 【表2】 X 0 1 2 3 4 5 6 7 8 9 10 a18 1 0 X 9 8 7 6 5 4 3 2 算法过程: 根据身份证主体码(前17位)分别与对应的加权因子(表1)计算乘积再求和,根据所得结果与11取模得到X值。 根据 X 值查询表2,得出a18即校验码值。 校验码计算程序及测试见如下代码: var checkCode = function (val) { var p = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/; var factor = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ]; var parity = [ 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2 ]; var code = val.substring(17); if(p.test(val)) { var sum = 0; for(var i=0;i<17;i++) { sum += val[i]*factor[i]; } if(parity[sum % 11] == code.toUpperCase()) { return true; } } return false; } // 输出 true, 校验码相符 console.log(checkCode("11010519491231002X")); // 输出 false, 校验码不符 console.log(checkCode("110105194912310021")); 演示代码 2.4 方案2整体代码 var checkID = function (val) { if(checkCode(val)) { var date = val.substring(6,14); if(checkDate(date)) { if(checkProv(val.substring(0,2))) { return true; } } } return false; } //输出 true console.log(checkID("11010519491231002X")); //输出 false,校验码不符 console.log(checkID("110105194912310021")); //输出 false,日期码不符 console.log(checkID("110105194902310026")); //输出 false,地区码不符 console.log(checkID("160105194912310029")); 演示代码 以上为三胖对身份证号码验证的理解和分析,如有不足请大家予以指正。 知名物理学家史蒂芬?霍金于2018年3月14日去世,享年76岁。一个博学又有趣的人,一路走好! 世间再无霍金,时间永留简史! 原文地址
简言 CSS网格布局(Grid)是一套二维的页面布局系统,它的出现将完全颠覆页面布局的传统方式。传统的CSS页面布局 一直不够理想。包括table布局、浮动、定位及内联块等方式,从本质上都是Hack的方式,并且遗漏了一些重要的功能(比如:垂直居中)。Flexbox的出现部分解决了上述问题,但Flex布局是为了解决简单的一维布局,适用于页面局部布局。而Grid天然就是为了解决复杂的二维布局而出现的,适用页面的整体布局。在实际工作中,Grid和Flexbox不但不矛盾,而且还能很好的结合使用。做为WEB程序员,我们在页面布局问题上都付出过努力,也将不断探索新的方案。而Grid是第一个专门为布局问题而生的CSS模块,我们有理由对Grid充满期待。 本文包括18个小节,62个实例,完整阅读需要时间20分钟以上。 为了获得最佳的阅体验,可以访问如下格式的教程: 学习CSS网格 1 网格容器 将属性 display 值设为 grid 或 inline-grid 就创建了一个网格容器,所有容器直接子结点自动成为网格项目。 1.1 例1 grid { display: grid; } 网格项目按行排列,网格项目占用整个容器的宽度。 演示程序 1.1 例2 grid { display: inline-grid; } 网格项目按行排列,网格项目宽度由自身宽度决定。 演示程序 2 显示网格 属性grid-template-rows和grid-template-columns用于显示定义网格,分别用于定义行轨道和列轨道。 2.1 例3 grid { display: grid; grid-template-rows: 50px 100px; } 属性grid-template-rows用于定义行的尺寸,即轨道尺寸。轨道尺寸可以是任何非负的长度值(px,%,em,等) 网格项目1的行高是50px,网格项目2的行高是100px。 因为只定义了两个行高,网格项目3和4的行高取决于其本身的高度。 演示程序 2.2 例4 grid { display: grid; grid-template-columns: 90px 50px 120px; } 类似于行的定义,属性grid-template-columns用于定义列的尺寸。 因为定义中只有三列,所以项目4,5,6排在新的一行; 并因为它们位于第1,2,3列的轨道上,所以其宽度等于定义中第1,2,3列轨道的宽度。 网格项目的第1列,第2列,第3列的宽度分别是 90px, 50px 和 120px 。 演示程序 2.3 例5 grid { display: grid; grid-template-columns: 1fr 1fr 2fr; } 单位fr用于表示轨道尺寸配额,表示按配额比例分配可用空间。 本例中,项目1占 1/4 宽度,项目2占 1/4 宽度,项目3占 1/2 宽度。 演示程序 2.4 例6 grid { display: grid; grid-template-columns: 3rem 25% 1fr 2fr; } 单位fr和其它长度单位混合使用时,fr的计算基于其它单位分配后的剩余空间。 本例中,1fr = (容器宽度 - 3rem - 容器宽度的25%) / 3 演示程序 3 轨道的最小最大尺寸设置 函数minmax()用于定义轨道最小/最大边界值。 3.1 例7 grid { display: grid; grid-template-rows: minmax(100px, auto); grid-template-columns: minmax(auto, 50%) 1fr 3em; } 函数minmax()接收两个参数:第一个参数表示最小轨道尺寸,第二个参数表示最大轨道尺寸。长度值可以是auto,表示轨道尺寸可以根据内容大小进行伸长或收缩。 本例中,第一行最小高度设置成100px,但是最大高度设置成auto,表示行高可以根据内容伸长超过100px。 本例中,第一列宽度的最大值设置成50%,表示其宽度不能超过整个容器宽度的50%。 演示程序 4 重复的网格轨道 函数repeat()用来定义重复的网格轨道,尤其适用于有多个相同项目的情况下。 4.1 例8 grid { display: grid; grid-template-rows: repeat(4, 100px); grid-template-columns: repeat(3, 1fr); } 函数repeat()接收两个参数:第一个参数表示重复的次数,第二个参数表示轨道尺寸。 演示程序 4.2 例9 grid { display: grid; grid-template-columns: 30px repeat(3, 1fr) 30px; } 函数repeat()可以用在轨道定义列表当中。 本例中,第1列和第5列的宽度是30px。函数repeat()创建了中间3列,每一列宽度都是1fr。 演示程序 5 定义网格间隙 属性grid-column-gap 和 grid-row-gap用于定义网格间隙。 网格间隙只创建在行列之间,项目与边界之间无间隙。 5.1 例10 grid { display: grid; grid-row-gap: 20px; grid-column-gap: 5rem; } 间隙尺寸可以是任何非负的长度值(px,%,em等)。 演示程序 5.2 例11 grid { display: grid; grid-gap: 100px 1em; } 属性grid-gap是grid-row-gap和grid-column-gap的简写形式。 第一个值表示行间隙,第二个值表示列间隙。 演示程序 5.3 例12 grid { display: grid; grid-gap: 2rem; } 如只有一个值,则其即表示行间隙,也表示列间隙。 演示程序 6 用网格线编号定位项目 网格线本质上是用来表示网格轨道的开始和结束。 每一条网格线编号都以1开始,以1为步长向前编号,其中包括行列两组网格线。 6.1 例13 .item1 { grid-row-start: 2; grid-row-end: 3; grid-column-start: 2; grid-column-end: 3; } 这是一个3行2列的网格,即在行上有4条网格线,在列上有3条网格线。项目1利用网格线编号定位在第2行第2列的位置上。 本例中,项目只跨越一行一列,则grid-row-end和grid-column-end的定义可以省略。 演示程序 6.2 例14 .item1 { grid-row: 2; grid-column: 3 / 4; } 属性grid-row 是 grid-row-start 和 grid-row-end的简写形式。 属性grid-column 是 grid-column-start 和 grid-column-end的简写形式。 如果只指定一个值,它表示 grid-row/column-start。 如果两个值都指定,第一个表示 grid-row/column-start ,第二个值表示grid-row/column-end。而且你必须用斜杠(/)分隔这两个值。 演示程序 6.3 例15 .item1 { grid-area: 2 / 2 / 3 / 3; } 属性grid-area 是 grid-row-start, grid-column-start, grid-row-end 和 grid-column-end的简写形式。 如果四个值都指定,则第一个表示 grid-row-start, 第二个表示 grid-column-start, 第三个表示 grid-row-end ,第四个表示 grid-column-end。 演示程序 7 网格项目跨越行列 网格项目默认都占用一行和一列,但可以使用前一节中定位项目的属性来指定项目跨越多行或多列。 7.1 例16 .item1 { grid-column-start: 1; grid-column-end: 4; } 通过grid-column-start和grid-column-end属性值的设置,使该网格项目跨越多列。 演示程序 7.2 例17 .item1 { grid-row-start: 1; grid-row-end: 4; } 通过grid-row-start和grid-row-end属性值的设置,使该网格项目跨越多行。 演示程序 7.3 例18 .item1 { grid-row: 2 / 5; grid-column: 2 / 4; } 简写属性 grid-row 和 grid-column 即能用来定位项目,也能用来使项目跨越多个行列。 演示程序 7.4 例19 .item1 { grid-row: 2 / span 3; grid-column: span 2; } 关键字 span 用来指定跨越行或列的数量。 演示程序 8 网格线命名 当利用属性grid-template-rows 和 grid-template-columns定义网格时,可以同时定义网格线的名称。网格线名称可以用于定位网格项目。 8.1 例20 grid { display: grid; grid-template-rows: [row-1-start] 1fr [row-2-start] 1fr [row-2-end]; grid-template-columns: [col-1-start] 1fr [col-2-start] 1fr [col-3-start] 1fr [col-3-end]; } 用属性grid-template-rows 和 grid-template-columns定义网格,同时定义网格线名称。 为避免混淆,网格线名称应避免使用规范中的关键字(span等)。 定义网格线名称的方法是要将其放在中括号内([name-of-line]),并要和网格轨道相对应。 8.2 例21 grid { display: grid; grid-template-rows: [row-start row-1-start] 1fr [row-1-end row-2-start] 1fr [row-2-end row-end]; grid-template-columns: [col-start] 1fr [col-2-start] 1fr [col-3-start] 1fr [col-end]; } 可以给同一网格线定义多个名称,方法就是在中括号内用空格将多个名称分开。 每一个网格线名都可以被引用,以用来定位网格项目。 9 用网格线名定位项目 利用命名的网格线,可以很方便地进行项目定位。 9.1 例22 .item1 { grid-row-start: row-2-start; grid-row-end: row-end; grid-column-start: col-2-start; grid-column-end: col-end; } 引用网格线名称不用加中括号。 演示程序 9.2 例23 .item1 { grid-row: row-2-start / row-end; grid-column: col-2-start / col-end; } 简写属性grid-row 和 grid-column也可以利用网格线名称来定位项目。 演示程序 10 用同名网格线命名和定位项目 函数repeat()可以定义同名网格线。这节省了给每条网格都命名的时间。 10.1 例24 grid { display: grid; grid-template-rows: repeat(3, [row-start] 1fr [row-end]); grid-template-columns: repeat(3, [col-start] 1fr [col-end]); } 函数repeat()可以用来定义同名网格线。 这样多个网格线拥有相同的名字。 同名网格线会被分配一个位置编号,做为其唯一标识。 10.2 例25 .item1 { grid-row: row-start 2 / row-end 3; grid-column: col-start / col-start 3; } 用同名网格线来定位项目时,应注意在网格线名称和编号之间有一个空格。 本例中,项目1的行定位开始于第2条名称是row-start的网格线,结束于第3条名称是row-end的网格线;列定位开始于第1条名称是col-start的网格线,结束于第3条名称是col-start的网格线。 演示程序 11 用网格区域命名和定位项目 如同网格线命名,可以用属性grid-template-areas给网格区域命名。网格区域名称可以用来定位网格项目。 11.1 例26 grid { display: grid; grid-template-areas: "header header" "content sidebar" "footer footer"; grid-template-rows: 150px 1fr 100px; grid-template-columns: 1fr 200px; } 一组区域名称要放在单引号或双引号内,每一个名称之间以空格分隔。 每一组名称定义一行,每一个名称定义一列。 11.2 例27 header { grid-row-start: header; grid-row-end: header; grid-column-start: header; grid-column-end: header; } 网格区域名称可以用在属性grid-row-start, grid-row-end, grid-column-start, 和 grid-column-end的值中,用来定位项目。 11.3 例28 footer { grid-row: footer; grid-column: footer; } 网格区域名称也可以用于简写属性grid-row 和 grid-column的值中。 11.4 例29 aside { grid-area: sidebar; } 网格区域名称也可以用于简写属性grid-area的值中。 演示程序 12 隐式网格 隐式网格用来在显式网格之外定位项目。有时在显示网格中没有足够的空间,或者是要在显示网格之外定位项目就要用到隐式网格。这时可以把这些项目放置在隐式网格中。 隐式网格可以通过属性 grid-auto-rows, grid-auto-columns, 和 grid-auto-flow 来定义。 12.1 例30 grid { display : grid; grid-template-rows: 70px; grid-template-columns: repeat(2, 1fr); grid-auto-rows: 140px; } 本例中,只定一个行轨道,因此项目 1 和 2 高 70px 。 第2行轨道有隐式网格自动创建并为项目 3 和 4 分配了空间。 属性grid-auto-rows 定义了隐式网格的行轨道尺寸,即项目3和4的高度是 140px 。 演示程序 12.2 例31 grid { display : grid; grid-auto-flow: row; } 缺省的网格布局方向是行的方向(row)。 12.3 例32 grid { display : grid; grid-auto-flow: column; } 网格的布局方向可以定义为列的方向(column)。 12.4 例33 grid { display : grid; grid-template-columns: 30px 60px; grid-auto-flow: column; grid-auto-columns: 1fr; } 本例中,我们只定义了两个列轨道的尺寸30px 和 60px。 隐式网格中自动创建其它列并给项目3,4,5分配空间;分配的空间尺寸是通过属性 grid-auto-columns定义的。 演示程序 13 隐式命名的网格区域 网格线名称可以任意指定,但分配以 -start 和 -end 结尾的名字有额外的益处,这样隐式地创建了具名网格区域,该名称可以用于项目定位。 13.1 例34 grid { display : grid; grid-template-rows: [outer-start] 1fr [inner-start] 1fr [inner-end] 1fr [outer-end]; grid-template-columns: [outer-start] 1fr [inner-start] 1fr [inner-end] 1fr [outer-end]; } 本例中,行和列都有名为inner-start 和 inner-end的网格线,它们隐式地给网格区域分派了名称(inner)。 item1 { grid-area: inner; } 这样我们就能够直接使用网格区域名来定位,而不需要再用网格线来定位项目了。 演示程序 14 隐式命名的网格线 隐式命名网格线和隐式命名的网格区域的工作原理刚好相反。 14.1 例35 grid { display : grid; grid-template-areas: "header header" "content sidebar" "footer footer"; grid-template-rows: 80px 1fr 40px; grid-template-columns: 1fr 200px; } 定义网格区域时隐式的命名了网格线的名称。这些网格线的名称是基于区域名加上-start 或 -end后缀组成的。 14.2 例36 item1 { grid-row-start: header-start; grid-row-end: content-start; grid-column-start: footer-start; grid-column-end: sidebar-end; } 本例中,header是通过隐式网格线名称进行定位的。 演示程序 15 层叠网格项目 通过项目定位可以使多个项目层叠在一起,属性z-index可以改变层叠项目的层次。 15.1 例37 .item-1, .item-2 { grid-row-start: 1; grid-column-end: span 2; } .item-1 { grid-column-start: 1; z-index: 1; } .item-2 { grid-column-start: 2 } 本例中,项目1 和 2 行定位开始于第1条行网格线,并跨越两列。 两个项目都是用网格线编号进行定位。项目1起始于第1条列网格线,项目2起始于第2条列网格线,这使得两个项目在第一行中间列发生层叠。 缺省情况下,项目2将层叠于项目1之上;然而,给项目1设置属性z-index: 1就使得项目1层叠于项目2之上。 演示程序 15.2 例38 .overlay { grid-row-start: header-start; grid-row-end: content-end; grid-column-start: content-start; grid-column-end: sidebar-start; z-index: 1; } 本例中,利用在 grid-template-areas 定义中的隐式网格线名称,定位了一个网格项目(overlay),并将层叠于上层。 演示程序 16 网格项目的对齐方式 CSS的 盒模型对齐模块 补充了CSS网格的内容,网格项目可以按行或列的轴线方向实现多种对齐方式。 属性justify-items 和 justify-self 以行轴为参照对齐项目,属性align-items 和 align-self 以列轴为参照对齐项目。 属性justify-items 和 align-items 是网格容器的属性,并支持如下这些值: auto normal start end center stretch baseline first baseline last baseline 16.1 例39 .grid { grid-template-rows: 80px 80px; grid-template-columns: 1fr 1fr; grid-template-areas: "content content" "content content"; } .item { grid-area: content } .grid { justify-items: start } 在行的轴线起点处对齐。 演示程序 16.2 例40 grid { justify-items: center; } 在行的轴线中点处对齐。 演示程序 16.3 例41 grid { justify-items: end; } 在行的轴线终点处对齐。 演示程序 16.4 例42 grid { justify-items: stretch; } 在行的轴线方向延伸并填满整个区域。stretch是缺省值。 演示程序 16.5 例43 grid { align-items: start; } 在列的轴线起点处对齐。 演示程序 16.6 例44 grid { align-items: center; } 在列的轴线中点处对齐。 演示程序 16.7 例45 grid { align-items: end; } 在列的轴线终点处对齐。 演示程序 16.8 例46 grid { align-items: stretch; } 在列的轴线方向延伸并填满整个区域。 演示程序 16.9 例47 grid { justify-items: center; align-items: center; } 项目定位于行轴和列轴线的中间位置。 演示程序 17 网格项目的对齐方式2 项目可以用属性align-self 和 justify-self定义自己的对齐方式,并支持如下这些属性值: auto normal start end center stretch baseline first baseline last baseline 17.1 例48 .item1 { justify-self: start } .item2 { justify-self: center } .item3 { justify-self: end } 属性justify-self 在行的轴线方向定义对齐方式。 演示程序 17.2 例49 .item1 { align-self: start } .item2 { align-self: center } .item3 { align-self: end } 属性align-self 在列的轴线方向定义对齐方式。 演示程序 17.3 例50 .item1 { justify-self: center align-self: center } 项目1定位在行的轴线和列的轴线的中间位置。 演示程序 18 网格轨道的对齐方式 在网格容器中,网格轨道延轴线方向有多种对齐方式。 属性align-content用于定义网格轨道延着行的轴线的对齐方式,而属性justify-content用于定义网格轨道沿着列的轴线的对齐方式。并分别支持如下属性: normal start end center stretch space-around space-between space-evenly baseline first baseline last baseline 18.1 例51 .grid { width: 100%; height: 300px; grid-template-columns: repeat(4, 45px); grid-template-rows: repeat(4, 45px); grid-gap: 0.5em; justify-content: start; } 列的轨道在行的轴线起点处对齐。start 是缺省值。 演示程序 18.2 例52 .grid { justify-content: end; } 列的轨道在行的轴线终点处对齐。 演示程序 18.3 例53 .grid { justify-content: center; } 列的轨道在行的轴线中间处对齐。 演示程序 18.4 例54 .grid { justify-content: space-around; } 在每一列的两侧平均分配额外空间。 演示程序 18.5 例55 .grid { justify-content: space-between; } 在列与列之间平均分配额外的空间。 演示程序 18.6 例56 .grid { justify-content: space-evenly; } 在列与列之间及列与边界之间平均分配额外空间。 演示程序 18.7 例57 .grid { align-content: start; } 行的轨道在列的轴线起点处对齐,属性start是缺省值。 演示程序 18.8 例58 .grid { align-content: end; } 行的轨道在列的轴线终点处对齐。 演示程序 18.9 例59 .grid { align-content: center; } 行的轨道在列的轴线中点处对齐。 演示程序 18.10 例60 .grid { align-content: space-around; } 每一行的两侧平均分配额外空间。 演示程序 18.11 例61 .grid { align-content: space-between; } 在行与行之间平均分配额外空间。 演示程序 18.12 例62 .grid { align-content: space-evenly; } 在行与行之间及行与边界之间平均分配额外空间。 演示程序 结语 本教程相对全面地介绍了网格的相关内容,但这并不是一个完整的技术文档。想更全面的学习相关内容,推荐访问 Mozilla开发者网络 和 W3C 的网格文档。 由于能力有限,翻译中难免错误较多,还请大家多多谅解! 十分感谢原文作者Jonathan Suh在本文排版设计,示例制作,文字编辑等方面卓越的工作。 为了获得最佳的阅体验,请访问如下排版的教程: 学习CSS网格 英文原版