admin管理员组

文章数量:1296918

Context: I'm building some libraries to help me build a portal with microfrontends. I have a ui library (with ui components), a commons library (uses ui, has shared components for all microfrontends), a renderer library (uses ui, is used for rendering strapi data). All of them uses tailwind css.

Problem: When I use a component from the commons library that accepts children, the breakpoints from the component used as child are not working. If I use the same component outside the commons component, the breakpoints work. For example:

<CommonsComponent>
  <ComponentWithBreakpoint /> // breakpoints do not work
</CommonsComponent>
<ComponentWithBreakpoint /> // breakpoints work

Looking at the dev tools, I can see the class with the breakpoint not being applied (lg:flex-row from layout.css):

The flex-col class is also coming from a different file (page.css)

The components are:

const CommonsComponent = ({children}: {children: React.ReactNode}) => {
return (<div className="flex flex-col gap-4 w-full lg:w-[70%]">
  {children}
</div>)
} //from the commons library
const ComponentWithBreakpoint = () => {
return (
<div className="flex flex-col md:flex-row md:justify-between md:items-center gap-2 w-full">
  //content
</div>
)} // from one of the microfrontends

Context: I'm building some libraries to help me build a portal with microfrontends. I have a ui library (with ui components), a commons library (uses ui, has shared components for all microfrontends), a renderer library (uses ui, is used for rendering strapi data). All of them uses tailwind css.

Problem: When I use a component from the commons library that accepts children, the breakpoints from the component used as child are not working. If I use the same component outside the commons component, the breakpoints work. For example:

<CommonsComponent>
  <ComponentWithBreakpoint /> // breakpoints do not work
</CommonsComponent>
<ComponentWithBreakpoint /> // breakpoints work

Looking at the dev tools, I can see the class with the breakpoint not being applied (lg:flex-row from layout.css):

The flex-col class is also coming from a different file (page.css)

The components are:

const CommonsComponent = ({children}: {children: React.ReactNode}) => {
return (<div className="flex flex-col gap-4 w-full lg:w-[70%]">
  {children}
</div>)
} //from the commons library
const ComponentWithBreakpoint = () => {
return (
<div className="flex flex-col md:flex-row md:justify-between md:items-center gap-2 w-full">
  //content
</div>
)} // from one of the microfrontends
Share edited Feb 11 at 17:38 leosole asked Feb 11 at 17:08 leosoleleosole 3534 silver badges14 bronze badges 4
  • 1 Would need the elements and their formatting within the components to reproduce the example, even without React. For example, I don't immediately understand why some classes have the ui- TailwindCSS v3 prefix while others don't. Are you using TailwindCSS v3? – rozsazoltan Commented Feb 11 at 17:22
  • 1 I added some components for clarification. I'm using TailwindCSS v3. The ui library uses th ui- prefix – leosole Commented Feb 11 at 17:29
  • Ah, UI library. You need to understand CSS specificity better. When it comes to equal-level styles, the one that is declared last will take precedence. So, if I say a div is .flex-col and then .lg:flex-row, but .flex-col is defined later in the CSS, no matter what you do, .flex-col will always be stronger. TailwindCSS handles this on its own, as it smartly inserts your classes into the native CSS in the correct order. However, with classes prefixed by ui-, it can't do anything if they're not generated by it. I suggest using native TailwindCSS classes for basic functions like these. – rozsazoltan Commented Feb 11 at 17:32
  • Your example doesn't include the lg:flex-row. For now, the issue you described is not reproducible for me, but the only thing I can think of is that you’re trying to override a natively embedded flex-col. – rozsazoltan Commented Feb 11 at 17:33
Add a comment  | 

1 Answer 1

Reset to default 1

It works in native TailwindCSS because TailwindCSS adds the classes to the result in the correct order.

<script src="https://cdn.tailwindcss"></script>

* Working<br>
Click the "Full page" button for the lg view
<div class="flex flex-col lg:flex-row">
  <div>1.</div>
  <div>2.</div>
</div>

<div class="flex lg:flex-row flex-col">
  <div>1.</div>
  <div>2.</div>
</div>

Now I'll show you what happens if I accidentally create a stronger rule.

<script src="https://cdn.tailwindcss"></script>

<style>
.flex-col {
  flex-direction: column;
}
</style>

