CSS很美妙,能够为您的页面穿上衣裳,各种各样五彩斑斓的衣裳,但是对于开发者来说,他又不够灵动,于是乎有了各种各样的预处理器Sass、LESS、Stylus(笔者建议Sass的SCSS语法),这些预处理器可以很大程度的提高CSS的灵活性,增强CSS的代码组织与维护。但是毕竟不是亲生的,然后负责CSS开发的那些大牛们坐不住了,开始给CSS赋予一些新的特性,本文就来探讨下CSS变量的进展与应用。
W3C的关于CSS变量的最新探索体现在CSS Custom Properties for Cascading Variables Module Level 1中,最新更新在2014年5月6日,目前为工作草案,所以本文章只为研究探索只用,所涉知识点存在修改的风险,W3C修改之后本文会同步更新。

##所为何来
我们知道,一个网站或应用往往包含大量的CSS,这些CSS里的一些属性值往往重复使用,比如网站使用的颜色体系,背景色、文字颜色、链接颜色等,这些重复使用的属性值散落在大量的CSS文档中,如果需要修改其中的一些值,例如改版颜色,那简直是个噩梦,我们需要每个文件进行查找、替换,眼花缭乱、机械重复的大量操作难免出错、难免头大,所以CSS代码的组织与维护已经成了困扰CSS使用的重要瓶颈。
当然,CSS预处理可以有效的解决这些问题,预处理器的使用已经成了事实上的行业标准,Sass正成为越来越多前端er的选择。但是,我们需要部署编译环境、需要让开发工具支持Sass等,需要一些额外的工作。遇事不免畅想,如果有一天,我们可以像使用普通CSS那些使用预处理器?
于是便有了W3C的CSS Various。

##剥茧抽丝
关于变量,不外乎定义和使用,接下来我们分别解析。

###定义变量
我们把需要重复使用的值存放到一个自定义的属性中,这个自定义的属性用双虚线开头标识,如下面代码所示。

1
2
3
4
5
6
7
8
/* 变量定义 */
:root {
--main-color: #06c;
}

/* 变量使用 */
#foo h1 {
color: var(--main-color);
}

####变量名
自定义属性名和变量名遵循CSS标识符的定义规则,可以包含字母数字(a-z,A-Z,0-9)、ISO 10646字符列表的U+00A0及以上字符、下划线(_)、连字符(-)等,不能以数字、连字符+数字、双连字符开始。
CSS变量语法中,大小写敏感,可以包含字母、数字、下划线、连字符,且最好不以数字、连字符开头。

1
2
3
4
5
6
7
8
9
10
11
12
/* 正确的变量名 */
:root{
--link-color: #06c;
--_hover-color: #f6c;
--toolTip_color: #ff0;
--main_background_color: #333;
}

/* 下面两个变量都有效,表示两个变量 */
:element{
--link-color:#06c;
--Link-color:#66c;
}

变量值可以接受任何符合语法的值,它的默认值为” “,但是不能为””,否则会报错。

####变量的继承和覆盖
变量的声明和使用遵循CSS的层叠特性,类似于普通编程语言里面的变量作用域。请看下面的代码。

1
2
3
4
:root { --color: blue; }
div { --color: green; }
#alert { --color: red; }
* { color: var(--color); }

1
2
3
4
5
6
<p>I inherited blue from the root element!</p>
<div>I got green set directly on me!</div>
<div id='alert'>
While I got red set directly on me!
<p>I’m red too, because of inheritance!</p>
</div>

###使用变量
我们可以通过var()的方式使用变量,但是不能在属性名、选择器中使用变量,只能在属性值中使用变量,使用变量的语法如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* 
* var()接受两个参数,自定义属性名(变量名)、缺省值
* 第一个参数custom-property-name调用变量
* 第二参数可选,指定自定义变量无效时的缺省值。
*/
var() = var( <custom-property-name> [, <any-value> ]? )

/* for example */
/* In the component’s style: */
.component .header {
color: var(--header-color, blue);
}
.component .text {
color: var(--text-color, black);
}

/* In the larger application’s style: */
.component {
--text-color: #080;
/* header-color isn’t set,
and so remains blue,
the fallback value */
}

我们可以嵌套调用CSS变量。

1
2
3
4
5
6
7
8
9
10
/*one example */
:root {
--main-color: #c06;
--accent-background: linear-gradient(to top, var(--main-color), white);
}
/*another example */
<one><two><three /></two></one>
one { --foo: 10px; }
two { --bar: calc(var(--foo) + 10px); }
three { --foo: calc(var(--bar) + 10px); }

##兼容并包
对于前端开发者来说,兼容并包永远是一个难以企及的痛,作为一个具有“极客思维”的前端er,我们还是要努力。
首先来看看,CSS变量目前的惨不忍睹的兼容性,如下图所示,数据来自caniuse
这里写图片描述
全线飘红有木有,只有firefox认识,还怎么玩。
有兄弟说,我就要任性,就要玩怎么办?老外写了个补丁(polyfill),大家不妨一试。

