Embrace the Elegance of CSS Components

  • components
  • css
  • javascript
  • web development
Apr 23, 2023
Discover why CSS stylesheets triumph over JavaScript UI frameworks for crafting primitive components.

The Allure of JavaScript Frameworks

JavaScript UI frameworks are the unsung heroes of modern web development. They streamline the process of building component-based applications, allowing developers to write less code and maintain consistency across projects. But as powerful as they are, it’s essential to recognize when traditional CSS stylesheets can outshine these frameworks, especially for primitive components.

The Case for Simplicity: When Less is More

Not every component needs the complexity of a JavaScript framework. Think about the humble button, label, or card—fundamental elements that behave predictably. By leveraging CSS for these components, you reduce dependencies, enhance performance, and maintain universal compatibility.

Building a Button: Framework vs. CSS

The Framework Approach

Using Svelte, you might create a versatile button component that adapts based on props:

<script lang="ts">
	let {
		variant = "primary",
		type = "submit",
		href = "",
		onclick = () => {},
	}: {
		variant?: "primary" | "secondary";
		type?: "submit" | "reset" | "button";
		href?: string;
		onclick?: () => {};
	} = $props();
</script>

{#if href}
	<a
		{href}
		class:primary={variant === "primary"}
		class:secondary={variant === "secondary"}
	>
		<slot />
	</a>
{:else}
	<button
		{type}
		onclick
		class:primary={variant === "primary"}
		class:secondary={variant === "secondary"}
	>
		<slot />
	</button>
{/if}

<style>
	a,
	button {
		border-radius: 5px;
	}
	.primary {
		background-color: blue;
	}
	.secondary {
		background-color: red;
	}
</style>

While this offers flexibility, it introduces complexity. Handling multiple elements (<a> vs. <button>) and maintaining consistent styles across them can become a maintenance headache.

The CSS-First Approach

Now, envision a scenario where you craft buttons purely with CSS:

.btn {
	border-radius: 5px;
}
.btn-primary {
	background-color: blue;
}
.btn-secondary {
	background-color: red;
}
<button class="btn btn-primary" type="button">Open Modal</button>
<a class="btn btn-secondary" href="#main">Skip to Content</a>

Advantages:

  • Framework Agnostic: Works seamlessly across different projects and frameworks.
  • Performance: Less JavaScript means faster load times.
  • Simplicity: Easier to maintain and understand.

Relying on JavaScript frameworks for every component can lead to bloated codebases and dependencies. Here’s why CSS can often be the superior choice:

  • Reduced Complexity: Fewer conditional elements and props.
  • Enhanced Compatibility: Native HTML elements work universally, even without JavaScript.
  • Maintainability: Stylesheets can be shared and managed across projects effortlessly.

Organizing with CSS Layers

Stay organized and future-proof your styles by utilizing CSS layers:

@layer base {
	html {
		scroll-behavior: smooth;
	}
}

@layer components {
	.btn {
		border-radius: 5px;
		background-color: blue;
	}
	.btn-secondary {
		background-color: red;
	}
}

@layer utilities {
	.flex {
		display: flex;
	}
}

Benefits:

  • Separation of Concerns: Distinguish between base styles, components, and utilities.
  • Scalability: Easily manage and scale styles as your project grows.
  • Clarity: Clear organization enhances readability and maintainability.

Conclusion: Less is Truly More

While JavaScript frameworks revolutionize front-end development, there’s a timeless elegance in leveraging CSS for primitive components. It’s about striking the right balance—using the right tool for the right job. By starting with CSS, you build a robust foundation that’s both flexible and efficient, ensuring your projects are sustainable and performant.

Ready to dive deeper? Explore TailwindCSS and learn how to craft stunning components with pure CSS.