惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
Google Developers Blog
S
Schneier on Security
The Hacker News
The Hacker News
P
Proofpoint News Feed
Spread Privacy
Spread Privacy
L
LINUX DO - 热门话题
L
Lohrmann on Cybersecurity
I
Intezer
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Schneier on Security
Schneier on Security
Security Latest
Security Latest
AWS News Blog
AWS News Blog
B
Blog RSS Feed
Microsoft Security Blog
Microsoft Security Blog
有赞技术团队
有赞技术团队
博客园 - 叶小钗
The Last Watchdog
The Last Watchdog
O
OpenAI News
月光博客
月光博客
Hacker News: Ask HN
Hacker News: Ask HN
阮一峰的网络日志
阮一峰的网络日志
S
Security @ Cisco Blogs
Google Online Security Blog
Google Online Security Blog
云风的 BLOG
云风的 BLOG
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Latest news
Latest news
P
Palo Alto Networks Blog
Last Week in AI
Last Week in AI
M
MIT News - Artificial intelligence
Google DeepMind News
Google DeepMind News
P
Proofpoint News Feed
C
CERT Recently Published Vulnerability Notes
Apple Machine Learning Research
Apple Machine Learning Research
U
Unit 42
PCI Perspectives
PCI Perspectives
博客园 - 聂微东
SecWiki News
SecWiki News
宝玉的分享
宝玉的分享
Forbes - Security
Forbes - Security
H
Heimdal Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Hugging Face - Blog
Hugging Face - Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
Troy Hunt's Blog
博客园 - 三生石上(FineUI控件)
Application and Cybersecurity Blog
Application and Cybersecurity Blog
罗磊的独立博客
WordPress大学
WordPress大学
D
Darknet – Hacking Tools, Hacker News & Cyber Security

Impressive Webs

Transforming Healthcare with VR: Virtual Surgery and Patient Simulation YouTube's Time-Based UX Problem for Live Sports Don't Let ChatGPT Write Your Code CSS Rules vs. CSS Rulesets - Impressive Webs Filestack: A File Uploader and Powerful APIs for App Content Delivery How to Disable JavaScript in Almost Any Browser - Impressive Webs A Review of ipwhois.io for Reliable Geolocation Data The Most Interesting Developer Tools for 2021 - Impressive Webs Fading in a Page on Load with CSS & JavaScript
Detecting Specific Text Input with HTML and CSS
https://www.facebook.com/ImpressiveWebs/ · 2021-10-20 · via Impressive Webs

Recently I came across a CodePen demo by a developer/engineer named Jane that was Tweeted out by Šime Vidas. The demo has a neat collection of HTML and CSS tricks rolled into one that I thought was worth examining in detail.

The page displays a secret message based on specific text input. Ok, that’s no big deal, right? Well this is done using pure HTML and CSS – no JavaScript. I’ve seen stuff like this before, but I thought it would be cool to break down exactly how this works. There are a few notable things happening in the code so I’ll break down each of the parts. Here’s the demo:

See the Pen
Add secret website button codes with vanilla CSS (NO JS!)
by Jane 💜 (@propjockey)
on CodePen.

Just make sure, as the instruction says, that your cursor is focused inside the CodePen preview window.

Using HTML’s accesskey

As the revealed secret message points out, the demo is using HTML’s accesskey attribute. That’s a bit of a blast from the past for some of us. It’s an old feature that:

provides a hint for generating a keyboard shortcut for the current element.

This means the user can trigger focus on the targeted element using a browser- or platform-specific key combination along with the specified accesskey value (which can be any “printable” character generated by the keyboard).

You can set up an accesskey value like this:

<input accesskey="c">

MDN’s article on accesskey has a handy chart showing how the accesskey can be triggered by the user on different browsers and platforms. The most likely combination is either ALT-KEY (Windows) or CTRL-ALT-KEY (Mac) – though there are a lot of variations depending on the browser.

In Jane’s demo, the input is visually hidden but still accessible. I’ll get to more on accesskey in a moment but let’s also look at the other interesting things in the demo.

Using the pattern Attribute

The other thing that makes this trick work is the use of the pattern attribute on the hidden text field. Strangely, MDN’s article doesn’t display the browser compatibility for pattern, but the attribute seems to be safe to use. If I recall correctly, this feature was added a little later than other HTML5 forms features.

This attribute accepts a regular expression that should be matched for the form field to validate. It can be used on text, tel, email, url, password, and search inputs.

In this instance, the demo isn’t using any special regex characters to do anything fancy – it’s just straight text that’s matched.

<input accesskey="c" pattern="wow!">

But there’s no form submission going on here, so how is this form field being “validated”?

The :valid and :placeholder-shown Pseudo-classes

