You DON'T need JavaScript

这哪是入门这是Trick

Posted by Donggu Ho on 2017-03-29

算了我还是去学JavaScript吧

这两天看见一个名为You-Dont-Need-Javascript的库……吓得我头都掉了。项目仅使用htmlCSS3就完成了各种点击轮播、手风琴、点击三状态样式切换、计数器、甚至数独游戏(??????????)等一系列功能……可以说是不讲道理了。你让我一个昨天面试还不会用JavaScript写轮播的人怎么活!于是认真研读了一下,这些项目主要是活用了CSS选择器的部分语法、input的各种伪类以及labelfor属性。

相关知识

CSS选择器

虽然CSS选择器常用的语法也就是tag .class #id,顶多加上element1 element2还有element1>element2,但其实还有许多不常用但仔细想想也挺实用的CSS选择器语法

  • element1 + element2
    选择紧跟在element1后面的第一个element2元素(同级元素),CSS2语法。

  • element1 ~ element2
    选择在element1后面的所有element2元素(同级元素),CSS3语法。

  • [attribute]
    选择含有attribute属性的元素,CSS2语法。

input伪类

其实伪类也属于CSS选择器的一部分。由于input元素的单击会导致其伪类的变更,因此可以作为一个点击事件绑定的“源头”。
以下伪类皆为CSS3语法:

  • input:checked
    被选中的input

  • input:enabled
    被启用的input

  • input:disabled
    被禁用的input

伪元素

伪元素的::before::after也是值得一提。可以通过编辑其content属性,在特定元素的前面和后面添加特定的内容,而且这是用css实现的,对html没有修改;这意味着对于爬虫和搜索引擎它是不可见的(虽然并不是不能实现,但绝大多数情况下爬虫和搜索引擎都不会考虑CSS),所以你不能把重要的需要被索引的信息放在里面。通常content用于装饰性质的元素添加,比如流行的在引用块的前后添加巨大的有样式的双引号等。考虑到这些元素本来就是作为装饰的辅助性存在,将其一并封装到CSS里面显然更加合理。
另外伪元素还有对n-child以及首字母等相关的伪类选择器,也是非常方便哒。

label元素

<label>标签相当于一种input元素的优化:它扩展了input元素的点击范围。<label> 标签本身不会为元素添加任何属性,这种角度来看与<span>非常类似。它通过for属性绑定到指定的表单元素,因此可以成为表单元素的扩展,绝大多数表单控件的美化也是通过这个完成的:隐藏无法改变样式的<input>元素本身(通常是单选或复选),展示效果多样的<label>,通过for进行指定。

1
2
3
4
<input type='radio' id="input1" style="display: none"/>
<label for="input1">
<anything></anything>
</label>

关于如何隐藏<input>元素,使用display: none的样式有一定的争议:这会导致读屏软件无法得知input元素的存在,对特殊人群形成不便。因此当需要读屏软件识别input时,推荐的做法是是用类似position: absolute; left: -200%的样式将其显示在屏幕外,但对读屏软件没有影响。

无JS的手风琴的实现

手风琴组件即 Accordion,是经典的网页组件。网上能找到的绝大多数实现都依赖了 JavaScript 和 jQuery。
实现效果如下:

  • This is an example accordion item

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nec posuere lorem. Pellentesque hendrerit, lorem luctus porttitor vestibulum, eros sapien mattis libero, euismod congue neque nisi at ipsum. Mauris semper ipsum sit amet metus semper malesuada. Donec vel est justo, ac porta diam.

    In ut est in orci commodo blandit. Cras rhoncus ultricies augue. Proin quam odio, venenatis ut tempus tristique, aliquet in velit. Pellentesque volutpat facilisis orci, ut congue mi rhoncus at. Nullam vehicula dignissim neque, sed rhoncus magna ultricies et.

  • Totally another one right here

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nec posuere lorem. Pellentesque hendrerit, lorem luctus porttitor vestibulum, eros sapien mattis libero, euismod congue neque nisi at ipsum. Mauris semper ipsum sit amet metus semper malesuada. Donec vel est justo, ac porta diam.

    In ut est in orci commodo blandit. Cras rhoncus ultricies augue. Proin quam odio, venenatis ut tempus tristique, aliquet in velit. Pellentesque volutpat facilisis orci, ut congue mi rhoncus at. Nullam vehicula dignissim neque, sed rhoncus magna ultricies et.

  • I think I can go on forever

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nec posuere lorem. Pellentesque hendrerit, lorem luctus porttitor vestibulum, eros sapien mattis libero, euismod congue neque nisi at ipsum. Mauris semper ipsum sit amet metus semper malesuada. Donec vel est justo, ac porta diam.

    In ut est in orci commodo blandit. Cras rhoncus ultricies augue. Proin quam odio, venenatis ut tempus tristique, aliquet in velit. Pellentesque volutpat facilisis orci, ut congue mi rhoncus at. Nullam vehicula dignissim neque, sed rhoncus magna ultricies et.

  • I was wrong, I’m done

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nec posuere lorem. Pellentesque hendrerit, lorem luctus porttitor vestibulum, eros sapien mattis libero, euismod congue neque nisi at ipsum. Mauris semper ipsum sit amet metus semper malesuada. Donec vel est justo, ac porta diam.

    In ut est in orci commodo blandit. Cras rhoncus ultricies augue. Proin quam odio, venenatis ut tempus tristique, aliquet in velit. Pellentesque volutpat facilisis orci, ut congue mi rhoncus at. Nullam vehicula dignissim neque, sed rhoncus magna ultricies et.