##只求甚解
综上所述,CSS变量处于草案阶段,浏览器兼容一般,今天写这篇文章仅为开阔视野,储备知识之用。商用还请大家使用Sass或LESS等预处理器。
如欲了解更多详情,使用下面的列表乃求甚解。


##致谢
前端开发whqet,关注前端开发,分享相关资源。csdn专家博客,王海庆希望能对您有所帮助。
本文原文链接,http://whqet.github.io/2015/02/12/CSS%E5%8F%98%E9%87%8F%E8%AF%95%E7%8E%A9%E5%84%BF/
欢迎大家访问独立博客http://blog.csdn.net/whqet/

2015年2月3日,CSS Counter Style level3成为了W3C的候选标准,是时候来一探究竟,看看强大魔力的@counter-style如何自定义list-style和counter。进来一坐,且听庆哥分解。

##强大魔力
使用CSS Counter Style可以做什么,来看看庆哥做的简单案例。当然,如果要发挥最大魔力,需要您的美好创意,这不是哥的特长,就不献丑了,欢迎各位通过留言提交您的创意。






需要注意的是,目前仅有firefox浏览较好的支持@counter-style。我依然把代码放到了codepen,请大家自由选择-在线研究-or-下载收藏-。
使用@counter-style命令,我们可以自定义列表样式,可以用在list-stylecountercounters等上。

##结构解析
定义一个counter-style的典型格式如下:

1
@counter-style counter名字{
	 system  : 算法;
	 range   : 使用范围;
	 symbols : 符号; or additive-symbols: 符号
	 prefix  : 前缀;
	 suffix  : 后缀;
	 pad     : 补零(eg. 01,02,03);
	 negative: 负数策略;
	 fallback: 出错后的默认值;
	 speakas : 语音策略;
}

上面详细列出了@counter-style的所有命令,大部分情况下,我们只需要使用其中几个命令即可,例如实现“天干编号”的命令如下。

1
2
3
4
5
6
@counter-style cjk-heavenly-stem {
system: alphabetic;
symbols: "\7532" "\4E59" "\4E19" "\4E01" "\620A" "\5DF1" "\5E9A" "\8F9B" "\58EC" "\7678";
/* 甲 乙 丙 丁 戊 己 庚 辛 壬 癸 */
suffix: "、";
}

接下来我们来简要看看各个命令的用法。

###算法-system
| 命令 | 意义 | 可接受值 | 默认值 |
| :——– |:——————| :—————–|:——-|
| system | 符号生成算法 | cyclic 、 numeric 、 alphabetic 、 symbolic 、 additive 、 [fixed ?] 、 [ extends ] | symbolic |
算法详细解释如下表所说。

参数 意义 示例代码 表现方式
cyclic 循环使用符号 system: cyclic; symbols:’a’ ‘b’ ‘c’; a,b,c,a,b,c,a
fixed 只用一遍符号,数字表示开始使用的位置 system: fixed 3; symbols:’a’ ‘b’ ‘c’ ‘d’; 1,2,a,b,c,d,7
symbolic 循环使用符号,第二遍双倍重复 system:symbolic; symbols:’a’ ‘b’ ‘c’; a,b,c,aa,bb,cc,aaa
alphabetic 类似于小写字母循环 system:alphabetic; symbols:’a’ ‘b’ ‘c’; a,b,c,aa,ab,ac,ba
numeric 类似于数字进制 system:alphabetic; symbols:’a’ ‘b’ ‘c’; b,c,c,ba,bb,bc,ca,cb
additive 类似于罗马数字的编号系统 system:additive; additive-symbols: c 3, b 2, a 1; a,b,c,ca,cb,cc,cca
extends 继承其他编号系统 system: extends decimal; suffix: ‘) ‘; 1),2),3),4),5),6),7)

###使用范围-range
指定自定义符号系统的使用范围,超出范围外的将采用fallback指定的默认编号。
可以使用[ [ | infinite ]{2} ]或 auto两种形式指定range范围,auto为默认值。
auto在不同system下的含义如下列表所示:

  • 在cyclic、numeric、fixed算法下,auto表示从负无穷到正无穷
  • 在alphabetic、symbolic算法下,auto表示从1到正无穷
  • additive算法下,auto表示从0到正无穷
  • extend算法下,auto取继承的父系统的取值范围,如果为预定义的复杂系统,取预定义的取值

    下面的示例都是正确的范围指定。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /*指定范围为auto,默认值*/
    range: auto;

    /*指定范围为两个数字:前面表示下限,后面表示上限,两个数字都包含在内,列表之间用逗号隔开*/
    range: 1 6;
    range: 1 2,4 6;

    /*指定范围为关键字*/
    range: infinite; /*从负无穷到正无穷*/
    range: infinite 4; /*从负无穷到4*/
    range: -6 infinite;/*从-6到正无穷*/

###使用符号-symbols和additive-symbols
这是自定义counter-style中非常重要的属性,在 cyclic、numeric、alphabetic、symbolic、fixed等算法中必须指定symbols属性,在additive算法中必须指定additive-symbols。

###使用前后缀-prefix和suffix
prefix的默认自为“ ”,suffix的默认值为”\2E\20”,一个点加一个空格。

