click事件修改css_CSS Click事件

click事件修改css

For the last few years, we’ve been witnessing the wonderful expansion of front-end languages especially HTML with the HTML5 specifications and CSS with the CSS Level 3 specifications.

We can now do a lot of stuff we couldn’t have done without JavaScript or images before, like rounded corners, gradients, responsive layouts, grid stuff, transparency in colors, and so much more.

But one thing we’ve always been missing is the possibility to handle click events with CSS. Actually, some people think we shouldn’t have this option since interactions are more like a JavaScript kind of stuff. I understand the idea, but it always bothered me to have to use JavaScript for a very simple click event.

Anyway, as of today, CSS doesn’t provide any official way to handle a click event in CSS. But there are some very interesting tricks that we can use to “detect” a click using CSS only, without a single line of JavaScript, and this is what we are going to talk about today.

免责声明 (Disclaimer)

This blog post is about showing the possibilities of CSS and some clever hacks. It’s clearly not for “real life” use cases. Please, consider the whole article as a playground for experimenting, not as a tutorial to handle click events on your website or application.

Plus, some of these techniques are not well supported by browsers, meaning it’s even more borderline; we intend to have some fun pushing the limits of CSS.

复选框黑客 (Checkbox hack)

Aaaaah, the checkbox hack. What a thing my friends! I’m sure you’ve all heard about the checkbox hack before. It’s probably the most common way to handle a click event in CSS. It relies on, well, a checkbox.

What’s cool about a checkbox is the fact that it’s binary. It’s either checked or not checked. There is no “half-way” checked. This is why the checkbox hack is a pretty reliable way to trigger a click event in CSS. Let’s make an example.

怎么运行的 (How it works)

The HTML

HTML


<input type="checkbox">
<p class="to-be-changed">I'm going to be red! It's gonna be legen... Wait for it...</p>



The CSS

CSS


.to-be-changed {
color: black;
}

input[type=checkbox]:checked ~ .to-be-changed {
color: red;
}



As you can see, it relies on the :checked pseudo-class and on the general sibling selector ~. Please note that it also works like a charm with the adjacent sibling selector +. Basically, it says “if the checkbox is checked, then the following elements with the .to-be-changed class will be red”.

Okay, a checkbox isn’t very sexy, but you can totally make something nicer by hiding the checkbox and binding a label to it. Something like this maybe:


<input type="checkbox" id="toggle">
<label for="toggle">Click me!</label>
<p class="to-be-changed">I'm going to be red! It's gonna be legen... Wait for it...</p>



So we hide the checkbox and use the label to trigger the click event.


input[type=checkbox] {
position: absolute;
top: -9999px;
left: -9999px;
}

label {
display: block;
background: #08C;
border: 1px solid rgba(0,0,0,.1);
color: white;
font-weight: bold;
}

input[type=checkbox]:checked ~ .to-be-changed {
color: red;
}



This way, you have some kind of button triggering the color change on the paragraph. Isn’t that cool? Re-clicking on the button is switching the color back to black of course.

(Note that there are different possibilities for hiding the checkbox, the most obvious of all being display:none.)

(请注意，隐藏复选框有多种可能性，其中最明显的是display:none 。)

You can see a demo here: Checkbox hack demo

优点缺点 (Pros & Cons)

优点(Pros)
• Binary, checked or not checked

二进制，已检查或未检查
• Clicking again gets you back to the first state (can also be a con if you consider having to click a second time is a pain)

再次单击将使您返回第一种状态(如果您认为必须第二次单击则很痛苦，这也可能是一个缺点)
• Allows chained click events (if first checkbox clicked and second checkbox clicked then do something)

允许链接的点击事件(如果单击了第一个复选框，然后单击了第二个复选框，则执行某些操作)
缺点 (Cons)
• Elements have to share the same parent (siblings)

元素必须共享同一父级(兄弟姐妹)
• Requires some extra HTML (input, label, etc.)

需要一些额外HTML(输入，标签等)
• Requires two workarounds to make it work on mobile browsers (please refer to further readings)

需要两个变通办法才能使其在移动浏览器上正常工作(请参阅更多参考资料)

There are like a bazillion demos with the checkbox hack since it’s clearly the most common way to handle a click event with pure CSS. However, there are probably a few things you may want to read about it:

：target方式(The :target way)