In order to check if the form field is valid, the demo makes use of the :valid CSS pseudo-class. So you can do something like the following to apply different styles to a form field that’s valid but hasn’t been submitted yet:

:valid {
  border: solid 1px green;
}

This will instantly place a green border on any valid form field, no need for form submission. There’s also a pseudo-class of :invalid which does the opposite. Both have good browser support, so don’t be afraid to use these.

The demo also uses the :placeholder-shown pseudo-class. This pseudo-class targets elements that are using the HTML placeholder attribute and whose placeholder value is visible (i.e. the user hasn’t inserted text to remove the placeholder value).

:placeholder-shown {
  background: white;
}

This feature isn’t important to the overall technique, but it’s part of the big selector that I’ll discuss next.

The Big Fancy CSS Selector

Once we understand those two pseudo-classes, then we can begin to grasp the big selector used in the demo:

.secret-code:not(:placeholder-shown):valid ~ * {
  --secret_code: ;
}

In addition to the :valid and :placeholder-shown pseudo-classes, the selector is using the more common :not() pseudo-class along with a sibling selector and a universal selector. That’s quite a bit to digest in a single CSS selector, but here’s what it means in plain English:

  • Target all sibling elements
  • Of every element with a class name of .secret-code
  • That has no placeholder text showing
  • That’s valid

And once we grasp that selector, then we can move on to the main CSS trick used to toggle the secret message on and off.

The --var() Space-toggle Hack

The demo is using a trick referred to as the space-toggle hack (or var-toggle hack), which Lea Verou nicely explained a year ago and apparently was first used/discovered by Ana Tudor. This trick uses CSS custom properties (i.e. CSS Variables). In fact, Jane has used it in multiple projects including CSS Mine Sweeper and a library called Augmented UI.

This technique is a way to easily toggle a set of CSS property/value pairs on a single element using a single property value.

Take note of the inline styles present on the div element in the demo:

<div style="--wow: var(--secret_code) green; color: var(--wow, black);">

The odd thing here, and the thing that makes the space-toggle hack work, is the value for the --wow custom property. Before the selector criteria is met, the value of this custom property is invalid. This is because the --secret_code variable has no value set (yet). The value of green that appears after the invalid custom property will take effect once the space character is put in place (hence the name “space-toggle hack”).

This essentially means --wow: var(--secret_code) green; will compute to --wow: green; (because the space is just extra white space, which is fine inside a CSS value).

To make it more clear, in plain English the inline style reads like this:

  • Define the --wow variable with a non-existent custom property followed by a space and the color green
  • Set the color property to whatever the --wow variable is set to (currently invalid), with a fallback of black
  • Since --wow is currently invalid, use its fallback

This is why the color of the text starts out black when you first load the page.

The key to the toggle, then, is to add a space character as a value for --secret_code. This makes the initial definition of --wow valid, so the fallback color of black isn’t used. Once the space character is inserted, the logic is like this:

  • Define the --wow variable with a space character, followed by another space and the color green
  • Set the color property to whatever the --wow variable is set to (currently a valid space), with a fallback of black
  • Since --wow is currently valid, and doesn’t break the value of green, the color is computed to green

The same logic applies to the hidden span element that shows the secret message:

<span style="--wow: var(--secret_code) block; display: var(--wow, none);">

Again, the value of “block” won’t take effect until the selector criteria is met, thus making var(--secret_code) valid (and, by extension, --wow is valid).

One of the things that first tripped me up about the space-toggle hack is the value that follows the invalid variable. In this case it was green. To me this looked like a fallback value, so the logic didn’t make sense at first glance. But this isn’t a fallback value; it’s a value that gets toggled “on” when the variable next to it gets validated by the space character passed in from the selector’s variable definition.

And one final thing about the space-toggle hack: It’s really not recommended in a lot of cases and will cause problems with some CSS minifiers. A minifier is usually going to delete unwanted space characters like the one set as the value in this hack. I tested it on a few online minifiers and it does indeed cause problems for some, but not all. So be aware of that if you choose to use this technique.

Final Warning About Using accesskey

As mentioned, this trick uses the accesskey attribute, which seems like a useful feature to take advantage of. As the original Tweet by Šime mentions, WebAIM provides a warning when discussing this subject:

Despite good intentions and because of varied and insufficient browser implementations, accesskey very often does not provide a viable solution for keyboard shortcuts on the web.

They go on to offer a whole slew of reasons why using accesskey is problematic and conclude with:

Due to numerous problems with implementation, accesskey is typically best avoided. If used, they must be implemented carefully. The bottom line: some users will benefit and some will not, and some may even be disadvantaged.

While the accesskey part of this trick is the primary reason it works, I hope the rest of it (which is more likely to be used) was somewhat educational to those of you who weren’t as familiar with it all.