###使用补零策略-pad
pad可以让开发者指定固定宽度的符号系统,例如三位的数字系统,001, 002,……,100, 101等。
pad指定的格式为 pad && ,例如 pad 3 “0”等。

匿名counter-style-symbols()函数

symblos函数将创建一个没有名字,prefix为””,suffix为” “,range为auto,fallback为decimal,negative为”\2d”(-), pad为0 “”,speak-as为auto的匿名style。也即我们只需要在匿名counter-style中指定system和symbols即可。

1
ol { list-style: symbols(cyclic "a" "b" "c" "d"); }

##预定义style
CSS Counter Styles Level 3预定了很多不错的符号系统,例如针对中国用户的天干、地支、中文数字、中文大写等符号系统。这些预定义的系统,使我们学习counter-style的不错资源,下面我们就来看几个。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*两位数字编号-01,02,03……10,11*/
@counter-style decimal-leading-zero {
system: extends decimal;
pad: 2 '0';
}
/*中文数字编号*/
@counter-style cjk-decimal {
system: numeric;
range: 0 infinite;
symbols: \3007 \4E00 \4E8C \4E09 \56DB \4E94 \516D \4E03 \516B \4E5D;
/* 〇 一 二 三 四 五 六 七 八 九 */
suffix: "\3001";
/* "、" */
}
/*天干编号*/
@counter-style cjk-heavenly-stem {
system: alphabetic;
symbols: "\7532" "\4E59" "\4E19" "\4E01" "\620A" "\5DF1" "\5E9A" "\8F9B" "\58EC" "\7678";
/* 甲 乙 丙 丁 戊 己 庚 辛 壬 癸 */
suffix: "、";
}
/*地支编号*/
@counter-style cjk-earthly-branch {
system: alphabetic;
symbols: "\5B50" "\4E11" "\5BC5" "\536F" "\8FB0" "\5DF3" "\5348" "\672A" "\7533" "\9149" "\620C" "\4EA5";
/* 子 丑 寅 卯 辰 巳 午 未 申 酉 戌 亥 */
suffix: "、";
}
/*中文大写编号-壹仟壹佰壹拾壹*/
@counter-style simp-chinese-formal {
/* this is a predefined complex style in the CSS3 Counter Styles specification */
system: additive;
range: -9999 9999;
additive-symbols: 9000 \7396\4EDF, 8000 \634c\4EDF, 7000 \67d2\4EDF, 6000 \9646\4EDF, 5000 \4f0d\4EDF, 4000 \8086\4EDF, 3000 \53C1\4EDF, 2000 \8CB3\4EDF, 1000 \58F9\4EDF, 900 \7396\4F70, 800 \634C\4F70, 700 \67D2\4F70, 600 \9646\4F70, 500 \4f0d\4F70, 400 \56DB\4F70, 300 \53C1\4F70, 200 \8CB3\4F70, 100 \58F9\4F70, 90 \7396\62FE, 80 \634C\62FE, 70 \67D2\62FE, 60 \9646\62FE, 50 \4f0d\62FE, 40 \8086\62FE, 30 \53C1\62FE, 20 \8CB3\62FE, 10 \58F9\62FE, 9 \7396, 8 \634C, 7 \67D2, 6 \9646, 5 \4f0d, 4 \8086, 3 \53C1, 2 \8CB3, 1 \58F9, 0 \96F6;
suffix:'、 ';
negative: "\8D1F";
}

##相关阅读
w3c 候选标准
Predefined Counter Styles

##致谢
前端开发whqet,关注前端开发,分享相关资源。csdn专家博客,王海庆希望能对您有所帮助。
本文原文链接,http://blog.csdn.net/whqet/article/details/43605725
欢迎大家访问独立博客http://whqet.github.io

程序媛and程序猿,兄弟姐妹们,大家周末好,我们今天来研读一下利用纯css实现段落文字的彩条效果。有朋友就说了,不就是css3的渐变吗,最多加上webkit内核的-webkit-background-clip,嗯,远不止哟,进来一坐了解详情……

##案例欣赏
这里写图片描述
这里写图片描述
代码我同样放到了codepen,大家可以-在线研究-,或-下载收藏-。

##知识解析
实现本案例您需要:

  • css3渐变
  • -webkit-background-clip: text和-webkit-text-fill-color: transparent
  • sass的function的内涵和自定义
  • 伪对象的使用

我们接下来品味实现过程,强烈建议大家根据上面的原理自行实现,有实现的兄弟欢迎通过评论提交佳作哟。

##实现情况
我们的html文件同样使用了haml,貌似下面代码这样。

1
2
3
4
.container
- 6.times do |i|
%section{class: "lh"}

%p 前端开发whqet,王海庆的技术博客,关注前端开发,分享相关资源,希望可以对您有所帮助。csdn专家博客http://blog.csdn.net/whqet和个人独立博客http://whqet.github.io同步更新,希望可以得到您的支持与肯定,您的支持是我最大的动力!王海庆,浙江邮电职业技术学院软件技术青椒一枚,其貌不扬、其名不翔,关心技术、热爱生活,我爱怒放的生命。

