Wondering what’s even more challenging than choosing a JavaScript framework? You guessed it: choosing a CSS-in-JS solution. Why? Because there are more than 50 libraries out there, each of them offering a unique set of features.
We tested 10 different libraries, which are listed here in no particular order: Styled JSX, styled-components, Emotion, Treat, TypeStyle, Fela, Stitches, JSS, Goober, and Compiled. We found that, although each library provides a diverse set of features, many of those features are actually commonly shared between most other libraries.
So instead of reviewing each library individually, we’ll analyse the features that stand out the most. This will help us to better understand which one fits best for a specific use case.
Note: We assume that if you’re here, you’re already familiar with CSS-in-JS. If you’re looking for a more elementary post, you can check out “An Introduction to CSS-in-JS.”
Common CSS-in-JS features
Most actively maintained libraries that tackle CSS-in-JS support all the following features, so we can consider them de-facto.
Scoped CSS
All CSS-in-JS libraries generate unique CSS class names, a technique pioneered by CSS modules. All styles are scoped to their respective component, providing encapsulation without affecting any styling defined outside the component.
With this feature built-in, we never have to worry about CSS class name collisions, specificity wars, or wasted time spent coming up with unique class names across theentire codebase.
This feature is invaluable for component-based development.
SSR (Server-Side Rendering)
When considering Single Page Apps (SPAs) — where the HTTP server only delivers an initial empty HTML page and all rendering is performed in the browser — Server-Side Rendering (SSR) might not be very useful. However, any website or application that needs to be parsed and indexed by search engines must have SSR pages and styles need to be generated on the server as well.
The same principle applies to Static Site Generators (SSG), where pages along with any CSS code are pre-generated as static HTML files at build time.
The good news is that all libraries we’ve tested support SSR, making them eligible for basically any type of project.
Automatic vendor prefixes
Because of the complex CSS standardization process, it might take years for any new CSS feature to become available in all popular browsers. One approach aimed at providing early access to experimental features is to ship non-standard CSS syntax under a vendor prefix:
/* WebKit browsers: Chrome, Safari, most iOS browsers, etc */ -webkit-transition: all 1s ease; /* Firefox */ -moz-transition: all 1s ease; /* Internet Explorer and Microsoft Edge */ -ms-transition: all 1s ease; /* old pre-WebKit versions of Opera */ -o-transition: all 1s ease; /* standard */ transition: all 1s ease;
However, it turns out that vendor prefixes are problematic and the CSS Working Group intends to stop using them in the future. If we want to fully support older browsers that don’t implement the standard specification, we’ll need to know which features require a vendor prefix.
Fortunately, there are tools that allow us to use the standard syntax in our source code, generating the required vendor prefixed CSS properties automatically. All CSS-in-JS libraries also provide this feature out-of-the-box.
No inline styles
There are some CSS-in-JS libraries, like Radium or Glamor, that output all style definitions as inline styles. This technique has a huge limitation, because it’s impossible to define pseudo classes, pseudo-elements, or media queries using inline styles. So, these libraries had to hack these features by adding DOM event listeners and triggering style updates from JavaScript, essentially reinventing native CSS features like :hover, :focus and many more.
It’s also generally accepted that inline styles are less performant than class names. It’s usually a discouraged practice to use them as a primary approach for styling components.
All current CSS-in-JS libraries have stepped away from using inline styles, adopting CSS class names to apply style definitions.
Full CSS support
A consequence of using CSS classes instead of inline styles is that there’s no limitation regarding what CSS properties we can and can’t use. During our analysis we were specifically interested in:
- pseudo classes and elements;
- media queries;
- keyframe animations.
All the libraries we’ve analyzed offer full support for all CSS properties.
Differentiating features
This is where it gets even more interesting. Almost every library offers a unique set of features that can highly influence our decision when choosing the appropriate solution for a particular project. Some libraries pioneered a specific feature, while others chose to borrow or even improve certain features.
React-specific or framework-agnostic?
It’s not a secret that CSS-in-JS is more prevalent within the React ecosystem. That’s why some libraries are specifically built for React: Styled JSX, styled-components, and Stitches.
However, there are plenty of libraries that are framework-agnostic, making them applicable to any project: Emotion, Treat, TypeStyle, Fela, JSS or Goober.
If we need to support vanilla JavaScript code or frameworks other than React, the decision is simple: we should choose a framework-agnostic library. But when dealing with a React application, we have a much wider range of options which ultimately makes the decision more difficult. So let’s explore other criteria.
Styles/Component co-location
The ability to define styles along with their components is a very convenient feature, removing the need to switch back-and-forth between two different files: the .css or .less/.scss file containing the styles and the component file containing the markup and behavior.
React Native StyleSheets, Vue.js SFCs, or Angular Components support co-location of styles by default, which proves to be a real benefit during both the development and the maintenance phases. We always have the option to extract the styles into a separate file, in case we feel that they’re obscuring the rest of the code.
Almost all CSS-in-JS libraries support co-location of styles. The only exception we encountered was Treat, which requires us to define the styles in a separate .treat.ts file, similarly to how CSS Modules work.
Styles definition syntax
There are two different methods we can use to define our styles. Some libraries support only one method, while others are quite flexible and support both of them.
Tagged Templates syntax
The Tagged Templates syntax allows us to define styles as a string of plain CSS code inside a standard ES Template Literal:
// consider "css" being the API of a generic CSS-in-JS library const heading = css` font-size: 2em; color: ${myTheme.color}; `;
We can see that:
- CSS properties are written in kebab case just like regular CSS;
- JavaScript values can be interpolated;
- we can easily migrate existing CSS code without rewriting it.
Some things to keep in mind:
- In order to get syntax highlight and code suggestions, an additional editor plugin is required; but this plugin is usually available for popular editors like VSCode, WebStorm, and others.
- Since the final code must be eventually executed in JavaScript, the style definitions need to be parsed and converted to JavaScript code. This can be done either at runtime, or at build time, incurring a small overhead in bundle size, or computation.
Object Styles syntax
The Object Styles syntax allows us to define styles as regular JavaScript Objects:
// consider "css" being the API of a generic CSS-in-JS library const heading = css({ fontSize: "2em", color: myTheme.color, });
We can see that:
- CSS properties are written in camelCase and string values must be wrapped in quotes;
- JavaScript values can be referenced as expected;
- it doesn’t feel like writing CSS, as instead we define styles using a slightly different syntax but with the same property names and values available in CSS (don’t feel intimidated by this, you’ll get used to it in no time);
- migrating existing CSS would require a rewrite in this new syntax.
Some things to keep in mind:
- Syntax highlighting comes out-of-the-box, because we’re actually writing JavaScript code.
- To get code completion, the library must ship CSS types definitions, most of them extending the popular CSSType package.
- Since the styles are already written in JavaScript, there’s no additional parsing or conversion required.
Styles applying method
Now that we know what options are available for style definition, let’s have a look at how to apply them to our components and elements.
Using a class attribute / className prop
The easiest and most intuitive way to apply the styles is to simply attach them as classnames. Libraries that support this approach provide an API that returns a string which will output the generated unique classnames:
// consider "css" being the API of a generic CSS-in-JS library const heading_style = css({ color: "blue" });
Next, we can take the heading_style, which contains a string of generated CSS class names, and apply it to our HTML element:
// Vanilla DOM usage const heading = `<h1 id="Title">Title</h1>`; // React-specific JSX usage function Heading() { return <h1 id="Title">Title</h1>; }
As we can see, this method pretty much resembles the traditional styling: first we define the styles, then we attach the styles where we need them. The learning curve is low for anyone who has written CSS before.
Using a component
Another popular method, that was first introduced by the styled-components library (and named after it), takes a different approach.
// consider "styled" being the API for a generic CSS-in-JS library const Heading = styled("h1")({ color: "blue" });
Instead of defining the styles separately and attaching them to existing components or HTML elements, we use a special API by specifying what type of element we want to create and the styles we want to attach to it.
The API will return a new component, having classname(s) already applied, that we can render like any other component in our application. This basically removes the mapping between the component and its styles.
Using the css prop
A newer method, popularised by Emotion, allows us to pass the styles to a special prop, usually named css. This API is available only for JSX-based syntax.
// React-specific JSX syntax function Heading() { return <h1 id="Title">Title</h1>; }
This approach has a certain ergonomic benefit, because we don’t have to import and use any special API from the library itself. We can simply pass the styles to this css prop, similarly to how we would use inline styles.
Note that this custom css prop is not a standard HTML attribute, and needs to be enabled and supported via a separate Babel plugin provided by the library.
Styles output
There are two mutually exclusive methods to generate and ship styles to the browser. Both methods have benefits and downsides, so let’s analyze them in detail.
Most CSS-in-JS libraries inject styles into the DOM at runtime, using either one or more
There are a few key advantages and preferred use cases for this approach:
- Inlining the styles during SSR provides an increase in page loading performance metrics such as FCP (First Contentful Paint), because rendering is not blocked by fetching a separate .css file from the server.
- It provides out-of-the-box critical CSS extraction during SSR by inlining only the styles required to render the initial HTML page. It also removes any dynamic styles, thus further improving loading time by downloading less code.
- Dynamic styling is usually easier to implement, as this approach appears to be more suited for highly interactive user interfaces and Single-Page Applications (SPA), where most components are client-side rendered.
The drawbacks are generally related to the total bundle size:
- an additional runtime library is required for handling dynamic styling in the browser;
- the inlined SSR styles won’t be cached out-of-the-box and they will need to be shipped to the browser upon each request since they’re part of the .html file rendered by the server;
- the SSR styles that are inlined in the .html page will be sent to the browser again as JavaScript resources during the rehydration process.
Static .css file extraction
There’s a very small number of libraries that take a totally different approach. Instead of injecting the styles in the DOM, they generate static .css files. From a loading performance point of view, we get the same advantages and drawbacks that come with writing plain CSS files.
- The total amount of shipped code is much smaller, since there is no need for additional runtime code or rehydration overhead.
- Static .css files benefit from out-of-the-box caching inside the browser, so subsequent requests to the same page won’t fetch the styles again.
- This approach seems to be more appealing when dealing with SSR pages or Static Generated pages since they benefit from default caching mechanisms.
However, there are some important drawbacks we need to take note of:
- The first visit to a page, with an empty cache, will usually have a longer FCP when using this method compared to the one mentioned previously; so deciding if we want to optimize for first-time users or returning visitors could play a crucial role when choosing this approach.
- All dynamic styles that can be used on the page will be included in the pre-generated bundle, potentially leading to larger .css resources that need to be loaded up front.
Almost all the libraries that we tested implement the first method, injecting the styles into the DOM. The only tested library which supports static .css file extraction is Treat. There are other libraries that support this feature, like Astroturf, Linaria, and style9, which were not included in our final analysis.
Atomic CSS
Some libraries took optimizations one step further, implementing a technique called atomic CSS-in-JS, inspired by frameworks such as Tachyons or Tailwind.
Instead of generating CSS classes containing all the properties that were defined for a specific element, they generate a unique CSS class for each unique CSS property/value combination.
/* classic, non-atomic CSS class */ ._wqdGktJ { color: blue; display: block; padding: 1em 2em; } /* atomic CSS classes */ ._ktJqdG { color: blue; } ._garIHZ { display: block; } /* short-hand properties are usually expanded */ ._kZbibd { padding-right: 2em; } ._jcgYzk { padding-left: 2em; } ._ekAjen { padding-bottom: 1em; } ._ibmHGN { padding-top: 1em; }
This enables a high degree of reusability because each of these individual CSS classes can be reused anywhere in the code base.
In theory, this works really great in the case of large applications. Why? Because there’s a finite number of unique CSS properties that are needed for an entire application. Thus, the scaling factor is not linear, but rather logarithmic, resulting in less CSS output compared to non-atomic CSS.
But there is a catch: individual class names must be applied to each element that requires them, resulting in slightly larger HTML files:
<!-- with classic, non-atomic CSS classes --> <h1 id="">...</h1> <!-- with atomic CSS classes --> <h1 id="">...</h1>
So basically, we’re moving code from CSS to HTML. The resulting difference in size depends on too many aspects for us to draw a definite conclusion, but generally speaking, it should decrease the total amount of bytes shipped to the browser.
Conclusion
CSS-in-JS will dramatically change the way we author CSS, providing many benefits and improving our overall development experience.
However, choosing which library to adopt is not straightforward and all choices come with many technical compromises. In order to identify the library that is best suited for our needs, we have to understand the project requirements and its use cases:
- Are we using React or not? React applications have a wider range of options, while non-React solutions have to use a framework agnostic library.
- Are we dealing with a highly interactive application, with client-side rendering? In this case, we probably aren’t very concerned about the overhead of rehydration, or care that much about extracting static .css files.
- Are we building a dynamic website with SSR pages? Then, extracting static .css files may probably be a better option, as it would allow us to benefit from caching.
- Do we need to migrate existing CSS code? Using a library that supports Tagged Templates would make the migration easier and faster.
- Do we want to optimize for first-time users or returning visitors? Static .css files offer the best experience for returning visitors by caching the resources, but the first visit requires an additional HTTP request that blocks page rendering.
- Do we update our styles frequently? All cached .css files are worthless if we frequently update our styles, thus invalidating any cache.
- Do we re-use a lot of styles and components? Atomic CSS shines if we reuse a lot of CSS properties in our codebase.
Answering the above questions will help us decide what features to look for when choosing a CSS-in-JS solution, allowing us to make more educated decisions.
위 내용은 CSS-in-JS의 철저한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

