Custom CSS Selectors
With cssnext it is possible to use a maybe future standard feature of CSS called "Custom CSS Selector".
Using custom CSS selectors, repeated selectors can be aliased to a shorter pseudo-selector.
Example:
/* Define custom selector, note that they must be prefixed with :-- */
@custom-selector :--headings h1, h2, h3, h4, h5, h6;
/* Use custom selector */
:--headings {
color: blue;
}
The custom selectors basically transform into :matches() selectors, most
modern browser support some kind of :matches()
(:-moz-any() and :-webkit-any()
).
:--heading
would be equivalent to the :matches(h1, h2, h3, h4, h5, h6)
pseudo-selector.
But cssnext compiles them into simple selectors, supported by all browsers.
Styling checkboxes using custom CSS selectors
As a more complicated example, I'm going to show you how one might implement custom checkboxes or radios.
Implement custom checkboxes and radios for browsers which support :checked
can be much more readable with custom selectors.
/*
Select radio and checkbox as :--checkbox, select both types as we will
customize both but style the radio a bit different later.
*/
@custom-selector :--checkbox input[type=checkbox], input[type=radio];
/* Only select radios which are customizable */
@custom-selector :--customizableRadio input[type=radio]:not(:checked), input[type=radio]:checked;
/* Checkboxes and radios are only customizable if `:checked` is supported */
@custom-selector :--customizable input[type=checkbox]:not(:checked), input[type=checkbox]:checked,
input[type=radio]:not(:checked), input[type=radio]:checked;
/*
Hide the radios and checkboxes by moving them out of the viewport,
some browsers behave weird if they are set to `display: none`
*/
:--customizable {
position: absolute;
left: -99999px;
}
:--customizable + label {
position: relative;
padding-left: 1.5em;
cursor: pointer;
}
:--customizable + label::before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 16px;
height: 16px;
border: 1px solid rgb(200, 200, 200);
background-color: rgb(255, 255, 255);
border-radius: 4px;
transition: border-color 0.15s, box-shadow 0.15s;
}
/* Make radios round */
:--customizableRadio + label::before {
border-radius: 50%;
top: -2px;
left: 6px;
}
:--customizable + label::after {
content: '\2713';
position: absolute;
top: -1px;
left: 4px;
font-size: 16px;
font-weight: 700;
line-height: 1.4;
color: green;
transition: opacity 0.2s;
}
/* Use bullets for radios instead of the check mark */
:--customizableRadio + label::after {
content: '\2022';
}
:--checkbox:not(:checked) + label::after {
opacity: 0;
}
:--checkbox:checked + label::after {
opacity: 1;
}
:--customizable:disabled + label::before {
border-color: #bbb;
background-color: #ddd;
}
:--checkbox:disabled:checked + label::after {
color: #999;
}
:--checkbox:disabled + label {
color: #aaa;
}
:--customizable:focus + label::before {
border-color: color(green tint(20%));
outline: 0;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 8px color(green a(60%));
}
:--customizable + label:hover::before {
border-color: green;
}
Which can now be used with the following HTML markup:
<div>
<input id="checkbox1" type="checkbox">
<label for="checkbox1">Checkme</label>
</div>
<div>
<input id="radio1" type="radio" name="radio" checked>
<label for="radio1">Checkme</label>
<input id="radio2" type="radio" name="radio">
<label for="radio2">Checkme</label>
</div>
Checkout the generated CSS file to see the difference to the CSS above.
Happy styling :)