Front-end development is quickly becoming more and more focused on efficiency – faster loading and rendering through selector choice and minimizing code. Pre-processors like Less and SCSS go a long way in doing some of the work for us, but there are plenty of ways to write minimal, quick CSS the native way. This guide covers 20 Pro CSS Tips to help you cut down on duplicate rules and overrides, standardize the flow of styling across your layouts and will help you create a personal starting framework that is not only efficient, but solves many common problems.
If you’re relatively new to CSS, check out The Power of CSS Selectors and How to Use Them for a thorough primer on many of the super-selectors featured here.
CSS reset libraries like normalize.css have been around for years, providing a clean slate for your site’s styles that help ensure better consistency across browsers. Most projects don’t really need all of the rules these libraries include, and can get by with one simple rule to remove all the margins and paddings applied to most elements in your layout by the browser’s default box-model:
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
Using the box-sizing
declaration is optional – if you follow the Inherit box-sizing tip below, you can skip it.
box-sizing
Let box-sizing
be inherited from html
:
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
This makes it easier to change box-sizing
when code is introduced through 3rd party plugins or applications that use different behavior.
How many times have you tried designing a grid, such as a portfolio or image gallery, where you used floats and then had to clear them or reset margins to get the columns to break into the number of rows you want? Get rid of nth-, first-, and last-child hacks by using the space-between
property value in flexbox:
.flex-container {
display: flex;
justify-content: space-between;
}
.flex-container .item {
flex-basis: 23%;
}
Now column gutters always appear evenly-spaced. Learn more about flexbox with Master CSS Flexbox in 5 Simple Steps
:not()
to Style Borders on ListsA very common practice in web design has been to use :last-child or :nth-child selectors to undo a style previously declared on the parent selector. Think of a navigation menu that uses borders to create a separator between each link, and the second rule added to take that border off the end:
.nav li {
border-right: 1px solid #666;
}
.nav li:last-child {
border-right: none;
}
This is quite messy as it not only forces the browser to render things one way, then undo it for a specific selector. Resetting styles this way is sometimes unavoidable, but for the most part, you can use the :not()
pseudo-class to only apply a style to the elements you want in one single statement:
.nav li:not(:last-child) {
border-right: 1px solid #666;
}
This says, put a border on all the .nav
list items except the last one. Simple!
Sure, you can also use .nav li + li
or even .nav li:first-child ~ li
, but :not()
will always be more semantic and easy to understand.
line-height
to body
The one thing that leads to inefficient stylesheets is repeating declarations over and over again. The better you get at planning your project and combining rules, the more fluid your CSS will be. One way to do this is understanding the cascade and how the styles you write for general selectors can be inherited elsewhere. Line height is one property you can set for your entire project, not only to minimize lines of code but to enforce a standard look to your site’s typography.
Rather than add line-height
to each <p>, <h*> and so on, add it to body
:
body {
line-height: 1.5;
}
Note we don’t declare a unit here – we just tell it to make the line height one and a half times more than the font size for the rendered text.
Setting a global rule to vertically center your layout is a great way to set a foundation for elegantly set content layouts where you’re not ready to use CSS Grid.
html, body {
height: 100%;
margin: 0;
}
body {
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
display: -webkit-flex;
display: flex;
}
We go into detail about all the ways you can vertically center things in CSS Vertical Centering Everything You Need To Know
SVG scales well for all resolution types and is supported in all browsers. So ditch your .png, .jpg, or .gif-jif-whatev files. Even FontAwesome now offers SVG Icon Fonts in FontAwesome 5. Setting SVG works just like any other image type:
.logo {
background: url("logo.svg");
}
Accessibility tip:If you use SVGs for interactable elements such as buttons, and the SVG fails to load, a rule like this one will help maintain accessibility (make sure it has the appropriate aria attributes set in the HTML):
.no-svg .icon-only:after {
content: attr(aria-label);
}
Using the universal selector (*
) with the adjacent sibling selector (+
) provides a powerful CSS capability that allows us to set rules for all elements in the flow of the document that specifically follow other elements:
* + * {
margin-top: 1.5rem;
}
This is another great trick that can help you create more uniform type and spacing. In the example above, all elements that follow other elements, like an H4 that follows an H3, or a paragraph following another paragraph, will each have at least 1.5rems of space (equal to about 30px.)
Consistent vertical rhythm provides a visual aesthetic that makes content far more readable. Where the owl selector may be too general, use a universal selector (*) within an element to create a consistent vertical rhythm for specific sections of your layout:
.intro > * {
margin-bottom: 1.25rem;
}
box-decoration-break
For Prettier Wrapped TextSay you want to apply uniform spacing, margins, highlights or background colors to long lines of text that wrap to more than one line, but don’t want the whole paragraph or heading to look like one large block. The box-decoration-break
property allows you to apply styles to just the text while keeping padding and margins intact. This is particularly useful if you want to apply highlights on hover, or style sub-text in a slider to have a highlighted look:
.p {
display: inline-block;
box-decoration-break: clone;
-o-box-decoration-break: clone;
-webkit-box-decoration-break: clone;
}
The inline-block
declaration allows the colors, backgrounds, margins and padding to be applied to each line of text rather than the entire element, and the clone
declaration makes sure those styles are applied consistently to each line equally.
Tables can be a pain to work with so try using table-layout: fixed
to keep cells at equal width:
.calendar {
table-layout: fixed;
}
This is especially useful for links that are inserted via a CMS, which don’t usually have a class attribute and helps you style them specifically without generically affecting the cascade. For example, the <a>
element has no text value but the href
attribute has a link:
a[href^="http"]:empty::before {
content: attr(href);
}
Speaking of link styling, you can find a generic a style in just about every stylesheet. This forces you to write additional overrides and style rules for any links in a child element, and when working with a CMS like WordPress can lead to problems with your king link style trumping a button text color, for example. Try this less-intrusive way to add a style for “default” links:
a[href]:not([class]) {
color: #999;
text-decoration: none;
transition: all ease-in-out .3s;
}
Now the style will only apply itself to links that otherwise have no other style rule.
To create a box with an intrinsic ratio, all you need to do is apply top or bottom padding to a div:
.container {
height: 0;
padding-bottom: 20%;
position: relative;
}
.container div {
border: 2px dashed #ddd;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
Using 20% for padding makes the height of the box equal to 20% of its width. No matter the width of the viewport, the child div will keep its aspect ratio (100% / 20% = 5:1).
This tip is less about code reduction and more about refining the detail of your designs. Broken images happen for a number of reasons, and are either unsightly or lead to confusion (just an empty element). Create more aesthetically-pleasing with this little bit of CSS:
img {
display: block;
font-family: Helvetica, Arial, sans-serif;
font-weight: 300;
height: auto;
line-height: 2;
position: relative;
text-align: center;
width: 100%;
}
img:before {
content: "We're sorry, the image below is missing :(";
display: block;
margin-bottom: 10px;
}
img:after {
content: "(url: " attr(src) ")";
display: block;
font-size: 12px;
}
rem
for Global Sizing; Use em
for Local SizingAfter setting the base font size at the root, for example html{font-size: 15px;}
, you can set font-size
for containing elements to rem
:
article {
font-size: 1.25rem;
}
aside {
font-size: .9rem;
}
Then set the font size for textual elements to em:
h2 { font-size: 2em; } p { font-size: 1em; }
Now each containing element becomes compartmentalized and easier to style, more maintainable, and flexible.
This is a great trick for a custom user stylesheet when working with content you can’t easily control from the source. This trick will help you avoid annoying your visitors with sound from an auto-playing video when the page is loaded, and again features the wonderful :not()
pseudo-selector:
video[autoplay]:not([muted]) {
display: none;
}
:root
for Flexible TypeThe font size in a responsive layout should be able to adjust to the viewport automatically, saving you the work of writing media-queries just to deal with font sizing. You can calculate the font size based on the viewport height and width using :root:
and viewport units:
:root {
font-size: calc(1vw + 1vh + .5vmin);
}
Now you can utilize the root em
unit based on the value calculated by :root:
body {
font: 1rem/1.6 sans-serif;
}
Combine this with the rem/em trick above for greater control. See CSS Fix for iOS vh-unit Bug for tips on managing older versions of Safari.
font-size
on Form Elements for a Better Mobile ExperienceTo avoid mobile browsers (iOS Safari, etc.) from zooming in on HTML form elements when a <select> drop-down is tapped, add font-size
to the input styles:
input[type="text"],
input[type="number"],
select,
textarea {
font-size: 16px;
}
Last but not least, the most powerful CSS level-up comes from CSS variables, which allow you to declare a set of common property values that can be reused via a keyword anywhere in the stylesheet. Your brand may have a set of colors to be used across the project to keep things consistent. Repeating these color values over and over again in your CSS is not only a chore, but also error prone. If a color needs to be changed at some point, your forced to find-and-replace, which is not reliable or fast, and when building products for end-users, variables make customization that much easier. For example:
:root {
--main-color: #06c;
--accent-color: #999;
}
h1, h2, h3 {
color: var(--main-color);
}
a[href]:not([class]),
p,
footer span{
color: var(--accent-color);
}
Learn more about CSS Variables on the MDN
Anh Tran
Love these tips and so many things to learn. They’re not old as in other articles! Thanks for sharing!
Ali
Wow! These tips ara simply amazing.. Thank you so much this great post..
DAVO
Thanks, this is a great list of CSS tips, i will definitely be using the :not(). Just wish all browsers support such useful selectors.
Asdf
Very Useful !!!!!!
Thanks…..
NAD
Help me!
I have the background web image ‘fixed’. It works on desktop but turns into ‘repeat’ on iOs. How do I solve it?
Thank you!
tony
body {
background-image: url(“paper.gif”);
background-repeat: repeat-y;
}
/* options: background-repeat: repeat|repeat-x|repeat-y|no-repeat|initial|inherit; */
ron
Using media queries. Google it.
boltgolt
If you want a fast rendering site, be warned that using the asterisk selector a lot (like suggested above) can severely impact performance.
Modern Web Design Perth
Will put some of these tips to use. Thanks
MNSTR
These will really give me an edge with further design briefs.
Thanks
LT
These are great tips! A few examples or even screen shots of useage would be super helpful, especially for anyone used to CSS needed to just get by vs. powerful CSS like this. A great article though, and really helpful for a newbie designer!
Creative Solutions
Thank you
Marko Selidba
Loved the tip about styling broken images. Would be great if you could write a post about CSS transitions. Thanks!
Davide L Rizzo
I have been designing large responsive websites for many years and shrinking your text proportionally with the screen size is almost always a bad idea.
:root {
font-size: calc(1vw + 1vh + .5vmin);
}
(Don’t do this)
If you have huge headings on a desktop site, sure use a media-query or fluid typography to scale down a bit. But 6pt equivalent font size on a mobile is relay hard to read. In most cases you want the body copy of text on your mobile to be the same or LARGER on a mobile so that it is easer to read.
Sixo
Great set of tips, tip #3, Flexbox has saved my life a couple of times but favorite had to have been about using rem and em units. Even today it still has confused the crap out of me.
Study Khazana
Thank you so much for this great tips.??
Al-Bantani
Thanks, it’s really helpful.
Peter
Seems good and useful tips. Thanks for sharing
Mark
Good read but I check out the Not: selector and it says is not well supported yet (13%)