이것은 우리가 양식 접근성에 대해 한 작은 시리즈의 세 번째 게시물입니다. 두 번째 게시물을 놓친 경우 "사용자 초점 관리 : Focus-Visible"을 확인하십시오. ~ 안에

이 튜토리얼은 Smart Forms 프레임 워크를 사용하여 전문적인 JavaScript 양식을 작성하는 것을 보여줍니다 (참고 : 더 이상 사용할 수 없음). 프레임 워크 자체를 사용할 수 없지만 원칙과 기술은 다른 형태의 건축업자와 관련이 있습니다.

CSS Box-Shadow 및 개요 속성은 주제를 얻었습니다. 실제 테마에서 어떻게 작동하는지에 대한 몇 가지 예와 이러한 스타일을 WordPress 블록 및 요소에 적용 해야하는 옵션을 보자.

Svelte Transition API는 맞춤형 전환을 포함하여 문서를 입력하거나 떠날 때 구성 요소를 애니메이션하는 방법을 제공합니다.

이 기사에서 우리는 스크롤 바의 세계로 뛰어들 것입니다. 너무 화려하게 들리지는 않지만 잘 설계된 페이지가 손을 잡고 있습니다.

웹 사이트의 컨텐츠 프레젠테이션을 설계하는 데 얼마나 많은 시간을 소비합니까? 새 블로그 게시물을 작성하거나 새 페이지를 만들 때

NPM 명령은 서버 시작 또는 컴파일 코드와 같은 것들에 대한 일회성 또는 지속적으로 실행되는 프로세스로 다양한 작업을 실행합니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

PhpStorm 맥 버전
최신(2018.2.1) 전문 PHP 통합 개발 도구

DVWA
DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

SecList
SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

안전한 시험 브라우저
안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.
