5 CSS methodologies and libraries to help keep your visual components organized
5 CSS methodologies and libraries to help keep your visual components organized
Styling with CSS can be difficult to maintain as the app grows. With more visual assets to coordinate and keep track of, it's easy to lose selectors and create conflicting rules. Keeping organized can help reduce visual errors and ensure that your styles remain consistent.
CSS structural frameworks are ways to keep your code organized through a series of standardization methods. Here is a quick rundown of 5 different CSS frameworks and methodologies to help you keep track of your styles, their application, and prevent conflicts in the future.
#1. CSS BEM methodology
BEM stands for Block-Element-Modifier. It is a methodology that breaks down your visual elements into three parts - the block, the element, and the modifier.
A block is defined as a UI element that is self-contained. An element extends the block and is more specific in its application. A modifier is an overarching piece of CSS that has the ability to extend both an element and a block.
Here is an example of a block:
.btn {}
Here is an example of an element (extending .btn
):
.btn__price {}
Here is an example of a modifier on btn
:
.btn--orange {} .btn--big {}
Advantages of BEM
- You get scoping and relationships through the naming convention
- You get flexibility through the ability to extend visual features by stacking the selectors
- You still get specific applications of CSS for certain elements without impacting related classes
Disadvantages of BEM
- The selectors can pollute your HTML with large and long class names. Here is an example:
export const Card = () => { return ( <section className="card"> <img className="card__avatar" src="..." /> <div className="card__info"> <div className="card__info__title">...</div> <div className="card__info__description">...</div> </div> </section> ); };
#2. SCSS (Sassy CSS)
SCSS, or Sassy CSS, gives developers the ability to programmatically create CSS rules with nesting to variables to make it less linear in its application. What this means is that developers have the ability to use references and inheritance rules that are more scoped and more akin to programming than single-level CSS rules.
SCSS is a preprocessor, which means that you will also need to compile it separately and will not work on its own without it.
Here is an example of what SCSS looks like:
.card { .avatar {} .info { .title {} .description {} } }
Based on the example above, when compiled, the .avatar
class will also inherit CSS from the .card
class.
Advantages of SCSS
- Clean and readable
- Minifies better than BEM
Disadvantages of SCSS
- Introduces an extra build step
#3. JSS
JSS is a JavaScript CSS module for React that allows you to write all your CSS as JavaScript objects. Here is an example:
import { createUseStyles } from 'react-jss'; const useStyles = createUseStyles({ card: {}, avatar: {}, info: {}, title: {}, description: {}, }); export const Card = () => { const css = useStyles(); return ( <section className={css.card}> <img className={css.avatar} src="..." /> <div className={css.info}> <div className={css.title}>...</div> <div className={css.description}>...</div> </div> </section> ); };
Instead of an external CSS file, the styles are actually an object created by createUseStyles
function, and these styles live in the same file. This allows your related code to be collocated in one place. You simply use these styles as a hook in your card
component or you can destructure classes from it and directly use them.
export const Card = () => { const { card, avatar, info, title, description } = useStyles(); return ( <section className={card}> <img className={avatar} src="..." /> <div className={info}> <div className={title}>...</div> <div className={description}>...</div> </div> </section> ); };
Advantages of JSS
- All relevant styles co-located in one place
- Great for design systems
- SCSS like syntax
Disadvantages of JSS
- Less performant. CSS being populated by JS rather than put into an external stylesheet can make the overall experience slower.
#4. Goober
Goober is another CSS in JavaScript library for React that lets you create CSS objects for easier application for your app. Here is an example code snippet of Goober:
import { styled } from 'goober'; const Button = styled('button')` border: 0; background: dodgerblue; span {color: white;} &:hover { background: tomato; span {color: black;} } `;
Goober uses styled()
to set the styling and its associated class name. Here is an example of a CSS object applied to a component.
import { styled } from 'goober'; export const AppCard = () => { return ( <Card> <Avatar src="..." /> <Info> <Title>...</Title> <Description>...</Description> </Info> </Card> ); }; const Card = styled('section')` /* Card styles */ `; const Avatar = styled('img')` /* Avatar styles */ `; const Info = styled('div')` /* Info styles */ `; const Title = styled('div')` /* Title styles */ `; const Description = styled('div')` /* Description styles */ `;
Advantages of Goober
-
Lightweight to integrate as it is only a 1KB library.
-
Extract CSS into styled tags during build time for enhanced performance.
Disadvantages of Goober
- Integrates the CSS as part of the app's JavaScript. This means that CSS sheets cannot easily be reused across different apps that may use the same styling. This can increase coding overhead if there are multiple apps involved.
#5. Linaria
Similar to Goober, Linaria uses a similar styled-component
structure. However, unlike Goober, Linaria compiles a separate CSS stylesheet and doesn't include itself in the final bundle.
Here is an example code snippet of CSS with Linaria:
import { styled } from '@linaria/react'; export const AppCard = () => { return ( <Card> <Avatar src="..." /> <Info> <Title>...</Title> <Description>...</Description> </Info> </Card> ); }; const Card = styled.section` /* Card styles */ `; const Avatar = styled.img` /* Avatar styles */ `; const Info = styled.div` /* Info styles */ `; const Title = styled.div` /* Title styles */ `; const Description = styled.div` /* Description styles */ `;
Advantage of Linaria
- You can add your CSS inside your JavaScript files and have it extracted out into a separate stylesheet during the build process
- zero runtime CSS in JavaScript
Disadvantage of Linaria
- Linaria isn't fully compatible with all the build tools.
CSS can make or break the visual experience of a user. The ability to keep track and maintain CSS has always been a problem for big projects. As interfaces increases in complexity, so do the number of rules that require maintenance.
Keeping CSS organized and centralized is a work in progress for many projects. Hopefully one of the above libraries and CSS methodologies can help reduce the pain of stray classes and stylesheets.