* Not Working<br>
Click the "Full page" button for the lg view
<div class="flex flex-col lg:flex-row">
  <div>1.</div>
  <div>2.</div>
</div>

<div class="flex lg:flex-row flex-col">
  <div>1.</div>
  <div>2.</div>
</div>

So the issue you described occurs because somewhere in your code, a .flex-col is hardcoded (but fixed after the classes generated by TailwindCSS). Therefore, no matter how TailwindCSS adds the .lg:flex-row, it will be overridden by the .flex-col that comes after it.

I'll show you what happens without TailwindCSS when a regular flex-col comes after lg:flex-row.

<style>
/* Generated by TailwindCSS */
.flex {
  display: flex;
}
.flex-col {
  flex-direction: column;
}
@media (min-width: 1024px) { 
  .lg\:flex-row {
    flex-direction: row;
  }
}
/* Added by you or your UI libary or etc. */
.flex-col {
  flex-direction: column;
}
</style>

* Not Working<br>
Click the "Full page" button for the lg view
<div class="flex flex-col lg:flex-row">
  <div>1.</div>
  <div>2.</div>
</div>

<div class="flex lg:flex-row flex-col">
  <div>1.</div>
  <div>2.</div>
</div>

And what happens if the classes are declared in the correct order:

<style>
/* Generated by TailwindCSS */
.flex {
  display: flex;
}
.flex-col {
  flex-direction: column;
}
@media (min-width: 1024px) { 
  .lg\:flex-row {
    flex-direction: row;
  }
}
/* Added by you or your UI libary or etc. */
.flex-col {
  flex-direction: column;
}
@media (min-width: 1024px) { 
  .lg\:flex-row {
    flex-direction: row;
  }
}
</style>

* Working<br>
Click the "Full page" button for the lg view
<div class="flex flex-col lg:flex-row">
  <div>1.</div>
  <div>2.</div>
</div>

<div class="flex lg:flex-row flex-col">
  <div>1.</div>
  <div>2.</div>
</div>

Conclusion: The order in which classes are added matters. By default, TailwindCSS adds its generated classes perfectly, but as you can see from my examples, either your own CSS or the UI library can re-declare the .flex-col, making it stronger than the lg:flex-row previously declared by TailwindCSS.

Your task now is to check where and why you're re-declaring the flex-col. If it's not possible to avoid re-declaring it, then add this CSS to the component:

.flex-col {
  flex-direction: column;
}
@media (min-width: 1024px) {
  .lg\:flex-row {
    flex-direction: row;
  }
}

or with Tailwind CSS v3 syntax:

.flex-col {
  flex-direction: column;
}
@screen lg {
  .lg\:flex-row {
    flex-direction: row;
  }
}

<script src="https://cdn.tailwindcss"></script>
<style type="text/tailwindcss">
/* Generated by TailwindCSS */
.flex {
  display: flex;
}
.flex-col {
  flex-direction: column;
}
@screen lg {
  .lg\:flex-row {
    flex-direction: row;
  }
}
/* Added by you or your UI libary or etc. */
.flex-col {
  flex-direction: column;
}
@screen lg {
  .lg\:flex-row {
    flex-direction: row;
  }
}
</style>

* Working<br>
Click the "Full page" button for the lg view
<div class="flex flex-col lg:flex-row">
  <div>1.</div>
  <div>2.</div>
</div>

<div class="flex lg:flex-row flex-col">
  <div>1.</div>
  <div>2.</div>
</div>

or with Tailwind CSS v4 syntax:

.flex-col {
  flex-direction: column;
}
.lg\:flex-row {
  @variant lg {
    flex-direction: row;
  }
}

<script src="https://unpkg/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
/* Generated by TailwindCSS */
.flex {
  display: flex;
}
.flex-col {
  flex-direction: column;
}
.lg\:flex-row {
  @variant lg {
    flex-direction: row;
  }
}
/* Added by you or your UI libary or etc. */
.flex-col {
  flex-direction: column;
}
.lg\:flex-row {
  @variant lg {
    flex-direction: row;
  }
}
</style>

* Working<br>
Click the "Full page" button for the lg view
<div class="flex flex-col lg:flex-row">
  <div>1.</div>
  <div>2.</div>
</div>

<div class="flex lg:flex-row flex-col">
  <div>1.</div>
  <div>2.</div>
</div>

本文标签: reactjsTailwind breakpoints overwritten when used inside specific componentStack Overflow