19

I am working in react with typescript and tailwindcss.

What I want is that instead of using @apply directive in main tailwind.css file (the file which conatins @tailwind base, @tailwind components, etc), I want to use it in any .scss file.

For example, in react whenever I create a component, I create a folder and an inside it I create a index.tsx file and a .scss file. I want to use @apply directive in that .scss file. In this way, it will be easy to work and debug because both the associated files will be inside the same folder. How can I achieve that ??

I have shown my basic folder structure below.

Folder structure:

src > components > Header > Header.tsx

import React from "react";
import styles from "./Header.module.scss";

interface Props {}

const Header: React.FC<Props> = (props) => {
  return <div className={styles.headerTag}>Header part here</div>;
};

export default Header;

src > components > Header > Header.module.scss

// what to import so that I can use tailwind like this

.headerTag {
  @apply text-8xl font-bold bg-gray-500;
}

Ashutosh
  • 209
  • 3
  • 9
  • 1
    Might be worth having a look into [using TailwindCSS with preprocessors](https://tailwindcss.com/docs/using-with-preprocessors#using-sass-less-or-stylus). – juliomalves Jan 02 '21 at 10:52
  • 3
    @juliomalves I already did. But there's nothing that would help me in writing the way I mentioned above. I already spent 5-6 days to get this to work but couln't. Now I am thinking about switching to tachyons-css because tachyons-css can be used in the way I mentioned above. – Ashutosh Jan 02 '21 at 17:38
  • 1
    I am facing the same issue now and breaking my head for a solution. – curious_coder Mar 24 '21 at 05:39
  • as an aside, I dropped using scss in favor of modern CSS and Tailwind – Keith Nicholas Jul 16 '21 at 01:21

3 Answers3

3

Created a repo with working solution.
If your project is based on create-react-app follow steps below to achieve that.

Add tailwind to your project

Add tailwind to your project following this guide from documentation. Note: they use craco to modify CRA webpack's configuration, but I'm sure you can do the same with react-app-rewired.

Steps:

  • npm install -D tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9
  • npm install @craco/craco
  • Make these changes in your package.json
  • create a file called craco.config.js
// craco.config.js
module.exports = {
  style: {
    postcss: {
      plugins: [
        require('tailwindcss'),
        require('autoprefixer'),
      ],
    },
  },
}
  • npx tailwindcss-cli@latest init
  • make these changes in tailwind.config.js changes in
  • include tailwind in your index.scss
@tailwind base;
@tailwind components;
@tailwind utilities;

Add scss modules support

Add scss modules support by installing npm i node-sass@5.0.0. You can try other versions but higher versions didn't work for me.

That's it

If it still doesn't work for you for some reason see repo for versions/configuration difference to get an idea what to change to handle it.

If you are using custom webpack build (or your project is not CRA based) more steps may be needed to work with taildwind and scss-modules.

Why postcss@7?

https://tailwindcss.com/docs/installation#post-css-7-compatibility-build

As of v2.0, Tailwind CSS depends on PostCSS 8. Because PostCSS 8 is only a few months old, many other tools in the ecosystem haven’t updated yet, which means you might see an error like this in your terminal after installing Tailwind and trying to compile your CSS:

Error: PostCSS plugin tailwindcss requires PostCSS 8.

Create React App doesn’t support PostCSS 8 yet so you need to install the Tailwind CSS v2.0 PostCSS 7 compatibility build for now as we’ve shown above.

nickbullock
  • 6,424
  • 9
  • 27
  • Is there a reason why `@tailwindcss/postcss7-compat` specifically was used? Is that because CRA is forced to use v7? Consider updating the post with important configuration pieces, the solution should preferably understandable without navigating to external links that can become unavailable. – Estus Flask Jul 15 '21 at 15:48
2

Seems like to achieve what you looking for you need to use a postcss-import plugin and configure main tailwind file slightly differently. I've made a very quick repo to demonstrate setup:

Repo link

Official docs on the matter

Basically, instead of just having this "typical" tailwind css file:

@tailwind base;
@tailwind components;
@tailwind utilities;

You need to add a dev dependency on postcss-import package. Then update postcss.config.js to actually use it:

module.exports = {
  plugins: {
    "postcss-import": {},
    tailwindcss: {},
    autoprefixer: {},
  },
}

And change main css file for tailwind to use imports instead:

@import "tailwindcss/base";
@import "tailwindcss/components";
@import "./components/Header/Header.module.css";
@import "tailwindcss/utilities";

This way you can start creating separate css files/modules and use them like you wanted to.

Here is Header.modules.css:

.headerTag {
    @apply bg-green-500 text-8xl;
}

I am not sure I personally prefer this way, because I guess the gist of tailwind is specifically not using bunch of css component classes, so instead I definitely prefer to just create React components with almost "inline" styling:

import React from "react";

interface Props {
    className: string;
}

const Header: React.FC<Props> = (props) => {
  return <div className={`bg-green-500 text-8xl ${props.className}`}>Header part here</div>;
};

export default Header;

This way I can override default styling at the place of usage.

fxdxpz
  • 1,969
  • 17
  • 29
0

So, an alternative way to do this, would be something like this:

styles/apply.js

const btn = 'py-2 px-4 font-semibold rounded-lg shadow-md';
const btnGreen = 'text-white bg-green-500 hover:bg-green-700';

export { btn, btnGreen };

pages/index.tsx

import type { NextPage } from 'next';

import { btn, btnGreen } from 'Styles/apply';

const Home: NextPage = () => {
  return (
    <div>
      <button className={`${btn} ${btnGreen}`}>
        Button
      </button>
    </div>
  );
}
Daltron
  • 1,729
  • 3
  • 20
  • 37