Use CSS or SCSS instead of Emotion?

Hi there, how would one approach using a framework like Semantic UI or even Bootstrap or similar with Frontity?

Thanks,
Kris

Hi @kris! :wave:

I think you can use either Semantic UI or Bootstrap without any problem. Since Frontity uses React, you should use the React version of those libraries:

Then, instead of import CSS files directly (we don’t allow CSS files in frontity) you have to import them as strings and use Global and css from Frontity as shown below. It’s needed to be done this way because we do a lot of CSS optimization.

For example, for Semantic UI:

import { Global, css } from 'frontity';
import { Button } from 'semantic-ui-react';
// Import Semantic UI CSS as string
import semanticUIStyles from 'semantic-ui-css/semantic.min.css';

const SemanticUIStyles = () => (
  <Global styles={css(semanticUIStyles)} />
);

const MyTheme = () => (
  <div>
    <SemanticUIStyles />
    <Button />
  </div>
);

Let me know if you need help or something.
Cheers!

2 Likes

I can understand not allowing css because y’all want to optimize stuff but this also presents difficulties for people who might want to use scss. Is there no ability to use sow thing like scss with frontity?

Hey Aslan, I understand your concern. What is your use case? Do you want to use SCSS because you’re already familiar with it or because you have a SCSS based theme you want to port to Frontity?


On the other hand, I’ve added a section in our docs to explain why we use CSS-in-JS and why it is important for Frontity:
https://docs.frontity.org/learning-frontity/styles#from-sass-to-css-in-js

I’ve also added some resources to learn about how to how to migrate from SASS/SCSS to CSS-in-JS.

2 Likes

I have the same thought as Aslan… WP has made his point being flexible. This css part has been very weird for me ( I’m coming from WP and Angular ).

At my case, I want to use SCSS because I’m already familiar with it and I have an SCSS based theme.

1 Like

First, I absolutely understand your concern. Thanks for sharing it. Please don’t take my answer as something personal. It’s not.

There are a couple of problems with SCSS:

  1. We cannot delete non-used CSS automatically. This may not seem important, but when you work with AMP the styles cannot be bigger than 50kbytes. With CSS-in-JS we can only add the styles used in your AMP page. With SCSS, we’d have to add all the styles of the whole theme to any single page.
  2. Frontity has a powerful package system. That means your are probably going to use a lot of code (that also includes CSS) but you haven’t coded yourself. That includes:
    • Packages: We haven’t had time to release packages yet, but our old framework had a lot and we will release them eventually. Things like wp-comments, disqus-comments, share-modal, adsense-ads, doubleclick-ads, post-carrousels, newsletter-modal
    • Processors: Our Html2React is also a key piece of Frontity and processors include a good deal of CSS. We had a lot of them in the old framework and we’ll release them as well: blockquotes, galleries, lazy-images, lazy-iframes, tables, embeds (youtube, twitter, instagram)…
    • Blocks: Support for complex Gutenberg blocks with Html2React: add React components for specific Gutenberg blocks. Much of those will include CSS.
    • WP Plugins: Support for WP plugins with Html2React. For example, ContactForm7, WP Review… They expose HTML and their processors will contain CSS.

So, in Frontity there will be lots of code coming from different places using CSS. If we don’t agree on a CSS solution, each package/processor/block/plugin developer will choose its own. Optimizing for “any type of CSS” is way more difficult than optimizing for a single one. Also, the bundle size may increase if those devs choose different CSS-in-JS libraries (there are a ton).

Besides that, SCSS doesn’t offer any additional feature that our CSS-in-JS (emotion) doesn’t have. So the only benefits are legacy SCSS code bases/themes and previous knowledge.

Sometimes these legacy codebases can mean a lot, we understand that. It’s simply that we cannot support or recommend SCSS at a framework level for the mentioned reasons.

Regarding WP flexibility, it comes at a price. For example, https://ma.tt/ loads 10 different CSS files. Frontity is designed for the webpack era of web, where all the assets are carefully bundled to increase performance and user experience, not developer flexibility. That doesn’t mean we cannot have an amazing developer experience (we do), but the focus is on the performance.

Last but not least: we wont’ be able to forbid anyone to use SCSS in Frontity once we release the ability to modify webpack via the frontity.config.js file (and we will soon). But people doing so will have to understand that the rest of Frontity is going to be on CSS-in-JS.

I hope this better clarifies the matter.


I did a quick research and it looks like there a couple of tools to migrate SASS to CSS-in-JS: https://docs.frontity.org/learning-frontity/styles#migrating-from-sass-to-css-in-js