然后我们设置下页面布局和全局css设置,为了简化问题,本案例使用了sass的scss语法、css reset和-prefix-free。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*全局变量的设置,行高和彩条颜色*/
$lh:1.8em;
$colors: #9588DD #DD88C8 #D3DD88 #88B0DD #FFD86F #B4DB6C #0090FB #00965E;
/*布局和全局设置*/
.container{
counter-reset:counterA;
}
.container section{
counter-increment:counterA;
position: relative;
padding:10vh 20vw;
background:#2B293D;
border-bottom:1px dashed rgba(255,255,255,.1);
&::before{
content:counter(counterA);
position: absolute;
left:0;
top:0;
font-size:20vw;
color:rgba(255,255,255,.05);
}
p{
text-indent: 2em;
line-height: $lh;
color:#fff;
}
}

###彩条效果
案例创意来自Chris Coyier’s Pen One line of Text Dif Color,案例效果如下
这里写图片描述
我们在实现这个效果时,手动设置渐变的颜色,需要把握的核心在于设置渐变点与段落文字的行高吻合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*第一个,彩色条纹,手动指定颜色*/
section:nth-of-type(1) {
p {
/*本案例仅仅兼容webkit内核浏览器*/
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
/*繁琐的渐变颜色设置*/
background-image: linear-gradient(
to bottom,
#9588DD,
#9588DD $lh,
#DD88C8 $lh,
#DD88C8 $lh*2,
#D3DD88 $lh*2,
#D3DD88 $lh*3,
#88B0DD $lh*3,
#88B0DD $lh*4,
#FFD86F $lh*4,
#FFD86F $lh*5,
#B4DB6C $lh*5,
#B4DB6C $lh*6,
#0090FB $lh*6,
#0090FB $lh*7,
#00965E $lh*7,
#00965E
);

}
}

###函数实现彩条效果
由上面彩条效果实现过程可知,渐变颜色的设置是整个案例实现的关键,但是比较不幸的是,这个过程太过danteng,这个煎熬的过程是程序猿都顶不住,于是穷则思变,使用scss的自定义函数来代替繁琐的人工设置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*第二个,彩色条纹,mixins方式读取预设值*/
/**
* $colors, 渐变颜色序列
* $lh, 段落的行高
*************************************************/

@function makestripes($colors,$lh){
$stripes: 'to bottom,';
$i: 1;
$l: length($colors);
@each $color in $colors{
$stripes:
$stripes +
$color + ' ' + ($lh * ($i - 1))
+ ',' +
$color + ' ' + ($lh * ($i * 1))
;

@if ($i < $l){
$stripes: $stripes + ',';
}
$i: $i + 1;
}
@return unquote('repeating-linear-gradient(' + $stripes + ')');
}
section:nth-of-type(2) {
p {
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
/*你体会到愉快了吗?*/
background-image: makestripes($colors,$lh);
}
}

###淡出效果
彩条效果多少有点炫技,属于前端er的玩儿弄,实际应用场合有待探索,但是下面的这个淡出效果应该应用挺广,比如用在日志摘要以增加设计的优雅。
这里写图片描述
本效果的实现,我们同样从手动设置渐变颜色出发,然后研究sass的函数设置,然后研究兼容firefox的实现方式,参见3.3-3.6.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*第三个,淡出效果,手动方式指定*/
section:nth-of-type(3) {
p {
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-image: linear-gradient(
to top,
rgba(white, 0.2),
rgba(white, 0.2) $lh,
rgba(white, 0.4) $lh,
rgba(white, 0.4) $lh*2,
rgba(white, 0.6) $lh*2,
rgba(white, 0.6) $lh*3,
rgba(white, 0.8) $lh*3,
rgba(white, 0.8));

background-position: bottom center;
}
}

###函数实现淡入淡出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*第四个,淡出效果,mixins*/
/**
* $color, 渐变颜色
* $lh, 段落的行高
* $dir, 渐变方向,可接受参数:'to top'表示淡出,'to bottom'表示淡入
* $n, 渐变的快慢,渐变完成的行数,默认为3行
*************************************************/

@function makesFade($color:white,$lh:1.5em,$dir:'to top',$n:3){
$stripes:$dir+", ";
@for $i from 1 through $n{
$stripes:
$stripes +
rgba($color,$i/$n) + ' ' + ($lh * ($i - 1))
+ ',' +
rgba($color,$i/$n) + ' ' + ($lh * ($i * 1));

@if ($i < $n){
$stripes: $stripes + ',';
}
}
@return unquote('linear-gradient(' + $stripes + ')');
}
section:nth-of-type(4) {
p {
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-image: makesFade(white,$lh,'to top',4);
}
}

