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. When two rules conflict, the cascade decides which one wins, and !important overrides it, which is why it should be a last resort. 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. For class names, a convention like BEM naming keeps large stylesheets predictable. To keep your stylesheets readable, label sections with comments. Typing effect with pure CSS Did you know that you can create a typing effect with zero JavaScript? Demo This is a typing demo. .typing-demo-wrapper { height: 200px; overflow: auto; /*This part is important for centering*/ display: grid; place-items: center; } .typing-demo { width: 22ch; animation: typing 2s steps(22), blink .5s step-end infinite alternate; white-space: nowrap; overflow: hidden; border-right: 3px solid; font-family: monospace; font-size: 2em; } @keyframes typing { from { width: 0 } } @keyframes blink { 50% { border-color: transparent } } This is a typing 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. Demo: box-shadow drop-shadow .drop-shadow-wrapper { height: 350px; display: flex; align-items: center; justify-content: center; } .mr-2 { margin-right: 2em; } .mb-1 { margin-bottom: 1em; } .text-center { text-align: center; } .box-shadow { box-shadow: 2px 4px 8px #585858; } .drop-shadow { filter: drop-shadow(2px 4px 8px #585858); } box-shadow Image with box-shadow drop-shadow Image with drop-shadow Smooth scroll with one line of CSS Smooth scrolling without JavaScript, with just one line of CSS. Demo: One Two Three Section one Section two Section three .cp-smooth { font-family: system-ui, sans-serif; } .cp-smooth__nav { display: flex; gap: 8px; margin-bottom: 12px; } .cp-smooth__nav a { padding: 6px 14px; border-radius: 8px; background: #1d4ed8; color: #fff; text-decoration: none; } .cp-smooth__scroller { height: 200px; overflow-y: auto; border-radius: 12px; /* The one line that does it */ scroll-behavior: smooth; } .cp-smooth__scroller section { display: grid; place-items: center; height: 200px; color: #fff; font-size: 24px; font-weight: 700; } #cp-smooth-1 { background: #1e3a8a; } #cp-smooth-2 { background: #0e7490; } #cp-smooth-3 { background: #6d28d9; } 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: Default Image Cursor Emoji Cursor .cursors-wrapper { display: flex; height: 350px; align-items: center; justify-content: center; background: #4776e6; background: -webkit-linear-gradient(to right, #4776e6, #8e54e9); background: linear-gradient(to right, #4776e6, #8e54e9); padding: 0 10px; } .tile { width: 200px; height: 200px;display: flex; align-items: center; justify-content: center; background-color: #de5448; margin-right: 10px;color: #fff; font-size: 1.4em; text-align: center; } .tile--image-cursor { background-color: #1da1f2; cursor: url(https://picsum.photos/20/20), auto; } .tile--emoji-cursor { background-color: #4267b2; cursor: url("data:image/svg+xml;utf8,🚀"), auto; } 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: This text is truncated, because there is not enough space to display it completely. .truncate-wrapper { display: flex; height: 250px; align-items: center; justify-content: center; background: #4776e6; background: -webkit-linear-gradient(to right, #4776e6, #8e54e9); background: linear-gradient(to right, #4776e6, #8e54e9); } .overflow-ellipsis { width: 200px; background-color: #fff; padding: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } This text is truncated, because there is not enough space to display it completely. 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. Full guide with demos: text-overflow: ellipsis and line-clamp. Demo: This text is trimmed to 3 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. This text is trimmed to 4 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. This text is not trimmed 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. .truncate-tile { background: linear-gradient(to right, #2B32B2, #1488CC); padding: 15px; margin-bottom: 15px; padding: 15px; width: 300px; color: #fff; } .line-clamp { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; /* Change this line if you want. In this case it trimmed the text to 3 lines. */ overflow: hidden; } .line-clamp--four { -webkit-line-clamp: 4; /* Trimmed the second tile to four lines. */ } This text is trimmed to 3 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. This text is trimmed to 4 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. This text is not trimmed 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. 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). It works like the better-known ::before and ::after, which add content without extra HTML. Demo: Select this text with your mouse to see the custom highlight colors. .cp-selection { padding: 24px; border-radius: 12px; background: #f1f5f9; color: #0f172a; font: 20px/1.5 system-ui, sans-serif; } .cp-selection::selection { background: #1d4ed8; color: #fff; } 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 ``? 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. A hidden checkbox does the same job for a CSS-only hamburger menu. Demo: Open modal Hello from a CSS modal No JavaScript: the :target pseudo-class shows it when the URL ends in #cp-modal. Close .cp-modal-demo { display: grid; place-items: center; padding: 32px; border-radius: 12px; background: #f1f5f9; font-family: system-ui, sans-serif; } .cp-modal-demo__open, .cp-modal__close { padding: 10px 18px; border-radius: 8px; background: #1d4ed8; color: #fff; text-decoration: none; } .cp-modal { position: fixed; inset: 0; z-index: 1000; display: none; place-items: center; padding: 16px; background: rgba(15, 23, 42, 0.6); font-family: system-ui, sans-serif; } /* Visible only while the URL hash matches its id */ .cp-modal:target { display: grid; } .cp-modal__box { max-width: 360px; padding: 24px; border-radius: 14px; background: #fff; color: #0f172a; } .cp-modal__box h4 { margin: 0 0 8px; } .cp-modal__box p { margin: 0 0 20px; } CSS 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). .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: Has text Has text .cp-empty { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; font-family: system-ui, sans-serif; } .cp-empty div { display: grid; place-items: center; height: 90px; border-radius: 12px; background: #dbeafe; color: #1e3a8a; } /* No children and no text, not even a space */ .cp-empty div:empty { background: repeating-linear-gradient(45deg, #fee2e2 0 10px, #fecaca 10px 20px); } 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. To hide the scrollbar but keep the box scrollable, set scrollbar-width: none. Demo: Scroll this box to see the custom scrollbar. Chrome, Edge and Firefox use the standard scrollbar-color and scrollbar-width properties. Safari uses the ::-webkit-scrollbar pseudo-elements, so both are included. Keep the thumb contrasting with the track, so the scrollbar stays easy to find. That's it. .cp-scrollbar { height: 160px; overflow-y: auto; padding: 0 20px; border-radius: 12px; background: #f1f5f9; color: #0f172a; font: 18px/1.6 system-ui, sans-serif; /* Standard: thumb color, then track color */ scrollbar-color: #1d4ed8 #dbeafe; scrollbar-width: thin; } /* Safari */ .cp-scrollbar::-webkit-scrollbar { width: 10px; } .cp-scrollbar::-webkit-scrollbar-track { background: #dbeafe; } .cp-scrollbar::-webkit-scrollbar-thumb { border-radius: 10px; background: #1d4ed8; } Scroll this box to see the custom scrollbar. Chrome, Edge and Firefox use the standard scrollbar-color and scrollbar-width properties. Safari uses the ::-webkit-scrollbar pseudo-elements, so both are included. Keep the thumb contrasting with the track, so the scrollbar stays easy to find. That's it. 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. .cp-sticky { height: 220px; overflow-y: auto; border-radius: 12px; background: #f1f5f9; color: #0f172a; font-family: system-ui, sans-serif; } .cp-sticky h4 { position: sticky; top: 0; margin: 0; padding: 12px 16px; background: #1d4ed8; color: #fff; } .cp-sticky p { margin: 0; padding: 16px 16px 120px; font-size: 17px; } 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: 1 2 3 4 5 .cp-snap { display: flex; gap: 12px; overflow-x: auto; padding-bottom: 8px; scroll-snap-type: x mandatory; } .cp-snap div { display: grid; place-items: center; flex: 0 0 75%; height: 160px; border-radius: 12px; background: linear-gradient(135deg, #1d4ed8, #0e7490); color: #fff; font: 700 40px system-ui, sans-serif; scroll-snap-align: center; } 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. Attribute selectors work the same way: a[target=”_blank”]::after can add an icon to links that open in a new tab. Demo: Hover over this or that. .cp-tooltips { padding: 56px 24px 24px; border-radius: 12px; background: #f1f5f9; color: #0f172a; font: 20px system-ui, sans-serif; text-align: center; } .cp-tooltips [data-tooltip] { position: relative; border-bottom: 2px dashed #1d4ed8; cursor: help; } .cp-tooltips [data-tooltip]::after { content: attr(data-tooltip); position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%); width: max-content; max-width: 220px; padding: 6px 10px; border-radius: 6px; background: #0f172a; color: #fff; font-size: 14px; opacity: 0; pointer-events: none; transition: opacity 0.2s; } .cp-tooltips [data-tooltip]:hover::after { opacity: 1; } Hover over this or that. caret-color: change the cursor color in inputs You can change the color of the text input cursor. Caret Color example codepen preview. :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:in-range { border-color: #16a34a; } input:out-of-range { border-color: #dc2626; } Input pseudo-classes `::in-range` and `out-of-range` 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 .cp-fancy { padding: 24px; border-radius: 12px; background: #0f172a; text-align: center; } .cp-fancy h4 { margin: 0; font: 900 clamp(36px, 8vw, 64px) system-ui, sans-serif; background: linear-gradient(90deg, #22d3ee, #6366f1, #a855f7); /* Paint the background only where the text is */ -webkit-background-clip: text; background-clip: text; color: transparent; } 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. Flex Gap Property Grayscale image with filter: grayscale() Use the grayscale() filter function to convert the input image to grayscale. grayscale-function 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. Both tricks work with radial gradients too. Demo: Rounded gradient border .cp-gradient-border { display: grid; place-items: center; height: 140px; border: 4px solid transparent; border-radius: 16px; /* Inner fill on the padding box, gradient on the border box */ background: linear-gradient(#fff, #fff) padding-box, linear-gradient(135deg, #22d3ee, #6366f1, #a855f7) border-box; color: #0f172a; font: 600 20px system-ui, sans-serif; } :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.
26 CSS Tips and Tricks for Modern Web Development
Full Article
Original Source
Read the full article at Hackernoon →KhanList aggregates and links to publicly available news content. We do not host full articles from third-party sources. Always verify important information with original sources.