If any of you want to go ahead with Frontity and try to migrate your SASS to CSS-in-JS I’d love to know about your experience so we can better understand and document that process.

If any of you still want to go ahead with Frontity but want to use SASS, please tell us as well. Even tho our current recommendation is not to use anything but the built-in CSS-in-JS solution, I’d love to know more about the real consequences of using SCSS.

4 Likes

I got your point. Thanks for this thoughtful response

2 Likes

Hey Luis I just now saw your reply here, sorry.

I’m still new to React but are you saying that allowing SCSS means that you can’t code-split so that only CSS used on that page is loaded? My understanding is that webpack handles code-splitting by default with create-react-app. Or is there some additional level of optimization that I’m missing?

My main desire to use scss is just so that I can have access to things like nesting. I realize that stuff is available through css in js but the mark up for it is not very intuitive in my opinion.

Also honestly I just prefer to have my css in a separate file because it means my editor can properly apply syntax highlighting and linting to it. Maybe it’s possible to make vscode lint and syntax highlight in css in js but I don’t know how it’s done off the top of my head and I haven’t found an extension that does it yet. Even if I did find an extension for that it’s another extension that frankly I don’t want to keep up with. It’s just nice to keep stuff clearly separated in other files yah know? I break my stuff out into as tiny components as possible. Typically my scss files are rarely more than 25 lines of code. I like making things extremely bite sized and reusable.

1 Like

create-react-app only does client side rendering, it doesn’t do server side rendering. That’s much simpler, but it’s also very bad for SEO.

Their code-splitting is based on react-lazy. Our code-splitting is based on loadable-component. Here’s a comparison between the two: https://www.smooth-code.com/open-source/loadable-components/docs/loadable-vs-react-lazy/

So far, there’s no possible way to do what we are doing (code-splitting + SSR + optimized-CSS) without a CSS-in-JS library: https://github.com/smooth-code/loadable-components/issues/94

But given the interest, I’m going to take pay special attention to this issue and check if that situation changes in the future.

Could you please provide an example?

We use this one, it works great: https://github.com/styled-components/vscode-styled-components

CSS-in-JS doesn’t prevent you from using as many files as you want and as small files as you want.

Instead of doing this:

.class-1 {
  color: blue;
}

.class-2 {
  color: red;
}
import styles from "./my-css.css";

const MyComponent = () => (
  <>
    <div className={styles.class-1}>Class 1!</div>
    <div className={styles.class-2}>Class 2!</div>
  </>
);

Do this:

export const Class1 = styled.div`
  color: blue;
`

export const Class2 = styled.div`
  color: red;
`
import { Class1, Class2 } from "./my-css";

const MyComponent = () => (
  <>
    <Class1>Class 1!</Class1>
    <Class2>Class 2!</Class2>
  </>
);

Please, bear in mind that our intention is not to reduce or limit the ways developers can use Frontity. We’d love to support CSS or SCSS. It’s just that, at this moment, and with the technology we have available, it is not an option we can support or recommend. I really hope that changes in the future and we can safely support both CSS-in-JS and CSS or SCSS files.

By the way, if you don’t want to use styled you can use the css prop. It’s probably more similar to what you are used to do in CSS:

export const class1 = css`
  color: blue;
`

export const class2 = css`
  color: red;
`
import * as styles from "./my-css";

const MyComponent = () => (
  <>
    <div css={styles.class1}>Class 1!</div>
    <div css={styles.class2}>Class 2!</div>
  </>
);

Thank you for the response Luis. This conversation is helping me become a better developer and understand the React ecosystem a lot better :slight_smile:

A really common use case for me is:

.button {
background-color: red;

    &:hover {
        background-color: blue;
    }
}

And I often use some simple mixins to handle responsive styles for mobile, or I can create mixins which can be used to apply complex sets of styles with variation.

Yeah, it’s not easy right? :sweat_smile:

Nesting in CSS-in-JS is based on SCSS, so the exact same syntax works perfectly:

const Button = styled.button`
  background-color: red;

  &:hover {
    background-color: blue;
  }
`

CSS-in-JS doesn’t have mixins because the very same pattern can be accomplished with regular JavaScript functions. It’s one of the benefits of staying in JavaScript: you can add any logic you want using JavaScript, and you don’t need to learn how to do it, because you already know JavaScript.

These series of videos explain how the different patterns of SCSS can be accomplished in CSS-in-JS. This one explain mixins:
https://egghead.io/lessons/scss-use-javascript-functions-as-mixin-directives-for-css-in-js-style-declarations#targetText=Mixins%20are%20reusable%20pieces%20of,passed%20in%20into%20valid%20CSS.