Modern CSS Techniques for Better UI

By Alex Developer 8 min read
css ui design web development

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

  1. Use Progressive Enhancement - Start with basic CSS, then add advanced features
  2. Test Browser Support - Use @supports for feature detection
  3. Optimize for Performance - Minimize layout thrashing and repaints
  4. Maintain Consistency - Use design tokens and custom properties
  5. 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!

Alex Developer

Content Creator