前言
《css 揭秘》这本书以案例的形式,介绍了 47 个网页设计经典难题的解决方案,我在学习之余将其一一记录下来,方便回顾,本文介绍前 19个案例效果及代码。
在线预览 play.csssecrets.io
1-半透明边框
难题
当你用 rgba() 或者 hsla() ,写了一个半透明的颜色,给到容器边框时候,你会发现,没有半透明效果,这是因为默认情况下,背景色会填充到边框区域,导致边框的半透明效果失效,当把 border 样式设置为 dashed 时候,你会很直观的发现这一点。
方案
使用 background-clip 属性调整上面的默认效果,这个属性的默认值为 border-box,此时背景会被元素的border 给遮盖,它还可以配置 padding-box || content-box, 此时浏览器将以内边距或内容区外沿来渲染。 修改后,border 的半透明效果就生效了。
拓展
background-clip 还有个 text 属性,很有意思,当设置为text 后,背景会被裁剪成文字的前景色
。
2-多重边框
难题
使用 border 来生成单一的边框很容易,但是若想生成多重边框就做不到了,通常需要使用各种 hack 例如使用多个元素来模拟实现。
方案1: box-shadow
一个正值的扩张半径加上两个为零的偏移量以及为零的模糊值,得到的“投影”其实就是一条实线;再结合 box-shadow 的逗号分隔语法,来创建任意数量的投影。
注意:
- 投影行为跟边框不完全一致
- 生成的边框默认出现在元素外圈,可以加上 inset 关键字来使投影绘制在元素的内圈,注意预留足够的内边距来腾出足够的间隙
方案2 : outline
如果只需要两层边框,可以在常规边框的基础上,增加 outline(描边)属性来产生外层的边框,特点是比较灵活。
总结
这两种方案都可以实现多重边框的效果,但是outline 只适用于双层边框的场景,如果需要更多层边框,可以用 box-shadow 来实现,另外这两种方案都有一个潜在的缺陷,采用时一定要在不同的浏览器中测试好最终效果。
3-灵活的背景定位
难题
想要的效果:使背景图片针对某个角进行准确的偏移定位?
方案1 background-position
方案2 background-origin
这种方案的优点是,当内边距改变时,其会自动进行位置偏移更新,不用重新声明新的偏移量。
方案3 calc()
calc() 也可以结合 background-position 进行准确的计算偏移量,达到同样的效果。注意 calc() 函数内部的 - 和 + 运算符两侧需要各加一个空白符,否则会解析错误。
background-position: calc(100% - 20px) calc(100% - 10px); 复制代码
4-边框内圆角
想要的效果如下,只显示内部圆角,外部仍然为矩角
方案1双元素叠加
使用双 div 元素叠加来实现
<div class="parent"> <div class="child"></div> </div> .parent { margin: 100px auto; width: 400px; height: 200px; background: #655; padding: 0.8em; } .child { height: 170px; background: tan; padding: 1em; border-radius: 0.8em; } 复制代码
方案2 单元素
这种方案在书中提到是个 hack, 果然我写这篇文章的时候,验证了谷歌浏览器中 outline 的样式会跟着border-radius 走,所以这个方案基本已经失效了。
div { outline: .6em solid #655; box-shadow: 0 0 0 .4em #655; /* todo calculate max of this */ max-width: 10em; border-radius: .8em; padding: 1em; margin: 1em; background: tan; font: 100%/1.5 sans-serif; } 复制代码
5-条纹背景
介绍
传统方案都是用 svg 或者图片来解决,这里直接使用 css 来创建条纹图案
// 水平条纹效果 background: linear-gradient(#fb3 50%, #58a 50%); background-size: 100% 30px; // 垂直条纹效果 background: linear-gradient(to right, #fb3 50%, #58a 0); background-size: 30px 100%; // 斜向条纹 background: linear-gradient(45deg, #fb3 50%, #58a 0); background-size: 30px 30px; // 同色系条纹 background: repeating-linear-gradient(30deg, #79b, #79b 15px, #58a 0, #58a 30px); background: #58a; // 同色系条纹 重构 background: repeating-linear-gradient( 30deg, hsla(0, 0%, 100%, .1), hsla(0, 0%, 100%, .1) 15px, transparent 0, transparent 30px); background: #58a; 复制代码
6-复杂的背景图案
桌布图案
/** * Checkerboard */ background: #eee; background-image: linear-gradient(45deg, rgba(0,0,0,.25) 25%, transparent 0, transparent 75%, rgba(0,0,0,.25) 0), linear-gradient(45deg, rgba(0,0,0,.25) 25%, transparent 0, transparent 75%, rgba(0,0,0,.25) 0); background-position: 0 0, 15px 15px; background-size: 30px 30px; min-height: 100%; /** * Polka dot */ background: #655; background-image: radial-gradient(tan 20%, transparent 0), radial-gradient(tan 20%, transparent 0); background-size: 30px 30px; background-position: 0 0, 15px 15px; 复制代码
棋盘
/** * Checkerboard */ background: #eee; background-image: linear-gradient(45deg, rgba(0,0,0,.25) 25%, transparent 0, transparent 75%, rgba(0,0,0,.25) 0), linear-gradient(45deg, rgba(0,0,0,.25) 25%, transparent 0, transparent 75%, rgba(0,0,0,.25) 0); background-position: 0 0, 15px 15px; background-size: 30px 30px; min-height: 100%; /** * Checkerboard with SVG */ background: #eee url('data:image/svg+xml,\ <svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" fill-opacity=".25" >\ <rect x="50" width="50" height="50" />\ <rect y="50" width="50" height="50" />\ </svg>'); background-size: 30px 30px; 复制代码
角向渐变
/** * Conic gradients test * PASS if green gradient, FAIL if red. */ background: red; background: conic-gradient(limegreen, green, limegreen); min-height: 100%; 复制代码
7-伪随机背景
难点:重复的平铺图案虽然美观,但是不太自然,下面介绍增加随机性背景的方法
/** * Pseudorandom stripes */ background: hsl(20, 40%, 90%); background-image: linear-gradient(90deg, #fb3 11px, transparent 0), linear-gradient(90deg, #ab4 23px, transparent 0), linear-gradient(90deg, #655 23px, transparent 0); background-size: 83px 100%, 61px 100%, 41px 100%; 复制代码
8-连续的图像边框
难点:通常这种效果是借助双 Dom 来实现,一个作为背景图,一个作为内容;我们的改进方案是基于一个元素来实现的。
/** * Basic border-image demo */ div { border: 40px solid transparent; border-image: 33.334% url('data:image/svg+xml,<svg xmlns="http:%2F%2Fwww.w3.org%2F2000%2Fsvg" width="30" height="30"> \ <circle cx="5" cy="5" r="5" fill="%23ab4"%2F><circle cx="15" cy="5" r="5" fill=" %23655"%2F> \ <circle cx="25" cy="5" r="5" fill="%23e07"%2F><circle cx="5" cy="15" r="5" fill=" %23655"%2F> \ <circle cx="15" cy="15" r="5" fill="hsl(15, 25%, 75%)"%2F> \ <circle cx="25" cy="15" r="5" fill=" %23655"%2F><circle cx="5" cy="25" r="5" fill="%23fb3"%2F> \ <circle cx="15" cy="25" r="5" fill=" %23655"%2F><circle cx="25" cy="25" r="5" fill="%2358a"%2F><%2Fsvg>'); padding: 1em; max-width: 20em; font: 130%/1.6 Baskerville, Palatino, serif; } div:nth-child(2) { margin-top: 1em; border-image-repeat: round; }
利用上面的条纹背景
/** * Vintage envelope themed border */ div { padding: 1em; border: 1em solid transparent; background: linear-gradient(white, white) padding-box, repeating-linear-gradient(-45deg, red 0, red 12.5%, transparent 0, transparent 25%, #58a 0, #58a 37.5%, transparent 0, transparent 50%) 0 / 6em 6em; max-width: 20em; font: 100%/1.6 Baskerville, Palatino, serif; }
9-自适应的椭圆
难点:border-radius 其实可以单独指定水平和垂直半径,用斜杠(/)分隔这两个值即可。利用这个特性可以创建椭圆圆角。
椭圆
/** * Flexible ellipse */ div { width: 20em; height: 10em; background: #fb3; border-radius: 50%; }
半椭圆
/** * Flexible half ellipse */ div { display: inline-block; width: 16em; height: 10em; margin: 1em; background: #fb3; border-radius: 50% / 100% 100% 0 0; } div:nth-of-type(2) { border-radius: 50% / 0 0 100% 100%; } div:nth-of-type(3) { border-radius: 100% 0 0 100% / 50%; } div:nth-of-type(4) { border-radius: 0 100% 100% 0 / 50%; }
四分之一椭圆
/** * Flexible quarter ellipse */ div { display: inline-block; width: 16em; height: 10em; margin: 1em; background: #fb3; border-radius: 100% 0 0 0; } div:nth-of-type(2) { border-radius: 0 100% 0 0; } div:nth-of-type(3) { border-radius: 0 0 100% 0; } div:nth-of-type(4) { border-radius: 0 0 0 100%; }
【css揭秘】- 47个不可不知的 css 技巧(上篇0-19)(二):https://developer.aliyun.com/article/1413851