There is another way, well known to “fake” a click event with CSS, using the :target pseudo-class. This pseudo-class is quite similar to the :hover one in the way that it matches only a specific scenario.

The special event for the :target pseudo-class depends on what we call a “fragment identifier”. To put it simple, this pseudo-class refers to a hashtag you can see sometimes at the end of the URL. So it matches when the hashtag and the ID of an element are the same.

：target伪类的特殊事件取决于我们所谓的“片段标识符”。 简而言之，该伪类引用的是您可能有时在URL末尾看到的主题标签。 因此，当主题标签和元素的ID相同时，它就匹配。

怎么运行的 (How it works)

The HTML

HTML


<a href="#id">Click me!</a>
<p id="id" class="to-be-changed">I'm going to be red! It's gonna be legen... Wait for it...</p>



The CSS

CSS


.to-be-changed {
color: black;
}

.to-be-changed:target {
color: red;
}



Basically, when clicking on the link (href="#id"), the URL changes and you go to the anchor #id in the page. In this very moment, the element having this id can be targeted with the :target pseudo-class.

You can see a demo here: :target way demo

优点缺点 (Pros & Cons)

优点(Pros)
• Very light CSS

很轻CSS
• Perfect for highlighting sections

非常适合突出显示部分
缺点(Cons)
• Messes with the browser history

浏览器历史记录
• Makes a page jump (when reaching to the anchor)

使页面跳转(到达锚点时)
• Requires an anchor tag to trigger the hashtag or a URL hack

需要锚标签来触发主题标签或URL hack
• Can only affect one element (since IDs are unique)

只能影响一个元素(因为ID是唯一的)
• No way of getting back to first state without another hashtag, a link, or a URL hack

没有其他标签，链接或URL hack，就无法回到第一状态

The browser support isn’t great but honestly, it’s not that bad. All major browsers support it well except Internet Explorer 6 to 8. So starting from IE9, you’re good.

：focus方式(The :focus way)

Let’s continue with another way using a pseudo-class; the :focus one this time. It’s pretty much the same idea, except, it doesn’t expect a URL change. It relies on the user’s focus on a particular element.

When you’re on a web page, you can press the tab key to navigate through various elements on the page. It’s particularly useful when filling forms, to go from one field to another without having to use the mouse. It’s also used by blind or visually impaired people to navigate through a site.

What’s important to note is that some elements can be focused, like links, inputs and such, and some other can’t, like paragraphs, divisions, and plenty others. Actually they can, but you’ll need to add the tabindex attribute with a numeric value.

怎么运行的 (How it works)

The HTML

HTML


<span tabindex="0">Click me!</span>
<p class="to-be-changed">I'm going to be red! It's gonna be legen... Wait for it...</p>



The CSS

CSS


span:focus ~ .to-be-changed {
color: red;
}



So, when you click on the span or reach it with the tab key, it becomes focused and matches the :focus pseudo-class. The adjacent sibling selector does the rest. Pretty easy, right? If you don’t want to mess with the tabindex for any reason, you can simply use a link with a # href. It will work like a charm as well.

You can see a demo here: :focus way demo

优点缺点 (Pros & Cons)

优点(Pros)
• Very light CSS and HTML

非常轻巧CSS和HTML
• Great for navigation or similar

非常适合导航或类似
缺点(Cons)
• Requires either a focusable element or the tabindex attribute

需要焦点元素或tabindex属性
• Matches only when the element is focused (which means clicking elsewhere will mess it up)

仅在元素集中时匹配(这意味着单击其他位置会使其混乱)

过渡黑客(Transition hack)

This is probably the most wicked way to handle a click event in CSS. Seriously guys, this is madness. This technique comes from Joel Besada and has always been one of my favorite CSS tricks.

The idea is to store a CSS style in a CSS transition. Yeah, you read it right, a CSS transition. Actually, the idea is pretty simple. It relies on applying a pseudo-infinite delay to a change in order to prevent it to get back to the default value. It may sound complicated but it’s fairly easy, trust me. Please have a look at the code.

怎么运行的 (How it works)

The HTML

HTML


<span>Click me!</span>
<p class="to-be-changed">I'm going to be red! It's gonna be legen... Wait for it...</p>



The CSS

CSS


.to-be-changed {
transition: all 0s 9999999s;
}

span:active ~ .to-be-changed {
transition: all 0s;
color: red;
}



