A collection of tips to help take your CSS skills pro.
- Use
:not()
to Apply/Unapply Borders on Navigation - Add Line-Height to
body
- Vertically-Center Anything
- Comma-Separated Lists
- Select Items Using Negative
nth-child
- Use SVG for Icons
- Text Display Optimization
- Use
max-height
for Pure CSS Sliders - Inherit
box-sizing
- Equal Width Table Cells
- Get Rid of Margin Hacks With Flexbox
- Use Attribute Selectors with Empty Links
Instead of putting on the border...
/* add border */
.nav li {
border-right: 1px solid #666;
}
...and then taking it off the last element...
/* remove border */
.nav li:last-child {
border-right: none;
}
...use the :not()
pseudo-class to only apply to the elements you want:
.nav li:not(:last-child) {
border-right: 1px solid #666;
}
Sure, you can use .nav li + li
or even .nav li:first-child ~ li
, but with :not()
the intent is very clear and the CSS selector defines the border the way a human would describe it.
You don't need to add line-height
to each <p>
, <h*>
, et al. separately. Instead, add it to body
:
body {
line-height: 1;
}
This way textual elements can inherit from body
easily.
No, it's not black magic, you really can center elements vertically:
html, body {
height: 100%;
margin: 0;
}
body {
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
display: -webkit-flex;
display: flex;
}
Want to center something else? Vertically, horizontally...anything, anytime, anywhere? CSS-Tricks has a nice write-up on doing all of that.
Note: Watch for some buggy behavior with flexbox in IE11.
Make list items look like a real, comma-separated list:
ul > li:not(:last-child)::after {
content: ",";
}
Use the :not()
pseudo-class so no comma is added to the last item.
Use negative nth-child
in CSS to select items 1 through n.
li {
display: none;
}
/* select items 1 through 3 and display them */
li:nth-child(-n+3) {
display: block;
}
Or, since you've already learned a little about using :not()
, try:
/* select items 1 through 3 and display them */
li:not(:nth-child(-n+3)) {
display: none;
}
Well that was pretty easy.
There's no reason not to use SVG for icons:
.logo {
background: url("logo.svg");
}
SVG scales well for all resolution types and is supported in all browsers back to IE9. So ditch your .png, .jpg, or .gif-jif-whatev files.
Note: If you have SVG icon-only buttons for sighted users and the SVG fails to load, this will help maintain accessibility:
.no-svg .icon-only:after {
content: attr(aria-label);
}
Sometimes fonts don't display optimally on all devices, so let the device browser help:
html {
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
Note: Please play with optimizeLegibility
responsibly. Also, there's no text-rendering
support for IE/Edge.
Implement CSS-only sliders using max-height
with overflow hidden:
.slider ul {
max-height: 0;
overlow: hidden;
}
.slider:hover ul {
max-height: 1000px;
transition: .3s ease; /* animate to max-height */
}
Let box-sizing
be inheritted from html
:
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
This makes it easier to change box-sizing
in plugins or other components that leverage other behavior.
Tables can be a pain to work with so try using table-layout: fixed
to keep cells at equal width:
.calendar {
table-layout: fixed;
}
Pain-free table layouts.
When working with column gutters you can get rid of nth-
, first-
, and last-child
hacks by using flexbox's space-between
property:
.list {
display: flex;
justify-content: space-between;
}
.list .person {
flex-basis: 23%;
}
Now column gutters always appear evenly-spaced.
Display links when the <a>
element has no text value but the href
attribute has a link:
a[href^="http"]:empty::before {
content: attr(href);
}
That's pretty convenient.
These protips work in current versions of Chrome, Firefox, Safari, and Edge, and in IE11.