html

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
<div class="accordion">
<ul>
<li>
<input type="radio" id="radio-1" name="radio-accordion" checked="checked" />
<label for="radio-1">Title:One</label>
<div class="content">
<h3>This is an example accordion item</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nec posuere lorem. Pellentesque hendrerit, lorem luctus porttitor vestibulum, eros sapien mattis libero, euismod congue neque nisi at ipsum. Mauris semper ipsum sit amet metus semper malesuada. Donec vel est justo, ac porta diam.</p>
<p>In ut est in orci commodo blandit. Cras rhoncus ultricies augue. Proin quam odio, venenatis ut tempus tristique, aliquet in velit. Pellentesque volutpat facilisis orci, ut congue mi rhoncus at. Nullam vehicula dignissim neque, sed rhoncus magna ultricies et.</p>
</div>
</li>
<li>
<input type="radio" id="radio-2" name="radio-accordion" />
<label for="radio-2">Title:Two</label>
<div class="content">
<h3>Totally another one right here</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nec posuere lorem. Pellentesque hendrerit, lorem luctus porttitor vestibulum, eros sapien mattis libero, euismod congue neque nisi at ipsum. Mauris semper ipsum sit amet metus semper malesuada. Donec vel est justo, ac porta diam.</p>
<p>In ut est in orci commodo blandit. Cras rhoncus ultricies augue. Proin quam odio, venenatis ut tempus tristique, aliquet in velit. Pellentesque volutpat facilisis orci, ut congue mi rhoncus at. Nullam vehicula dignissim neque, sed rhoncus magna ultricies et.</p>
</div>
</li>
<li>
<input type="radio" id="radio-3" name="radio-accordion" />
<label for="radio-3">Title:Three</label>
<div class="content">
<h3>I think I can go on forever</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nec posuere lorem. Pellentesque hendrerit, lorem luctus porttitor vestibulum, eros sapien mattis libero, euismod congue neque nisi at ipsum. Mauris semper ipsum sit amet metus semper malesuada. Donec vel est justo, ac porta diam.</p>
<p>In ut est in orci commodo blandit. Cras rhoncus ultricies augue. Proin quam odio, venenatis ut tempus tristique, aliquet in velit. Pellentesque volutpat facilisis orci, ut congue mi rhoncus at. Nullam vehicula dignissim neque, sed rhoncus magna ultricies et.</p>
</div>
</li>
<li>
<input type="radio" id="radio-4" name="radio-accordion" />
<label for="radio-4">Title:Four</label>
<div class="content">
<h3>I was wrong, I'm done</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nec posuere lorem. Pellentesque hendrerit, lorem luctus porttitor vestibulum, eros sapien mattis libero, euismod congue neque nisi at ipsum. Mauris semper ipsum sit amet metus semper malesuada. Donec vel est justo, ac porta diam.</p>
<p>In ut est in orci commodo blandit. Cras rhoncus ultricies augue. Proin quam odio, venenatis ut tempus tristique, aliquet in velit. Pellentesque volutpat facilisis orci, ut congue mi rhoncus at. Nullam vehicula dignissim neque, sed rhoncus magna ultricies et.</p>
</div>
</li>
</ul>
</div>

CSS

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
/*使用styls生成*/
.accordion {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
background: #efefef;
border-radius: 5px;
padding: 0;
}
.accordion ul {
list-style: none;
padding: 0;
margin: 0;
}
.accordion ul li {
padding: 0;
margin: 0;
}
.accordion ul input[type='radio'] {
display: none;
}
.accordion ul label {
display: block;
text-align: center;
background: #444;
font-size: 20px;
color: #fff;
border-radius: 5px;
padding: 0.2em 0;
}
.accordion ul .content {
overflow: hidden;
height: 10px;
transition: all 0.3s ease-out;
padding: 0 20px;
}
.accordion ul input:checked ~ .content {
height: 300px;
}

总结

据说使用CSS来实现的话可以提高性能。在CSS3的条件下甚至达成了平滑的过渡效果,美哉。强烈推荐去看看这个库的其它实现,非常长见识。