Skip to content

Should I use application.css at all with Tailwind? #180

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
pil0u opened this issue Jun 29, 2022 · 3 comments
Closed

Should I use application.css at all with Tailwind? #180

pil0u opened this issue Jun 29, 2022 · 3 comments

Comments

@pil0u
Copy link

pil0u commented Jun 29, 2022

Hi,

I am wrapping my head around CSS with Rails 7, importmaps and Tailwind, especially in terms of code structure.

When running a rails new with Tailwind, the structure looks like:

app
 |__ assets
   |__ builds
   |__ config
   |__ stylesheets
     |__ application.css
     |__ application.tailwind.css

When I look at the downloaded files upon initial page load in the browser, there are 2 stylesheets:

  • application.debug-xxxxx.css
  • tailwind.debug-yyyyy.css

The tailwind file contains a minified version of Tailwind's used classes and styles, that's fair. But the application contains a duplicate of the code written in application.tailwind.css, not minified. I suppose this is due to these lines:

/*
 * ...
 * 
 *= require_tree .
 *= require_self
 */

Why would I need the application.css in the first place if I let Tailwind do the heavy lifting for classes selection and minification?

Suppose I want to self-host fonts. Usually I would create a app/assets/stylesheets/fonts.css file along with a app/assets/fonts folder, which would be appended to the compiled application.debug-xxxxx.css file.
I could also add the CSS-related code (with my @font-face properties) directly in the application.tailwind.css file:

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

@layer base {
  @font-face {
    font-family: 'Source Code Pro';
    font-style: normal;
    font-weight: 300;
    src: local('Source Code Pro'), url('source-code-pro-300.woff2') format('woff2');
  }
}

Would that be desirable to get rid of the application.css file? I might be missing something obvious but I don't understand why I need my users to download part of the CSS twice.

@walterdavis
Copy link

walterdavis commented Jun 29, 2022 via email

@dhh
Copy link
Member

dhh commented Jun 29, 2022

What @walterdavis said. In the future, please direct usage questions to https://discuss.hotwired.dev ✌️

@dhh dhh closed this as completed Jun 29, 2022
@markquezada
Copy link

I realize this is an old issue but I found it because I was wondering the exact same thing.

Regarding the above comment:

Even if you use Tailwind, you are going to run into situations where you do need to craft some specific CSS for your layout and components. I'm thinking here of branding, or anything custom that is used more than twice that you don't want to build out of tiny atomic CSS classes

I'm not sure if the sentiment of the maintainers of tailwindcss-rails has changed but the above is antithetical to tailwind's philosophy on reusing styles:

Tailwind encourages a utility-first workflow, where designs are implemented using only low-level utility classes.

On the above linked page on reusing styles, they specifically call out not relying on CSS classes to extract complex components and instead, mention these alternatives:

  • editor language and features
    • multi-cursor editing
    • loops/maps
  • extracting components and partials
  • extracting classes with @apply

On that last point, they offer this guidance:

While it’s highly recommended that you create proper template partials for more complex components, you can use Tailwind’s @apply directive to extract repeated utility patterns to custom CSS classes when a template partial feels heavy-handed.

Here's an example of how you'd use @apply in application.tailwind.css:

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

@layer components {
  .btn-primary {
    @apply py-2 px-4 bg-blue-500 text-white font-semibold rounded-lg shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-400 focus:ring-opacity-75;
  }
}

Example usage:

<!-- Before extracting a custom class -->
<button class="py-2 px-4 bg-blue-500 text-white font-semibold rounded-lg shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-400 focus:ring-opacity-75">
  Save changes
</button>

<!-- After extracting a custom class -->
<button class="btn-primary">
  Save changes
</button>

Using tailwind's @layer directive over putting custom styles directly in application.css offers these additional benefits:

The @layer directive helps you control declaration order by automatically relocating your styles to the corresponding @tailwind directive, and also enables features like modifiers and tree-shaking for your own custom CSS.

It also means you can use @apply to compose styles from tailwind utilities, which you can't do in application.css.

You can read the docs on @layer for more info.

As mentioned in the above linked docs on @layer, If you really need custom rules, you can add them to the end of the application.tailwind.css file:

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

.my-custom-style {
  /* ... */
}

You can also use @layer to add custom utility classes:

@layer utilities {
  .column-fill-auto {
    column-fill: auto;
  }
}

... or even change default styles:

@layer base {
  h1, h2, h3 { @apply font-bold text-gray-700 font-heading; }

  h1 { @apply text-3xl; }

  h2 { @apply text-2xl; }

  h3 { @apply text-xl; }
}

For the above reasons, if your project is greenfield or otherwise all-in on tailwind, I believe application.tailwind.css should be essentially treated as your "index" for css and I don't see why application.css is useful at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants