wire-elements / modal

Livewire component that provides you with a modal that supports multiple child modals while maintaining state.
MIT License
1.11k stars 129 forks source link

Enabling Tailwind CSS' JIT mode breaks modals on screen widths over 640px (sm breakpoint) #65

Closed JulienZD closed 6 months ago

JulienZD commented 3 years ago

Setting mode: 'jit' in tailwind.config.js breaks modals on screen widths > 640px (Tailwind's sm breakpoint). Clicking a button to enable the modal does correctly fade in the backdrop, but the actual content is placed at the very bottom outside the screen.

This only affects the modals when the sm:* classes are active. The modal content shows up fine on screen widths below 640px.

I've found that a way to fix this is to purge './vendor/livewire-ui/modal/resources/**/*' rather than './vendor/livewire-ui/modal/resources/views/*.blade.php' in tailwind.config.js.

JIT off (works as expected): image

JIT on (broken, note the visible y overflow): image

JIT on while purging './vendor/livewire-ui/modal/resources/**/*': Works as expected, same result as JIT off.

The screenshots were taken on a fresh Laravel project with livewire-ui/modal@1.0 installed. Installed npm packages are tailwindcss@2.2.4, autoprefixer@10.3.1 and postcss-import@14.0.2.

The HelloWorld modal component was made as per the tutorial.

tailwind.config.js purge contents are as instructed by the readme:

module.exports = {
  purge: {
    content: [
      './vendor/livewire-ui/modal/resources/views/*.blade.php',
      './storage/framework/views/*.php',
      './resources/views/**/*.blade.php',
    ],
    options: {
      safelist: [
        'sm:max-w-2xl'
      ]
    }
  },
  // ...
}

webpack.mix.js (if relevant):

const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js')
    .postCss('resources/css/app.css', 'public/css', [
        require('postcss-import'),
        require('tailwindcss'),
        require('autoprefixer'),
    ]);

welcome.blade.php:

<html>
<head>
      <link rel="stylesheet" href="{{ asset('css/app.css') }}">
      <script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
      @livewireStyles
</head>
<body>
    <div class="h-screen grid place-content-center">
        <button class="bg-gray-800 text-white p-4" onclick="Livewire.emit('openModal', 'hello-world')">Click me</button>
    </div>

    @livewire('livewire-ui-modal')
    @livewireScripts
</body>
</html>
gavinhewitt commented 3 years ago

@JulienZD

I'm experiencing the same issue. After breaking my head over why this was happening on one install but not another, I finally traced it down to the differences in Tailwind versions, 2.1.2 vs 2.2.4 (breaking version). I tried your solution but for me it does not seem to have effect. I'm still investigating though and I may have missed something crucial. Will report back.

gavinhewitt commented 3 years ago

Narrowed it down to sm:block and sm:inline-block. Not sure why those would be problematic but when you comment them out the modal appears (but positioned incorrectly and full width).

@PhiloNL Aren't you having issues with this? You look like someone that has JIT enabled ;-)

gavinhewitt commented 3 years ago

Sooo, after spending hours investigating and being confused it finally occurred to me that the modal width (4xl) possibly had not been picked up by jit. Added sm:max-w-4xl to the safelist and it now works.

Could that be your issue too @JulienZD ?

JulienZD commented 3 years ago

@gavinhewitt

You're right. A couple days ago I found that setting the sm:max-w-* classes in the safelist does indeed make them show up. At the time I still had './vendor/livewire-ui/modal/resources/**/*' in my purge list, allowing to sm:max-w-2xl work by default. Which makes sense as this probably caused Tailwind to pick up this line: https://github.com/livewire-ui/modal/blob/13ddf19ba43529e8644186ff32f0cfdad57ee538/resources/js/modal.js#L7

When I realized this it didn't occur to me to try it with the original recommended purge config. However, I did notice that the example tailwind.config.js in the README has the purge object defined as so:

purge: {
    content: [
        // purged files
    ],
    options: {
        safelist: ['sm:max-w-2xl']
    }
}

This is actually an incorrect setup when you use JIT. Adding other classes to this array doesn't work, as those classes are passed to PurgeCSS (which I guess doesn't work as expected with JIT enabled).

Because of this your purge object should look like this when using JIT:

purge: {
    content: [
        // purged files
    ],
    safelist: [
        'sm:max-w-2xl',
        // other sm:max-w breakpoints you use in your modals
    ]
}

@PhiloNL It may be a good idea to mention this in the TailwindCSS section of the README as it will prevent many hours of headaches.

victorybiz commented 3 years ago

@JulienZD Thanks! I was having same issue, your instructions worked but for only 2xl breakpoint which is the default, other breakpoints doesn't work, modal displays at the bottom of the page with full width despite defining them on the safelist.

dimitri-koenig commented 3 years ago

My very simple solution to this problem is: adding all possible widths as a blade comment right next to livewire-modal-ui tag, like this:

{{-- modalwidth comment for tailwind purge, used widths: sm:max-w-sm sm:max-w-md sm:max-w-lg sm:max-w-xl sm:max-w-2xl sm:max-w-3xl sm:max-w-4xl sm:max-w-5xl sm:max-w-6xl sm:max-w-7xl --}}
@livewire('livewire-ui-modal')

That way the tailwind parser finds those required css classes and includes them. Alternative is the safelist option in the tailwind config. But my personal preference is to keep such special stuff where it belongs and keep my tailwind config as small and clean as possible.

seabasss commented 2 years ago

Isn’t the problem that the modal is splitting the tailwind class names so JIT can’t find them? If so, maybe it’s an idea to use complete class names to avoid having to add all sizes to the safelist.

breadthe commented 2 years ago

My very simple solution to this problem is: adding all possible widths as a blade comment right next to livewire-modal-ui tag, like this:

{{-- modalwidth comment for tailwind purge, used widths: sm:max-w-sm sm:max-w-md sm:max-w-lg sm:max-w-xl sm:max-w-2xl sm:max-w-3xl sm:max-w-4xl sm:max-w-5xl sm:max-w-6xl sm:max-w-7xl --}}
@livewire('livewire-ui-modal')

That way the tailwind parser finds those required css classes and includes them. Alternative is the safelist option in the tailwind config. But my personal preference is to keep such special stuff where it belongs and keep my tailwind config as small and clean as possible.

I was having the same problem and your solution was the only one that worked. It's strange that safelisting the same classes doesn't work at all. I can see that in the production bundle size (26.7K when the classes are included properly vs 26.4K when they are not)

manusiakemos commented 2 years ago
{
  "purge": {
    "content": [
      "./resources/**/*.blade.php",
      "./resources/**/*.js",
      "./resources/**/*.vue",
      "./vendor/wire-elements/modal/resources/views/*.blade.php",
      "./storage/framework/views/*.php"
    ],
    "options": {
      "safelist": [
        "sm:max-w-sm",
        "sm:max-w-md",
        "sm:max-w-lg",
        "sm:max-w-xl",
        "sm:max-w-2xl",
        "sm:max-w-3xl",
        "sm:max-w-4xl",
        "sm:max-w-5xl",
        "sm:max-w-6xl",
        "sm:max-w-7xl"
      ]
    }
  }
}
a21ns1g4ts commented 2 years ago

Allow all


options: {
    safelist: [
        "sm:max-w-sm",
        "sm:max-w-md",
        "sm:max-w-lg",
        "sm:max-w-xl",
        "sm:max-w-2xl",
        "sm:max-w-3xl",
        "sm:max-w-4xl",
        "sm:max-w-5xl",
        "sm:max-w-6xl",
        "sm:max-w-7xl",
        "md:max-w-lg",
        "md:max-w-xl",
        "lg:max-w-2xl",
        "lg:max-w-3xl",
        "xl:max-w-4xl",
        "xl:max-w-5xl",
        "2xl:max-w-6xl",
        "2xl:max-w-7xl'",
    ],
}
azmilazizi commented 2 years ago

im relatively new to github issues but last two worked for me. Thankyou mastah

DanjBethel commented 2 years ago

This still isn't working for me. Modal being stuck to the bottom with a scrollbar.

Any concrete solutions for this?

camerontucker commented 2 years ago

TailwindCSS recommends using the 'content' configuration instead of safelist in tailwind.config.js. So just scan the ModalComponent which has the possible widths:

content: [
        "./resources/**/*.blade.php",
        "./resources/**/*.js",
        "./vendor/wire-elements/modal/src/ModalComponent.php"
      ],