Modern CSS Techniques for Better UI
Modern CSS Techniques for Better UI
CSS has evolved tremendously in recent years, introducing powerful features that make creating beautiful, responsive user interfaces easier than ever. Let’s explore some modern techniques that every web developer should know.
1. CSS Grid for Complex Layouts
CSS Grid revolutionized how we approach layout design. Unlike Flexbox, which is one-dimensional, Grid allows for two-dimensional layouts:
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}
.featured {
grid-column: span 2;
grid-row: span 2;
}
This creates a responsive gallery where items automatically wrap and the featured item spans multiple columns and rows.
Grid Template Areas
For more complex layouts, use named grid areas:
.layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar main aside"
"footer footer footer";
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
2. Custom Properties (CSS Variables)
CSS custom properties enable dynamic theming and consistent design systems:
:root {
--primary-color: #3b82f6;
--secondary-color: #64748b;
--spacing-unit: 1rem;
--border-radius: 0.5rem;
--font-size-base: 1rem;
--font-size-lg: 1.125rem;
--font-size-xl: 1.25rem;
}
.button {
background-color: var(--primary-color);
padding: calc(var(--spacing-unit) * 0.5) var(--spacing-unit);
border-radius: var(--border-radius);
font-size: var(--font-size-base);
}
/* Dark mode */
[data-theme="dark"] {
--primary-color: #60a5fa;
--secondary-color: #94a3b8;
}
Dynamic Color Calculations
:root {
--hue: 210;
--saturation: 50%;
--lightness: 50%;
--primary: hsl(var(--hue), var(--saturation), var(--lightness));
--primary-light: hsl(var(--hue), var(--saturation), calc(var(--lightness) + 20%));
--primary-dark: hsl(var(--hue), var(--saturation), calc(var(--lightness) - 20%));
}
3. Container Queries
Container queries allow components to respond to their container’s size rather than the viewport:
.card-container {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 400px) {
.card {
display: flex;
align-items: center;
}
.card-image {
width: 150px;
margin-right: 1rem;
}
}
@container card (min-width: 600px) {
.card {
padding: 2rem;
}
.card-title {
font-size: 1.5rem;
}
}
4. Modern Selectors
The :has() Selector (Parent Selector)
The :has() selector allows you to style parent elements based on their children:
/* Style cards that contain an image */
.card:has(img) {
border: 2px solid var(--primary-color);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
/* Style form when it has invalid inputs */
.form:has(input:invalid) {
border-color: #ef4444;
}
/* Style article with featured class inside */
.article-list:has(.article.featured) {
padding-top: 2rem;
}
:is() and :where() for Cleaner Code
/* Instead of repeating selectors */
:is(h1, h2, h3, h4, h5, h6) {
font-family: var(--heading-font);
line-height: 1.2;
margin-bottom: 0.5em;
}
/* :where() has zero specificity */
:where(button, .button) {
padding: 0.5rem 1rem;
border-radius: var(--border-radius);
border: none;
cursor: pointer;
}
5. Logical Properties
Logical properties adapt to different writing modes and text directions:
.sidebar {
/* Instead of margin-left */
margin-inline-start: 2rem;
/* Instead of padding-top and padding-bottom */
padding-block: 1rem;
/* Instead of border-right */
border-inline-end: 1px solid #ccc;
}
.card {
/* Instead of margin: 1rem 0 */
margin-block: 1rem;
/* Instead of padding: 0 1rem */
padding-inline: 1rem;
}
6. Advanced Animations
Scroll-Driven Animations
@keyframes fade-in {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.animate-on-scroll {
animation: fade-in linear;
animation-timeline: view();
animation-range: entry 0% entry 100%;
}
View Transitions API
::view-transition-old(main),
::view-transition-new(main) {
animation-duration: 0.3s;
}
::view-transition-old(main) {
animation-name: slide-out;
}
::view-transition-new(main) {
animation-name: slide-in;
}
@keyframes slide-out {
to {
transform: translateX(-100%);
}
}
@keyframes slide-in {
from {
transform: translateX(100%);
}
}
7. Improved Typography
Fluid Typography
h1 {
font-size: clamp(2rem, 5vw, 4rem);
}
p {
font-size: clamp(1rem, 2.5vw, 1.125rem);
line-height: clamp(1.4, 1.5vw, 1.6);
}
Advanced Text Effects
.gradient-text {
background: linear-gradient(45deg, #3b82f6, #8b5cf6, #ec4899);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
background-size: 300% 300%;
animation: gradient-shift 3s ease infinite;
}
@keyframes gradient-shift {
0%, 100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
}
8. Scroll Snap for Better UX
.carousel {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
gap: 1rem;
}
.carousel-item {
scroll-snap-align: start;
flex: 0 0 auto;
width: 300px;
scroll-snap-stop: always;
}
/* Smooth scrolling with custom easing */
.smooth-scroll {
scroll-behavior: smooth;
scroll-timeline: scroll();
}
9. Performance Optimizations
content-visibility
.large-section {
content-visibility: auto;
contain-intrinsic-size: 1000px;
}
will-change
.animated-element {
will-change: transform;
}
/* Remove after animation completes */
.animated-element.animation-complete {
will-change: auto;
}
Contain Property
.component {
contain: layout style paint;
}
Best Practices
- Use Progressive Enhancement - Start with basic CSS, then add advanced features
- Test Browser Support - Use
@supportsfor feature detection - Optimize for Performance - Minimize layout thrashing and repaints
- Maintain Consistency - Use design tokens and custom properties
- Consider Accessibility - Ensure your designs work for all users
/* Feature detection */
@supports (container-type: inline-size) {
.responsive-component {
container-type: inline-size;
}
}
/* Respect user preferences */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
/* High contrast support */
@media (prefers-contrast: high) {
.button {
border: 2px solid;
}
}
Conclusion
Modern CSS provides powerful tools for creating beautiful, responsive, and performant user interfaces. By leveraging these techniques, you can build better web experiences while writing more maintainable code.
Key takeaways:
- Grid and Flexbox work together for powerful layouts
- Custom properties enable dynamic, themeable designs
- Container queries provide true component-based responsive design
- Modern selectors reduce CSS complexity
- Performance should always be considered
The key is to use these features progressively and always consider browser support and user experience. Happy styling!