持续更新...
这里将展示本人有关于CSS类的开发经验,并没有有循序渐进,关联性不强,都是想到哪写到哪,望海涵。
更多前端 H5 干货请点击 - 《H5 - 前端开发干货》
1. 常见的css私有前缀
在不同浏览器出现渲染不同时,往往是各内核的解析不同,加上私有前缀可保证兼容性:
前缀 | 浏览器 |
---|---|
-moz- | Firefox |
-webkit- | Safari and Chrome |
-o- | Opera |
-ms- | Internet Explorer |
但一般来说,推荐使用 Sass 或者 Less 进行预编译,保证不会遗漏:
SCSS:
@mixin css3($property, $value) {
@each $prefix in -webkit-, -moz-, -ms-, -o-, '' {
#{$prefix}#{$property}: $value;
}
}
使用:
.border_radius {
@include css3(transition, 0.5s);
}
CSS:
.border_radius {
-webkit-transition: 0.5s;
-moz-transition: 0.5s;
-ms-transition: 0.5s;
-o-transition: 0.5s;
transition: 0.5s;
}
2. 浮动清除
当div需要左浮动右浮动时会脱离文档流,导致了高度塌陷。
这时候需要给它们的父级清除浮动,重新回到文档中保证整体结构中。
.clearfix:before,
.clearfix:after {
content: "";
display: table;
}
.clearfix:after {
clear: both;
}
.left {
float: left;
}
.right {
float: right;
}
原理为在父级前后用伪类插入块级元素,并清除其两边的浮动,达到撑开父级高度的目的。
3. 媒体查询
结构:@media screen and (code)
下面为字体根据分辨率实现不同字体大小:
@media screen and (min-width: 375px) {
body {
font-size: 13px; } }
@media screen and (min-width: 414px) {
body {
font-size: 14px; } }
@media screen and (min-width: 768px) {
body {
font-size: 16px; } }
@media screen and (min-width: 1024px) {
body {
font-size: 24px; } }
4. 通用的样式重置文件
因内核的不同,一些渲染的解析也是不同的,为了统一样式使得在各种浏览器中显示效果一直,我们一般会重置样式后再进行开发,下面提供一份css重置样式的文件及三份Sass文件。
gitHub 地址
1.样式重置css文件 —— common.css
2.Sass函数文件 —— function.scss
3.Sass常量文件 —— global.scss
4.Sass样式重置文件 —— common.scss
5. 超出隐藏并显示省略号
//单行省略
{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
//多行行省略
{
display: -webkit-box;
-webkit-line-clamp: [2,3,4]; //填写数字代表第几行省略
-webkit-box-orient: vertical;
overflow: hidden;
}
6. 伪类使用
- 锚伪类
a:link {color: #FF0000} /* 未访问的链接 */
a:visited {color: #00FF00} /* 已访问的链接 */
a:hover {color: #FF00FF} /* 鼠标移动到链接上 */
a:active {color: #0000FF} /* 选定的链接 */
- 其他伪类
属性 | 描述 |
---|---|
:focus | 向拥有键盘输入焦点的元素添加样式。 |
:first-child | 向元素的第一个子元素添加样式。 |
:lang | 向带有指定 lang 属性的元素添加样式。 |
- 点击按钮 - 最好用伪类实现
//比如这个点击更多的按钮,采用伪类可以更灵活的调整按钮父级的大小与其他 div 的位置关系
.more:after {
content: "";
position: relative;
top: 2px;
right: -4px;
display: inline-block;
width: 16px;
height: 16px;
background: url('../img/more.png') no-repeat center;
background-size: 100%;
}
7. flex盒子布局
对于实现元素之间的自适应排列,传统解决方案,基于盒状模型,依赖 display
属性 + position
属性 + float
属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现,虽然能利用 table 实现,但是依旧缺乏灵活性。
推荐使用 flex 布局方式,可灵活实现各种布局需求:
阅读阮一峰的这篇文章了解更多 —— 《Flex 布局教程:语法篇》
这里就不在累述了,提醒一点适用范围为:
- 安卓 4.4以上
- ios 9以上
8. 浏览器支持测试
Can I Use...?
该网站可以查询出某 css 属性在各个浏览器版本的实现情况,非常好用
9. 浏览器回退机制
提供回退机制通常是一种很好的做法,这样可以确保你的网站不会在低版本浏览器中挂掉,而只是看起来没有那么炫而已,利用样式声明的层叠机制来实现。
background: rgb(255, 128, 0);
background: -moz-linear-gradient(0deg, yellow, red);
background: -o-linear-gradient(0deg, yellow, red);
background: -webkit-linear-gradient(0deg, yellow, red);
background: linear-gradient(90deg, yellow, red);
还可以采用 Modernizr JS插件来动态改变,或者使用 @supports 的 CSS 判断机制
@supports (条件) {
/*具体的条件样式*/
}
@supports not (条件) { //排除
/*具体的条件样式*/
}
@supports (条件) and (条件) { //并集
/*具体的条件样式*/
}
@supports (条件) or (条件) { //或集
/*具体的条件样式*/
}
当然 @supports 的支持情况要上 Can I Use...? 查询一下
10. 动态计算长度值
因预处理器 Sass Less 等技术出现,w3c 也借鉴了其中的一些性质,比如:
calc() = calc(四则运算)
用于动态计算长度值。
需要注意的是,运算符前后都需要保留一个空格,例如:width: calc(100% - 10px);
任何长度值都可以使用calc()函数进行计算;
calc()函数支持 "+", "-", "*", "/" 运算;
calc()函数使用标准的数学运算优先级规则;
很明显在预处理时,没有办法识别 100% 到底是多少,没法完成计算。而在浏览器中则是既是渲染,当然能够计算出准确的值。
11. css3中的变量用法
ul { --accent-color: purple; }
ol { --accent-color: rebeccapurple; }
li { background: var(--accent-color); }
跟上条一样,明显借鉴了预处理的变量模式,虽然能通过后代选择来完成这样的操作,但是变量的用法还是非常灵活的。
12. rgba() 和 hsla()
RGB是通过红绿蓝三原色来描述颜色的颜色空间,R=Red、G=Green、B=Blue。
原理就是三原色的亮度值叠加,并加上灰度值,在我看来更类似于平面的颜色空间的取值函数。
但问题也是显而易见的,比如你已经选定一种颜色,想要调节它的饱和度,亮度,这里的计算就变得异常困难。这时候就需要 hsla() 来描述你想要的颜色。
H:
Hue(色调)。0(或360)表示红色,120表示绿色,240表示蓝色,也可取其他数值来指定颜色。取值为:0 - 360
S:
Saturation(饱和度)。取值为:0.0% - 100.0%
L:
Lightness(亮度)。取值为:0.0% - 100.0%
A:
Alpha透明度。取值0~1之间。
在我看来它则是立体的颜色空间的取值函数,类似于一个圆柱体。色调为 0 - 360 的圆,从圆心到圆边,饱和度越来越高,最后则是其高度,决定其亮度。
两者都是描述颜色的方式,跟 canvas与svg,位图与矢量图,来描述图像的方式是一样,以不同角度描述同一件东西而已。
13. 半透明边框实现
一开始你一定会这么写吧
border: 10px solid hsla(0,0%,100%,.5);
background: white;
最后的结果,并没有看到透明边框呀!
尝试下这样的写法:
border: 10px solid hsla(0,0%,100%,.5);
background: white;
background-clip: padding-box;
看透明边框出来了,原理是在没有设置 background-clip 时,背景会被裁减到内容框,即成为了边框的背景,所以看不到了。设置为 padding-box 时背景被裁剪到内边距框,保留了内边距的背景,这时候就能显示出来啦。
14. 双边框实现
这里有一个我们一直忽略的属性 outline 别再用双 div 实现双边框了,使用 outline 吧!
background: yellowgreen;
border: 10px solid #655;
outline: 5px solid deeppink;
15. 条纹填充
用法自行百度
background: repeating-linear-gradient(60deg,
#fb3, #fb3 15px, #58a 0, #58a 30px);
16. svg在css中的写法
background: #eee url('data:image/svg+xml,\
');
background-size: 30px 30px;
17. 四边形
想要做到这种四边形的按钮大家的第一反应一定是通过skew() 的变形属性来对这个矩形进行斜向拉伸:
transform: skewX(-45deg);
但显而易见的是,这样子做字体也会跟着形变
那要如何在不添加多一个 div 结构的前提下完成预期的效果呢?答案就是伪元素了,思路是把所有样式(背景、边框等)应用到伪元素上,然后再对伪元素进行变形。因为我们的内容并不是包含在伪元素里的,所以内容并不会受到变形的影响,代码如下:
.button {
position: relative;
/* 其他的文字颜色、内边距等样式…… */
}
.button::before {
content: ''; /* 用伪元素来生成一个矩形 */
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
z-index: -1;/* 将堆叠层次推到宿主元素之后 */
background: #58a;
transform: skew(45deg);
}
不仅仅 skew() 变形可以采用这种方法,还适用于其他任何变形样式,当我们想变形一个元素而不想变形它的内容时就可以用到它。举个例子,我们把这个技巧针对rotate() 变形样式稍稍调整一下,再用到一个正方形元
素上,就可以很容易地得到一个菱形。
18. 菱形图片
.picture {
width: 400px;
transform: rotate(45deg);
overflow: hidden;
}
.picture > img {
max-width: 100%;
transform: rotate(-45deg) scale(1.42);
}
19. 梯形标签
nav > a {
position: relative;
display: inline-block;
padding: .3em 1em 0;
}
nav > a::before {
content: '';
position: absolute;
top: 0; right: 0; bottom: 0; left: 0; z-index: -1;
background: #ccc;
background-image: linear-gradient(hsla(0,0%,100%,.6),
hsla(0,0%,100%,0));
border: 1px solid rgba(0,0,0,.4);
border-bottom: none;
border-radius: .5em .5em 0 0;
box-shadow: 0 .15em white inset;
transform: perspective(.5em) rotateX(5deg);
transform-origin: bottom;
}
20. 饼图
思路:通过两个半圆与伪元素遮盖的方式形成饼图扇形
html:
css:
.pie {
width: 100px; height: 100px;
border-radius: 50%;
background: yellowgreen;
background-image:linear-gradient(to right, transparent 50%, #655 0); //通过渐变制作另外的半圆
}
.pie::before {
content: '';
display: block;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%; //这里是将遮盖的伪元素矩形变成半圆;难以理解的话,就.pie 设置overflow: hidden 的样式;
background-color: inherit; //跟随父级背景色,减少重复代码
transform-origin: left; //这是将旋转中心定位在左边长中点
transform: rotate(.2turn); //旋转百分之二十
}
tips:
1、
border-radius: 2em 1em 4em / 0.5em 3em;
等价于
border-top-left-radius: 2em 0.5em;
border-top-right-radius: 1em 3em;
border-bottom-right-radius: 4em 0.5em;
border-bottom-left-radius: 1em 3em;
2、
.2turn
一个圆为 1turn
这里表示百分之二十的圆
到这里 0 ~ 50% 的扇形是十分方便的就能够做出来了,那百分五十以上的呢?大家很轻易地就会想到只要把伪元素遮挡的背景颜色变成一样的不就可以了吗!
.pie::before {
content: '';
display: block;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background: #655; //这个就是关键
transform-origin: left;
transform: rotate(.1turn); //减去半圆后的占比面积
}
看到这里你可能会想到一个问题,这些都是写死的比例,而且伪元素是没办法写行内样式的,那要如何动态形成饼图呢?要想通过行内样式控制扇形大小,首先我们可以先看看这个动画形成的过程:
@keyframes spin {
to { transform: rotate(.5turn); }
}
@keyframes bg {
50% { background: #655; }
}
.pie::before {
content: '';
display: block;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background-color: inherit;
transform-origin: left;
animation: spin 3s linear infinite,
bg 6s step-end infinite;
}
替换一下代码,你将会看到一个饼图从0 变化到100% 的动画,从而得到一个炫酷的进度指示器。这时候我们就想到了,只要我能控制它在哪一帧停下来就可以得到任意的饼图啦,同时这个可以在内联样式中实现。
@keyframes spin {
to { transform: rotate(.5turn); }
}
@keyframes bg {
50% { background: #655; }
}
.pie::before {
/* [其余的样式代码保持原样] */
animation: spin 50s linear infinite,
bg 100s step-end infinite; //用整体动画时间为100s,方便计算
animation-play-state: paused; //这里为动画停止
animation-delay: inherit; //定义动画何时开始
}
而HTML变为:
这里是负值的意思是直接到 20s 的动画进度所形成的饼图
到这里我们就可以通过 js 来动态形成饼图了。那多个扇形呢?这时候就需要 svg 的登场了,这里不属于css我就不在这里累述了,下次会补充上 svg 篇的。
21. 单侧投影
投影 box-shadow 其实是有6个参数的,虽然我们不怎么用到,先来看看这6个参数是什么吧:
box-shadow: h-shadow v-shadow blur spread color inset;
值 | 描述 |
---|---|
h-shadow | 必需。水平阴影的位置。允许负值。 |
v-shadow | 必需。垂直阴影的位置。允许负值。 |
blur | 可选。模糊距离。 |
spread | 可选。阴影的尺寸。 |
color | 可选。阴影的颜色。请参阅 CSS 颜色值。 |
inset | 可选。将外部阴影 (outset) 改为内部阴影。 |
单侧投影:
box-shadow: 0 5px 4px -4px black;
双侧投影:
box-shadow: 5px 0 5px -5px black,-5px 0 5px -5px black;
核心:
h-shadow | v-shadow 其中一个为零;
blur = - spread;
22. 不规则投影 | 滤镜
很明显的可以看出对于不规则的边框 box-shadow 是实现的不够好的。而 滤镜效果规范 为这个问题提供了一个解决方案。它引入了一个叫作filter 的新属性,这个属性也是从SVG 那里借鉴过来的。尽管CSS 滤镜基本上就是SVG 滤镜,但我们并不需要掌握任何SVG 知识。相反,只需要一些函数就可以很方便地指定滤镜效果了,比如blur()、grayscale() 以及我们需要的drop-shadow()。
实现就这么简单:
filter: drop-shadow(2px 2px 10px rgba(0,0,0,.5));
同样的滤镜还能完成下面这种效果
好比如实现头像致灰鼠标悬浮时还原彩色的效果也是可以通过 filter 实现:
img {
transition: .5s filter;
filter: sepia(1) saturate(4) hue-rotate(295deg);
}
img:hover,
img:focus {
filter: none;
}
当然还有一种混合模式的滤镜效果:
a {
background: hsl(335, 100%, 50%);
}
img {
mix-blend-mode: luminosity;
}
mix-blend-modet 用法
接下来详细的看看 filter 的各种属性:
filter: none | blur() | brightness() | contrast() | drop-shadow() | grayscale() | hue-rotate() | invert() | opacity() | saturate() | sepia() | url();
Filter | 描述 |
---|---|
none | 默认值,没有效果。 |
blur(px) | 给图像设置高斯模糊。"radius"一值设定高斯函数的标准差,或者是屏幕上以多少像素融在一起, 所以值越大越模糊;如果没有设定值,则默认是0;这个参数可设置css长度值,但不接受百分比值。 |
brightness(%) | 给图片应用一种线性乘法,使其看起来更亮或更暗。如果值是0%,图像会全黑。值是100%,则图像无变化。其他的值对应线性乘数效果。值超过100%也是可以的,图像会比原来更亮。如果没有设定值,默认是1。 |
contrast(%) | 给图像设置一个阴影效果。阴影是合成在图像下面,可以有模糊度的,可以以特定颜色画出的遮罩图的偏移版本。 函数接受 |
grayscale(%) | 将图像转换为灰度图像。值定义转换的比例。值为100%则完全转为灰度图像,值为0%图像无变化。值在0%到100%之间,则是效果的线性乘子。若未设置,值默认是0; |
hue-rotate(deg) | 给图像应用色相旋转。"angle"一值设定图像会被调整的色环角度值。值为0deg,则图像无变化。若值未设置,默认值是0deg。该值虽然没有最大值,超过360deg的值相当于又绕一圈。 |
invert(%) | 反转输入图像。值定义转换的比例。100%的价值是完全反转。值为0%则图像无变化。值在0%和100%之间,则是效果的线性乘子。 若值未设置,值默认是0。 |
opacity(%) | 转化图像的透明程度。值定义转换的比例。值为0%则是完全透明,值为100%则图像无变化。值在0%和100%之间,则是效果的线性乘子,也相当于图像样本乘以数量。 若值未设置,值默认是1。该函数与已有的opacity属性很相似,不同之处在于通过filter,一些浏览器为了提升性能会提供硬件加速。 |
saturate(%) | 转换图像饱和度。值定义转换的比例。值为0%则是完全不饱和,值为100%则图像无变化。其他值,则是效果的线性乘子。超过100%的值是允许的,则有更高的饱和度。 若值未设置,值默认是1。 |
sepia(%) | 将图像转换为深褐色。值定义转换的比例。值为100%则完全是深褐色的,值为0%图像无变化。值在0%到100%之间,则是效果的线性乘子。若未设置,值默认是0; |
url() | URL函数接受一个XML文件,该文件设置了 一个SVG滤镜,且可以包含一个锚点来指定一个具体的滤镜元素。例如: |
initial | 设置属性为默认值,可参阅: CSS initial 关键字 |
inherit | 从父元素继承该属性,可参阅:CSS inherit 关键字 |
23. 文本行的斑马纹
实现上图的效果,立马反应出来的是 :nth-child() / :nth-of-type() 伪类,一般的情况是可以应对啦,但是这个有以下两个缺点:
- 明显的每一行都需要用标签包裹;
- 当一个标签内一行显示不完的时候就会导致大条纹的产生;
- 过多的 DOM 元素还会拖累整个页面的性能;
解决方法对整个元素设置统一背景,听起来好像很糟糕,但是利用以下几个属性的特性就能够完美的实现斑马条纹:
- 利用css的渐变生成背景图;
- 利用em单位设定背景尺寸;
- background-size 需要设置为line-height 的两倍;
padding: .5em;
line-height: 1.5;
background: beige;
background-size: auto 3em;
background-origin: content-box;
background-image: linear-gradient(rgba(0,0,0,.2) 50%,transparent 0);
24. tab缩进
pre {
tab-size: 2;
}
25. 空心字效果
background: deeppink;
color: white;
text-shadow: 1px 1px black, -1px -1px black,
1px -1px black, -1px 1px black;
26. 鼠标光标样式
先补充一下 css 2.1 提供的内置样式(cursor属性):
接下来是CSS3新增的样式
27. 自定义复选框
如我们所知复选框的样式是非常难以修改的,想要自定义样式,我们一般是通过
28. 根据兄弟元素的数量来设置样式
为了解决当需要根据不同的兄弟元素数量来决定样式实现,比如当元素只有4个时,跟元素有8个时用不同的样式。那要如何选中呢? 用兄弟元素选择器 ‘~’ 明显是不行的,因为它只会选中在其后面的兄弟元素。
li:first-child:nth-last-child(4), /* 是列表中的第一个元素同时又是从后往前数第四个元素 */
li:first-child:nth-last-child(4) ~ li { /* 再利用兄弟元素选择器 */
/* 当列表正好包含四项时,命中所有列表项 */
}
//同时提供sass的混合宏,方便实现
@mixin n-items($n) { /* 定义mixin */
&:first-child:nth-last-child(#{$n}),
&:first-child:nth-last-child(#{$n}) ~ & {
@content;
}
}
/* 调用时是这样的: */
li {
@include n-items(4) {
/* 属性与值写在这里 */
}
}
29. 垂直居中
“44 年前我们就把人类送上月球了,但现在我们仍然无法在CSS 中
实现垂直居中。” —— James Anderson(这个挺有意思的~)
在CSS 中对元素进行水平居中是非常简单的:如果它是一个行内元素,就对它的父元素应用text-align: center;如果它是一个块级元素,就对它自身应用margin: auto。然而如果要对一个元素进行垂直居中,可能光是想想就令人头皮发麻了。
我们以下面的例子来做说明
Am I centered yet?
Center me, please!
我们先从最简单的情况开始实现,当对象是存在固定的宽高时,先把这个元素的左上角放置在视口(或最近的、具有定位属性的祖先元素)的正中心,然后再利用负外边距把它向左、向上移动(移动距离相当于它自身宽高的一半),从而把元素的正中心放置在视口的正中心。
main {
position: absolute;
top: 50%;
left: 50%;
margin-top: -3em; /* 6/2 = 3 */
margin-left: -9em; /* 18/2 = 9 */
width: 18em;
height: 6em;
}
当然根据我们上面提到过的 calc() 函数,还可以简化为:
main {
position: absolute;
top: calc(50% - 3em);
left: calc(50% - 9em);
width: 18em;
height: 6em;
}
但通常情况下我们是不会固定对象的宽高的,这时候我们可以利用 translate 来代替负外边距的效果,对于绝大多数CSS 属性(包括margin)来说,百分比都是以其父元素的尺寸为基准进行解析的,而独独 translate 是以这个元素自身的宽度和高度为基准进行换算和移动的
main {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
这个方法还是存在一些缺陷的:
- 我们有时不能选用绝对定位,因为它对整个布局的影响太过强烈。
- 如果需要居中的元素已经在高度上超过了视口,那它的顶部会被视口裁切掉(参见图7-19)。有一些办法可以绕过这个问题,但hack味道过浓。
- 在某些浏览器中,这个方法可能会导致元素的显示有一些模糊,因为元素可能被放置在半个像素上。这个问题可以用transformstyle:preserve-3d 来修复,不过这个修复手段也可以认为是一个hack,而且很难保证它在未来不会出问题。
也存在着不依靠绝对定位而用视口来实现的方法
main {
width: 18em;
padding: 1em 1.5em;
margin: 50vh auto 0;
transform: translateY(-50%);
}
但是最推荐的还是 Flexbox 伸缩盒模型是最佳的解决方法
body {
display: flex;
min-height: 100vh;
margin: 0;
}
main {
margin: auto;
}
30. 头部尾部固定 - 中间内容自适应区域滚动
31. 缓动效果
tips: 为什么采用变形属性来制作动画,而不是类似top 或margin-top 这样的属性?因为变形属性的动画过程更加流畅;而其他CSS 属性由于需要对齐到像素,往往略显生硬。
@keyframes bounce {
60%, 80%, to {
transform: translateY(400px);
animation-timing-function: ease;
}
70% { transform: translateY(300px); }
90% { transform: translateY(360px); }
}
.ball {
/* 外观样式 */
animation: bounce 3s cubic-bezier(.1,.25,1,.25);
// animation: bounce 3s ease-in; 或者使用本来就存在的函数
}
//CSS 提供了一个 cubic-bezier(x1, y1, x2, y2) 函数,允许我们指定自定义的调速函数,实际上就是规定一条二次贝塞尔曲线来决定动画的加速度
//调速函数推荐:cubic-bezier(.215,.61,.355,1) 和 cubicbezier(.755,.05,.855,.06)
32. CSS强制英文、中文换行与不换行 强制英文换行
代码 | 作用 |
---|---|
word-break:break-all; | 只对英文起作用,以字母作为换行依据 |
word-wrap:break-word; | 只对英文起作用,以单词作为换行依据 |
white-space:pre-wrap; | 只对中文起作用,强制换行 |
white-space:nowrap; | 强制不换行,都起作用 |
white-space:nowrap; overflow:hidden; text-overflow:ellipsis;(部分浏览器支持) | 不换行,超出部分隐藏且以省略号形式出现 |
33. CSS箭头写法
//左箭头
border-top: 2px solid #ffffff;
border-right: 2px solid #ffffff;
transform: rotate(-135deg);
//右箭头
border-top: 2px solid #ffffff;
border-right: 2px solid #ffffff;
transform: rotate(45deg);