The idea behind the first declaration is to delay any change to approximately 116 days to make sure the changes will stay once they’ve been set. It is not infinite, but kind of, right?

But we don’t want to apply the changes 116 days after clicking, we want it to be set immediately! So the idea is to override the delay during the click (:active pseudo-class) to apply the changes. Then when the click will be released, the old transition property will kick back in, setting back the delay to 9999999s, preventing the changes to going back to the default state.

You can see a demo here: Transition hack demo

优点缺点 (Pros & Cons)

优点(Pros)
• Insanely clever

疯狂的聪明
• Keeps the exact value when releasing the click, even if the transition isn’t finished yet (see below)

释放点击时仍保留确切的值，即使转换尚未完成(请参阅下文)

[…] a cool fact is that you can end a transition halfway through and have the property still keep the exact value that it had at that point in the transition. So for example, let’s say we have a linear transition from opacity 1 to 0 over two seconds, but only let it run for one second. The opacity value should now be stuck at 0.5 because the delay prevents it from going back. If we now were to run the opacity transition again, it would continue from 0.5 instead of starting over from the beginning.

[…]一个很酷的事实是，您可以在过渡中途结束过渡，并让该属性仍然保留过渡时该点的确切值。 举例来说，假设我们在两秒钟内从不透明度1到0进行了线性转换，但只让其运行了一秒钟。 现在，不透明度值应保持在0.5，因为延迟会阻止它返回。 如果现在再次运行不透明度转换，它将从0.5开始而不是从头开始。

缺点 (Cons)
• Decent but not so good browser support (not IE9- and Opera Mini)

不错，但浏览器支持不太好(不是IE9和Opera Mini)
• Only works with transitionable values

仅适用于可转换的值
• No way of getting back to the first state

无法回到第一状态
• Not really infinite if you can afford waiting 116 days

如果您负担得起等待116天，并不是真的无限

最后的话 (Final words)

As of today, we can do some click detections with CSS. I mean, this is possible even if it’s pretty much a hack in any case. Some ways are better than others for some situations, but all in all, it’s not something to be used in a real project.

Tab Atkins Jr. blogged about this a few months ago. He wrote a whole proposal about toggling states in CSS. A glance at his work:

Tab Atkins Jr.几个月前就对此发表了博客。 他撰写了有关在CSS中切换状态的完整提案。 看一下他的工作：


toggle-states:  none | <integer> sticky? | infinity  (initial: none)
toggle-group:   none | <ident>  (initial: none)
toggle-share:   none | <selector>#  (initial: none)
toggle-initial: <integer>  (initial: 1)



… where:

……其中：

• toggle-states is the basic function that turns toggle functionality on/off. None means it doesn’t toggle, 2 or more implements different states of checked.

toggle-states是打开/关闭切换功能的基本功能。 None表示不切换，2个或更多实现不同的checked状态。

• toggle-group implements the radio-button functionality. If you click an element with toggle-group set to a non-none value, all elements sharing the same toggle-group will be automatically set to first state (off)

toggle-group实现单选按钮功能。 如果单击切换组设置为非值的元素，则共享同一切换组的所有元素将自动设置为第一状态(关闭)

• toggle-share implements the label functionality. When you click an element with toggle-share, it acts as if you’d clicked all the elements it points to.

toggle-share实现标签功能。 当您单击带有切换共享的元素时，它的作用就像您单击了它所指向的所有元素。

• toggle-initial sets the initial state of the toggle

toggle-initial设置toggle-initial的初始状态

However, he admitted his idea is not perfect and can still face some issues and paradoxes. I won’t go any further into the topic since it would be out of the scope of this article, but I highly suggest you read it. Even if it’s incomplete, it’s still brilliant.

So we’re back to JavaScript. It’s probably the best way to go if you want consistency and reliability. However, if you want to have fun doing things “the pure CSS way”, then you might have found this article useful. 😉

On a side note, Chris Coyier at CSS-Tricks wrote a blog post about handling double clicks with pure CSS about 2 years ago. It may be old, but it’s still very interesting to see some of the ways to get (or fail to get) there.

Anyway, thanks a lot for reading guys. Please be sure to ask questions or show any related work!

click事件修改css

07-25 2495
10-14 2万+
06-27 256
09-17 216
08-14 9705
02-02 3007