CSS Tips and Tricks: 26 You Won’t See in Most Tutorials
Contents
- What is CSS?
- Typing effect with pure CSS
- drop-shadow() for transparent images
- Smooth scroll with one line of CSS
- Center a div horizontally and vertically
- Custom CSS cursor (image or emoji)
- text-overflow: ellipsis (truncate text)
- line-clamp: truncate text to multiple lines
- Change the text selection color with ::selection
- CSS resize: make any element resizable
- CSS modal without JavaScript (:target)
- CSS calc()
- Style empty elements with :empty
- Custom scrollbar CSS
- position: sticky (sticky headers)
- CSS scroll snap
- CSS tooltip with attr()
- caret-color: change the cursor color in inputs
- :in-range and :out-of-range
- Gradient text CSS (background-clip)
- Flex gap
- Grayscale image with filter: grayscale()
- Gradient border CSS (with rounded corners)
- :has() parent selector
- aspect-ratio
- accent-color for checkboxes and radios
- Fluid font size with clamp()
- FAQ
- More CSS
CSS tips and tricks you won’t see in most tutorials.
If you’re learning CSS, I’d suggest you check this Introduction to CSS first.
What is CSS?
Cascading Style Sheets (CSS) is a style sheet language used for describing the presentation of a document written in a markup language like HTML. CSS is the main technology of the World Wide Web, alongside HTML and JavaScript.
CSS is designed to enable the separation of presentation and content, including layout, colors, and fonts. This separation can improve content accessibility, provide more flexibility and control in the specification of presentation characteristics, enable multiple web pages to share formatting by specifying the relevant CSS in a separate .css file and reduce complexity and repetition in the structural content. To keep your stylesheets readable, label sections with comments. Here’s how comments in CSS work.
Typing effect with pure CSS
Did you know that you can create a typing effect with zero JavaScript?
Demo:
drop-shadow() for transparent images
When you work with transparent images you can use `drop-shadow()` filter function to create a shadow on the image’s content, instead of `box-shadow` property which creates a rectangular shadow behind an element’s entire box (build those with the CSS box shadow generator): filter:
drop-shadow(2px 4px 8px #585858);
Demo:
Smooth scroll with one line of CSS
Smooth scrolling without JavaScript, with just one line of CSS.
Demo:
Center a div horizontally and vertically
Easily center anything, horizontally and vertically, with 3 lines of CSS.
Explore other ways to center a div.
.center {
display: flex;
align-items: center;
justify-content: center;
}
Custom CSS cursor (image or emoji)
Did you know that you can use your own image, or even emoji as a cursor?
Demo:
text-overflow: ellipsis (truncate text)
Did you know that you can truncate text with plain CSS?
It takes three properties together: overflow: hidden, white-space: nowrap and text-overflow: ellipsis. The element also needs a limited width, either set directly or from a flex or grid parent.
Demo:
line-clamp: truncate text to multiple lines
You can use -webkit-line-clamp property to truncate the text to the specific number of lines. An ellipsis will be shown at the point where the text is clamped.
Use it together with display: -webkit-box, -webkit-box-orient: vertical and overflow: hidden. Despite the prefixes, this combination works in all modern browsers and is the standard way to show a two- or three-line preview with an ellipsis.
Demo:
-webkit-line-clamp property to truncate the text to the specific number of lines.
An ellipsis will be shown at the point where the text is clamped.
-webkit-line-clamp property to truncate the text to the specific number of lines.
An ellipsis will be shown at the point where the text is clamped.
-webkit-line-clamp property to truncate the text to the specific number of lines.
An ellipsis will be shown at the point where the text is clamped.
Change the text selection color with ::selection
The `::selection` CSS pseudo-element applies styles to the part of a document that has been highlighted by the user (such as clicking and dragging the mouse across text).
Demo:
Select this text with your mouse to see the custom highlight colors.
CSS resize: make any element resizable
Did you know that you can make any element resizable, just like `<textarea>`?
It only works when overflow is something other than visible, for example overflow: auto.
.resize {
resize: both;
}
CSS modal without JavaScript (:target)
You can use the `:target` pseudo-class to create modals with zero JavaScript.
Demo:
Hello from a CSS modal
No JavaScript: the :target pseudo-class shows it when the URL ends in #cp-modal.
CloseCSS calc()
The `calc()` CSS function lets you perform calculations when specifying CSS property values:
You can mix units in one expression: calc(100% - 2rem) gives a full-width element with side margins, and calc(100vh - 64px) fills the screen below a 64px header. Put spaces around + and -, or the expression is invalid. For fluid sizes with limits, combine it with clamp() (see the tip below).
Full guide: CSS calc() with examples.
.calculated-width: {
width: calc(100% - 30px);
}
Style empty elements with :empty
You can use the `:empty` selector to style an element that has no children or text at all:
Demo:
Custom scrollbar CSS
Use the standard scrollbar-color and scrollbar-width properties for Chrome, Edge and Firefox, and the ::-webkit-scrollbar pseudo-elements for Safari.
Demo:
position: sticky (sticky headers)
You can create sticky section headers with 2 lines of CSS. Not sure how sticky differs from absolute, relative and fixed? See position absolute vs relative.
A sticky element needs a threshold like top: 0, and it only sticks inside its parent. If it doesn’t stick, check the ancestors: overflow: hidden or overflow: auto on any parent creates a new scroll container and breaks it.
Demo:
Section 1
Scroll inside this box. Each header sticks to the top until the next section pushes it away.
Section 2
The sticky header stays within its own section, its containing block.
Section 3
Two lines of CSS: position: sticky and top: 0.
CSS scroll snap
You can use the CSS Scroll Snap feature to create well-controlled scroll experiences:
Demo:
CSS tooltip with attr()
Create dynamic CSS-only tooltips, using the attr() CSS function.
attr() reads any attribute of the element, so each tooltip’s text lives in the HTML and one CSS rule styles them all.
Demo:
Hover over this or that.
caret-color: change the cursor color in inputs
You can change the color of the text input cursor.
:in-range and :out-of-range
Use the :in-range and :out-of-range pseudo-classes to style number inputs whose value is inside or outside the min and max attributes.
/* <input type="number" min="1" max="10"> */
input:in-range {
border-color: #16a34a;
}
input:out-of-range {
border-color: #dc2626;
}
Gradient text CSS (background-clip)
Use the background-clip property to create beautiful headlines.
Design the gradient in the CSS gradient generator, or add an outline with CSS text stroke.
Demo:
Fancy headline
Flex gap
Use the gap CSS property to set the gaps (gutters) between rows and columns.
gap works in both flexbox and grid, and replaces the old margin hacks between items.
Grayscale image with filter: grayscale()
Use the grayscale() filter function to convert the input image to grayscale.
Gradient border CSS (with rounded corners)
The gradient sits on the border-box and a solid fill on the padding-box, so the corners stay rounded. Design the colors in the CSS gradient generator, or see the animated border snippet for a moving version.
Demo:
:has() parent selector
:has() selects an element based on what it contains, the parent selector CSS was missing for years. It works in all modern browsers.
/* A card that contains an image */
.card:has(img) {
padding: 0;
}
/* A label followed by an invalid input */
label:has(+ input:invalid) {
color: #dc2626;
}
aspect-ratio
Keep an element’s proportions without the old padding-top hack. Great for videos, thumbnails and avatars.
.video {
width: 100%;
aspect-ratio: 16 / 9;
}
.avatar {
width: 64px;
aspect-ratio: 1;
object-fit: cover;
}
accent-color for checkboxes and radios
Recolor native checkboxes, radio buttons, range sliders and progress bars with one line, no custom styling needed.
:root {
accent-color: #1d4ed8;
}
Fluid font size with clamp()
clamp(min, preferred, max) lets text grow with the screen but never get too small or too large. No media queries needed.
h1 {
/* 2rem on phones, up to 4rem on wide screens */
font-size: clamp(2rem, 1rem + 4vw, 4rem);
}
Happy coding!
Want to explore more? Here’s a tutorial on how to create CSS Pulse Animation.
FAQ
Do these CSS tips work in all browsers?
Yes. Every tip on this page works in current Chrome, Edge, Firefox and Safari. Where a property still needs a prefix, like -webkit-line-clamp, the prefixed version is supported everywhere.
Can I use these tricks without JavaScript?
Yes. The typing effect, smooth scrolling, modals, tooltips, sticky headers and scroll snap on this page are all pure CSS.
What is the most useful CSS trick for beginners?
Centering with display: grid; place-items: center, and truncating text with text-overflow: ellipsis. Both solve problems you hit on almost every project.
More CSS
Free CSS generators: box shadow, text shadow, gradients, border radius and glassmorphism. Guides: position absolute vs relative, CSS text stroke, comments in CSS, CSS line height and the HTML tips companion post.