###兼容firefox的淡出方式
我们知道上面的案例因为使用webkit内核的background-clip,text-fill-color,因此只兼容webkit内核的浏览器,这不公平。firefox会叫屈不平,所以我们得做点什么。我们把颜色渐变添加在::after伪对象上覆盖文字,注意这时,渐变颜色跟背景颜色一样,透明度从1到0。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*第五个,兼容其他浏览器*/
section:nth-of-type(5) {
p{
position: relative;
}
p::after{
content:"";
width:100%;
height:100%;
position: absolute;
left:0;
bottom:0;
background-image: linear-gradient(
to top,
rgba(#2B293D, 1),
rgba(#2B293D, 1) $lh,
rgba(#2B293D, 0.8) $lh,
rgba(#2B293D, 0.8) $lh*2,
rgba(#2B293D, 0.6) $lh*2,
rgba(#2B293D, 0.6) $lh*3,
rgba(#2B293D, 0.4) $lh*3,
rgba(#2B293D, 0.4) $lh*4,
rgba(#2B293D, 0.2)
);

background-position: bottom center;
}
}

###兼容firefox的函数实现淡入淡出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*第六个,兼容其他浏览器的mixins*/
/**
* $color, 渐变颜色,这里就是背景色。
* $lh, 段落的行高
* $dir, 渐变方向,可接受参数:'to top'表示淡出,'to bottom'表示淡入
* $n, 渐变的快慢,渐变完成的行数,默认为3行
*************************************************/

@function makesFadeOther($color:white,$lh:1.5em,$dir:'to top',$n:3){
$stripes:$dir+", ";
@for $i from 1 through $n{
$stripes:
$stripes +
rgba($color,1-$i/$n) + ' ' + ($lh * ($i - 1))
+ ',' +
rgba($color,1-$i/$n) + ' ' + ($lh * ($i * 1));

@if ($i < $n){
$stripes: $stripes + ',';
}
}
@return unquote('linear-gradient(' + $stripes + ')');
}
section:nth-of-type(6) {
p{
position: relative;
}
p::after {
content:"";
width:100%;
height:100%;
position: absolute;
left:0;
bottom:0;
background-image: makesFadeOther(#2B293D,$lh,'to top',4);
}
}

##相关阅读

##版权说明
前端开发whqet,关注前端开发,分享相关资源。csdn专家博客,王海庆希望能对您有所帮助。
本文欢迎转载,转载请注明,保留原文链接。
本文原文链接,http://whqet.github.io/2015/02/07/段落文字彩条效果/
欢迎大家访问我的博客,http://blog.csdn.net/whqet/

ladies and 乡亲们,表单验证你在做吗?客户端or服务器端,javascript or jquery,动手写 or 使用插件,今天我们来探索下使用纯css实现表单验证,借以学习css selectors level 4中的表单相关的伪类选择器。

##案例欣赏
这里写图片描述
代码我同样放到了codepen,大家可以在线研究,或下载收藏

##知识解析
关键在于使用css selectors levle4里的一些伪类实现表单验证,这些伪类有:

  • :required和:optional
  • :in-range和out-of-range
  • :valid和:invalid
  • :read-only和:read-write

上面的案例就是使用了:in-range和:out-of-range,接下去我们来一一解读下。

###:required和:optional
:required可以选中具有required属性的表单元素,可以是input、select和textarea,例如下面这些元素都会被选中。

1
2
3
4
5
6
7
8
<input type="name" required>
<input type="checkbox" required>
<input type="email" required>
<!-- and other input types as well.. -->
<textarea name="name" id="message" cols="30" rows="10" required></textarea>
<select name="nm" id="sel" required>
<!-- options -->
</select>

:optional则选中不具有required属性的表单元素,利用这两个伪类我们可以实现下面这个有意思的效果。代码同样放在了codepen,在线研究or下载收藏,悉听尊便。
这里写图片描述
本代码主要利用:required和:optional两个伪类对必选和选填的两种表单实施不同的样式,不同的提示文字。核心代码如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*可选表单样式*/
input:optional,
select:optional {
border-right: 3px solid #888;
background-color: #f8f8f8;
color: #888;
}

/*必选表单样式*/
input:required,
textarea:required {
border-right: 3px solid #aa0088;
}

/*可选表单提示文字*/
input:optional+label::after{
content:"(可选)";
}

/*必选表单提示文字*/
input:required+label::after{
content:"(必填)";
}

/*可选表单激活效果*/
input:optional:focus,
select:optional:focus {
box-shadow: 0 0 2px 1px #aaa;
}

/*必选表单激活效果*/
input:required:focus,
select:required:focus,
textarea:required:focus {
outline: 0;
box-shadow: 0 0 2px 1px #aa0088;
}

:in-range和out-of-range

这两个伪类分别选中表单属性值在范围内、范围外两个状态,这两个伪类可以用在接受数字范围的元素上,例如type为number的表单或者sliders。案例效果如上面“案例欣赏”版块所示,我们这里仅仅展示核心代码,借以帮助大家理解两个伪类的使用。

1
2
3
4
5
6
7
8
9
input:out-of-range{
border: 1px solid tomato;
}

input:in-range~ label::after {
content: "输入一个正确的从1到10的数字";
}

input:out-of-range ~ label::after {
content: "枣糕,你傻了!";
}

###:valid和:invalid
这两个伪类针对具有type的input表单而立,比如有一个type=email的表单,当它的值不是有效的邮箱格式时触发:invalid伪类,值为有效的邮箱格式时触发:valid伪类。
这里写图片描述
同样,放在了codepen,请在线研究下载收藏,然后我们来看看核心代码,如下所示。

1
2
3
4
5
6
7
8
9
input:invalid{
border: 1px solid tomato;
}

input:valid~ label::after {
content: "耶,一个邮箱!";
}

input:invalid ~ label::after {
content: "枣糕,邮箱邮箱,是邮箱吗?";
}

:read-only和:read-write

下面这些元素可以激活:read-only伪类。

  • 具有disabled属性的表单
  • 具有read-only或disbaled属性的text-area
  • 其他没有指定contenteditable属性的任何元素

例如下面代码代码所示的元素,都可以激活:read-only伪类选择器。

1
2
3
4
5
<input type="text" disabled>
<input type="number" disabled>
<input type="number" readonly>
<textarea name="nm" id="id" cols="30" rows="10" readonly> </textarea>
<div class="random"> </div> <!-- regular element that is not editable with contenteditable -->

:read-write元素恰恰与:read-only元素相反。
这个比较简单,就不再做案例。谢谢。

##浏览器兼容情况
上述的几个伪类选择器在标准浏览器(chrome、safari、opera、firefox)里支持良好,IE支持不好。

##深入阅读

ladies and 乡亲们,表单验证你在做吗?客户端or服务器端,javascript or jquery,动手写 or 使用插件,今天我们来探索下使用纯css实现表单验证,借以学习css selectors level 4中的表单相关的伪类选择器。

##案例欣赏
这里写图片描述
代码我同样放到了codepen,大家可以在线研究,或下载收藏

##知识解析
关键在于使用css selectors levle4里的一些伪类实现表单验证,这些伪类有:

  • :required和:optional
  • :in-range和out-of-range
  • :valid和:invalid
  • :read-only和:read-write

上面的案例就是使用了:in-range和:out-of-range,接下去我们来一一解读下。

###:required和:optional
:required可以选中具有required属性的表单元素,可以是input、select和textarea,例如下面这些元素都会被选中。

1
2
3
4
5
6
7
8
<input type="name" required>
<input type="checkbox" required>
<input type="email" required>
<!-- and other input types as well.. -->
<textarea name="name" id="message" cols="30" rows="10" required></textarea>
<select name="nm" id="sel" required>
<!-- options -->
</select>

:optional则选中不具有required属性的表单元素,利用这两个伪类我们可以实现下面这个有意思的效果。代码同样放在了codepen,在线研究or下载收藏,悉听尊便。
这里写图片描述
本代码主要利用:required和:optional两个伪类对必选和选填的两种表单实施不同的样式,不同的提示文字。核心代码如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*可选表单样式*/
input:optional,
select:optional {
border-right: 3px solid #888;
background-color: #f8f8f8;
color: #888;
}

/*必选表单样式*/
input:required,
textarea:required {
border-right: 3px solid #aa0088;
}

/*可选表单提示文字*/
input:optional+label::after{
content:"(可选)";
}

/*必选表单提示文字*/
input:required+label::after{
content:"(必填)";
}

/*可选表单激活效果*/
input:optional:focus,
select:optional:focus {
box-shadow: 0 0 2px 1px #aaa;
}

/*必选表单激活效果*/
input:required:focus,
select:required:focus,
textarea:required:focus {
outline: 0;
box-shadow: 0 0 2px 1px #aa0088;
}

:in-range和out-of-range

这两个伪类分别选中表单属性值在范围内、范围外两个状态,这两个伪类可以用在接受数字范围的元素上,例如type为number的表单或者sliders。案例效果如上面“案例欣赏”版块所示,我们这里仅仅展示核心代码,借以帮助大家理解两个伪类的使用。

1
2
3
4
5
6
7
8
9
input:out-of-range{
border: 1px solid tomato;
}

input:in-range~ label::after {
content: "输入一个正确的从1到10的数字";
}

input:out-of-range ~ label::after {
content: "枣糕,你傻了!";
}

###:valid和:invalid
这两个伪类针对具有type的input表单而立,比如有一个type=email的表单,当它的值不是有效的邮箱格式时触发:invalid伪类,值为有效的邮箱格式时触发:valid伪类。
这里写图片描述
同样,放在了codepen,请在线研究下载收藏,然后我们来看看核心代码,如下所示。

1
2
3
4
5
6
7
8
9
input:invalid{
border: 1px solid tomato;
}

input:valid~ label::after {
content: "耶,一个邮箱!";
}

input:invalid ~ label::after {
content: "枣糕,邮箱邮箱,是邮箱吗?";
}

:read-only和:read-write

下面这些元素可以激活:read-only伪类。

  • 具有disabled属性的表单
  • 具有read-only或disbaled属性的text-area
  • 其他没有指定contenteditable属性的任何元素

例如下面代码代码所示的元素,都可以激活:read-only伪类选择器。

1
2
3
4
5
<input type="text" disabled>
<input type="number" disabled>
<input type="number" readonly>
<textarea name="nm" id="id" cols="30" rows="10" readonly> </textarea>
<div class="random"> </div> <!-- regular element that is not editable with contenteditable -->

:read-write元素恰恰与:read-only元素相反。
这个比较简单,就不再做案例。谢谢。

##浏览器兼容情况
上述的几个伪类选择器在标准浏览器(chrome、safari、opera、firefox)里支持良好,IE支持不好。

##深入阅读

###引言
今天来看一组表单标签动画效果,希望可以对大家有所帮助,灵感来自于Inspiration for Text InputText Input Love,一并致谢。
表单标签动画畅想
效果照例放在Codepen,虽少效果较慢,但值得期待。在线编辑下载收藏

###搭建根基
我们同样使用了haml来简化html书写。

1
#container
  -(1..15).each do
    %div.row
      %label
        %input{:type=>"text"}
        %span姓名
      %label
        %input{:type=>"text"}
        %span性别
      %label
        %input{:type=>"text"}
        %span邮箱

css部分我们使用了scss,首先我们来搭建页面布局和基础设置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/* 重置*/
*, *:before, *:after { box-sizing: border-box; }
/*容器设置*/
#container{
counter-reset: counterA;
}
/*布局实现*/
div.row{
position: relative;
width: 100%;
height:20vw;
padding-left:15vw;
counter-increment: counterA;
&:before{
content:counter(counterA);
color:rgba(255,255,255,.05);
font-size:10vw;
position: absolute;
left:0px;
}
label{
position: relative;
display: block;
float: left;
margin:8vw 2vw;
input{
width:160px;
height:30px;
line-height:30px;
background: rgba(255,255,255,.1);
border:none;
outline:none;
border:1px solid #fff;
color: #377D6A;
padding:4px 10px;
border-radius:4px;
text-indent: 38px;
transition: all .3s ease-in-out;

::-webkit-input-placeholder {
color: transparent;

}
+span{
position: absolute;
left:0;
top:0;
color:#fff;
background: #7AB893;
display: inline-block;
padding: 7px 4px;
transform-origin:left center;
transform: perspective(300px);
transition: all .3s ease-in-out;
border-radius:4px 0 0 4px;
}
}
input:focus,
input:active {
text-indent: 0;
background: rgba(255,255,255,.2);

::-webkit-input-placeholder {
color: #f00;

}
+span{
background: darken(#7AB893,20%);
}
}
}
/*设置背景色,随机颜色*/
@for $i from 1 through 15{
&:nth-child(#{$i}){
background:hsl(random(360),60%,30%);
}
}
//设置每一行的动画效果
//&:nth-child(1){}
}

###效果一
这里写图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
//设置每一行的动画效果
//&:nth-child(1){}
//效果一,标签左移
&:nth-child(1){
input:focus,
input:active{
border-radius:0 4px 4px 0;
+span{
border-radius:4px 0 0 4px;
transform: translateX(-100%);
}
}
}

###效果二
这里写图片描述

1
2
3
4
5
6
7
8
9
10
//效果二,标签右移
&:nth-child(2){
input:focus,
input:active{
+span{
border-radius:0 4px 4px 0;
transform: translateX(300%);
}
}
}

###效果三
这里写图片描述

1
2
3
4
5
6
7
8
9
10
11
//效果三,标签上移
&:nth-child(3){
input:focus,
input:active{
text-indent: 0px;
+span{
background-color: transparent;
transform: translateY(-100%);
}
}
}

###效果四
这里写图片描述

1
2
3
4
5
6
7
8
9
10
11
//效果四,标签下移
&:nth-child(4){
input:focus,
input:active{
text-indent: 0px;
+span{
background-color: transparent;
transform: translateY(100%);
}
}
}

###效果五
这里写图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//效果五,标签上旋
&:nth-child(5){
input+span{
transform-origin:left bottom;
}
input:focus,
input:active{
border-radius:0 4px 4px 0;
text-indent: 20px;
+span{
transform: rotate(-60deg);
border-radius:0 4px 4px 0;
}
}
}

###效果六
这里写图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//效果六,标签下旋
&:nth-child(6){
input+span{
transform-origin:left bottom;
}
input:focus,
input:active{
border-radius:0 4px 4px 0;
+span{
animation:swing 1s;
animation-fill-mode: forwards;
border-radius:0 4px 4px 0;
}
}
}
//第6个动画
@keyframes swing{
0% {
transform: rotate(0);
}
20% {
transform: rotate(116deg);
}
40% {
transform: rotate(60deg);
}
60% {
transform: rotate(98deg);
}
80% {
transform: rotate(76deg);
}
100% {
transform: rotate(82deg);
}
}

###效果七
这里写图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
//效果七,标签左折
&:nth-child(7){
input+span{
transform-origin:right center;
}
input:focus,
input:active{
border-radius:0 4px 4px 0;
+span{
transform:perspective(300px) translateX(-100%) rotateY(60deg);
}
}
}

###效果八
这里写图片描述

1
2
3
4
5
6
7
8
9
10
11
//效果八,标签左翻
&:nth-child(8){
input:focus,
input:active{
border-radius:0 4px 4px 0;
+span{
transform: rotateY(180deg);
border-radius:0 4px 4px 0;
}
}
}

###效果九
这里写图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//效果九,标签上移变提示框
&:nth-child(9){
input{
+span{
background: transparent;
&:before{
content:"";
width:0;
height:0;
position: absolute;
left:20px;
bottom:-10px;
border:5px solid #000;
border-color:darken(#7AB893,20%) transparent transparent transparent;
transition:all .3s;
opacity: 0;
}
}
}
input:focus,
input:active{
+span{
padding:3px 10px;
border-radius:6px;
transform:translateY(-150%);
&:before{
opacity: 1;
}
}
}
}

###效果十
这里写图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//效果十,标签上移,框变色
&:nth-child(10){
input{
border-width:1px 0;
border-radius:0;
+span{
background: transparent;
}
}
input:focus,
input:active{
border-width:2px 0;
border-color:#000;
+span{
background:transparent;
transform:translateY(-120%);
}
}
}

###效果十一
这里写图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 //效果十一,标签左弹性
&:nth-child(11){
input{
border-radius:0;
border-width:1px 0;
+span{
background: transparent;
}
}
input:focus,
input:active{
+span{
background:transparent;
border:1px solid #fff;
border-radius:0;
border-width:0 0 0 1px;
animation:halfLeft .6s ease-in;
animation-fill-mode: forwards;
}
}
@keyframes halfLeft{
20%{
transform:translateX(-60%);
}
40%{
transform:translateX(-42%);
}
60%{
transform:translateX(-56%);
}
80%{
transform:translateX(-46%);
}
100%{
transform:translateX(-50%);
}
}
}

###效果十二
这里写图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//效果十二,横线上移
&:nth-child(12){
input{
border-radius:0;
border-width:0;
background:transparent;
+span{
background: transparent;
&:before{
content:"";
width:160px;
height:1px;
background-color: #fff;
position: absolute;
left:0;
bottom:0;
}
}
}
input:focus,
input:active{
+span{
background:transparent;
transform:translateY(-100%);
}
}
}

###效果十三
这里写图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//效果十三,边框动画
&:nth-child(13){
input{
border-radius:0;
border:1px solid #fff;
border-top-color:rgba(255,255,255,0);
border-right-color:rgba(255,255,255,0);
border-bottom-color:rgba(255,255,255,1);
border-left-color:rgba(255,255,255,0);
background:transparent;
+span{
background: transparent;
}
}
input:focus,
input:active{
transition:none;
animation:borderAnim 3s;
animation-fill-mode:forward;
border:1px solid #fff;
+span{
background:transparent;
transform:translateY(-100%);
}
}
}
@keyframes borderAnim{
25%{
border-top-color:rgba(255,255,255,0);
border-right-color:rgba(255,255,255,1);
border-bottom-color:rgba(255,255,255,1);
border-left-color:rgba(255,255,255,0);
}
50%{
border-top-color:rgba(255,255,255,1);
border-right-color:rgba(255,255,255,1);
border-bottom-color:rgba(255,255,255,1);
border-left-color:rgba(255,255,255,0);
}
75%{
border-top-color:rgba(255,255,255,1);
border-right-color:rgba(255,255,255,1);
border-bottom-color:rgba(255,255,255,1);
border-left-color:rgba(255,255,255,1);
}
}

###效果十四
这里写图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//效果十四,前后立体变化
&:nth-child(14){
input{
border-radius:0;
border:1px solid #fff;
transform-origin:left center;
color:#fff;
+span{
background: transparent;
}
}
input:focus,
input:active{
transform:scale(1.2);
box-shadow:0px 0px 2px #000;
color:#fff;
border:2px solid #fff;
+span{
background:transparent;
transform:translateY(-100%) scale(0.8);
}
}
}

###效果十五
这里写图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//效果十五,背景条纹动画
&:nth-child(15){
input{
border-radius:0;
border:1px solid #fff;
background-color: #026873;
background-image: linear-gradient(90deg, rgba(255,255,255,.07) 50%, transparent 50%),
linear-gradient(90deg, rgba(255,255,255,.13) 50%, transparent 50%),
linear-gradient(90deg, transparent 50%, rgba(255,255,255,.17) 50%),
linear-gradient(90deg, transparent 50%, rgba(255,255,255,.19) 50%);

background-size: 13px, 29px, 37px, 53px;
animation: shadowGo 10s linear infinite;
animation-play-state:running;
+span{
background: transparent;
}
}
input:focus,
input:active{
background-color: #137884;
background-size: 13px, 29px, 37px, 53px;
animation-play-state:paused;
+span{
transform:translateY(-100%) scale(0.8);
background:transparent;
color:#137884;
}
}
}
@keyframes shadowGo{
0% {background-position: 0 0}
100% {background-position: -600% 0%}
};

十五种动画效果,希望可以对您有所帮助。如果你耐着性子读到这里,是我的莫大荣幸,感谢感谢。
欢迎评论,欢迎拍砖。

####前端开发whqet,关注前端开发,分享相关资源。csdn专家博客,王海庆希望能对您有所帮助。

####本文原文链接,http://blog.csdn.net/whqet/article/details/43369821