Pure CSS#
Traditional CSS with external stylesheets. The most straightforward styling approach for Jac applications.
Overview#
Pure CSS is the foundation of web styling. You write CSS in a separate file and import it into your Jac code. This approach is perfect for: - Simple projects - Learning CSS fundamentals - Maximum control over styling - Minimal dependencies
Example#
See the complete working example: examples/css-styling/pure-css/
Quick Start#
1. Create CSS File#
Create a styles.css file in your project:
.container {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.card {
background: white;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
padding: 40px;
min-width: 400px;
text-align: center;
}
.title {
font-size: 2rem;
color: #667eea;
margin: 0 0 10px 0;
font-weight: 600;
}
2. Import CSS in Jac#
In your Jac file, import the CSS file:
# Pages
cl import from react {useState, useEffect}
cl import ".styles.css";
cl {
def app() -> any {
let [count, setCount] = useState(0);
return <div className="container">
<div className="card">
<h1 className="title">Counter Application</h1>
<p>Count: {count}</p>
</div>
</div>;
}
}
3. Use Class Names#
Apply CSS classes using the className prop:
return <div className="container">
<div className="card">
<h1 className="title">Counter Application</h1>
</div>
</div>;
4. Dynamic Classes#
Dynamically construct class names based on state:
let countClass = "countDisplay " + ("positive" if count > 0 else "negative" if count < 0 else "zero");
return <div className={countClass}>{count}</div>;
Import Syntax#
CSS files are imported using the cl import syntax:
This compiles to:
Vite automatically processes CSS imports and extracts them to a separate CSS file during the build process.
Best Practices#
1. Organize Your CSS#
Use comments to separate sections:
/* ============================================
Container Styles
============================================ */
.container {
/* styles */
}
/* ============================================
Card Styles
============================================ */
.card {
/* styles */
}
2. Use Semantic Class Names#
Make class names descriptive and meaningful:
/* Good */
.button-primary { }
.card-header { }
.navigation-menu { }
/* Avoid */
.btn1 { }
.div1 { }
.red { }
3. Use CSS Variables for Theming#
Leverage CSS custom properties for theming:
:root {
--primary-color: #007bff;
--secondary-color: #6c757d;
--spacing-unit: 1rem;
}
.button {
background-color: var(--primary-color);
padding: var(--spacing-unit);
}
4. Mobile-First Design#
Design for mobile, then enhance for desktop:
/* Mobile first */
.container {
padding: 1rem;
}
/* Desktop */
@media (min-width: 768px) {
.container {
padding: 2rem;
}
}
5. Avoid Inline Styles#
Keep styles in the CSS file for maintainability:
Advantages#
- No build step required for CSS
- Easy to understand and maintain
- Works with any CSS framework
- Minimal dependencies
- Great browser support
- Familiar syntax for developers
Limitations#
- No variables or nesting (use CSS variables for theming)
- No preprocessing features
- Global scope (use BEM or similar for scoping)
- No dynamic styling based on props
- Manual organization required
When to Use#
Choose Pure CSS when:
- You're building a simple application
- You want minimal dependencies
- You prefer traditional CSS workflow
- You're learning CSS fundamentals
- You need maximum control
- You want to avoid build complexity
CSS Variables (Custom Properties)#
Use CSS custom properties for theming and dynamic values:
:root {
--primary: #007bff;
--secondary: #6c757d;
--success: #28a745;
--danger: #dc3545;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 2rem;
}
.button {
background-color: var(--primary);
padding: var(--spacing-md);
}
.button-success {
background-color: var(--success);
}
Responsive Design#
Use media queries for responsive layouts:
.container {
padding: 1rem;
}
@media (min-width: 768px) {
.container {
padding: 2rem;
}
}
@media (min-width: 1024px) {
.container {
padding: 3rem;
}
}
Naming Conventions#
BEM (Block Element Modifier)#
Utility Classes#
Next Steps#
- Learn about CSS Variables for advanced theming
- Explore Sass/SCSS for preprocessing features
- Check out Tailwind CSS for utility-first approach
- See CSS Modules for scoped styles (coming soon)
Resources#
- MDN CSS Documentation
- CSS Tricks
- Can I Use - Browser compatibility