Skip to content

Conversation

@adamwathan
Copy link
Member

This PR makes the same changes as #4604, but for the filter and backdrop-filter utilities. Like that PR, this only targets the JIT engine due to minor breaking changes.

It makes all of the individual filter and backdrop-filter classes like brightness-*, saturate-*, backdrop-contrast-*, backdrop-blur-*, etc. work without the need for using the filter or backdrop-filter classes to "enable" them.

<!-- Before -->
<div class="filter brightness-150 invert backdrop-filter backdrop-blur-md backdrop-contrast-50">

<!-- After -->
<div class="brightness-150 invert backdrop-blur-md backdrop-contrast-50">

How it works

This works by adding two new rules targeting the universal (*) selector to the base layer that look like this:

/* For `filter` utilities */
* {
  --tw-blur: var(--tw-empty, /*!*/ /*!*/);
  --tw-brightness: var(--tw-empty, /*!*/ /*!*/);
  --tw-contrast: var(--tw-empty, /*!*/ /*!*/);
  --tw-grayscale: var(--tw-empty, /*!*/ /*!*/);
  --tw-hue-rotate: var(--tw-empty, /*!*/ /*!*/);
  --tw-invert: var(--tw-empty, /*!*/ /*!*/);
  --tw-saturate: var(--tw-empty, /*!*/ /*!*/);
  --tw-sepia: var(--tw-empty, /*!*/ /*!*/);
  --tw-drop-shadow: var(--tw-empty, /*!*/ /*!*/);
  --tw-filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale)
    var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}

/* For `backdrop-filter` utilities */
* {
  --tw-backdrop-blur: var(--tw-empty, /*!*/ /*!*/);
  --tw-backdrop-brightness: var(--tw-empty, /*!*/ /*!*/);
  --tw-backdrop-contrast: var(--tw-empty, /*!*/ /*!*/);
  --tw-backdrop-grayscale: var(--tw-empty, /*!*/ /*!*/);
  --tw-backdrop-hue-rotate: var(--tw-empty, /*!*/ /*!*/);
  --tw-backdrop-invert: var(--tw-empty, /*!*/ /*!*/);
  --tw-backdrop-opacity: var(--tw-empty, /*!*/ /*!*/);
  --tw-backdrop-saturate: var(--tw-empty, /*!*/ /*!*/);
  --tw-backdrop-sepia: var(--tw-empty, /*!*/ /*!*/);
  --tw-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness)
    var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate)
    var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate)
    var(--tw-backdrop-sepia);
}

Then each individual filter-related class looks something like this:

.blur-md {
  --tw-blur: blur(12px);
  filter: var(--tw-filter);
}
.brightness-150 {
  --tw-brightness: brightness(1.5);
  filter: var(--tw-filter);
}
.backdrop-contrast-0 {
  --tw-backdrop-contrast: contrast(0);
  backdrop-filter: var(--tw-backdrop-filter);
}
.backdrop-grayscale {
  --tw-backdrop-grayscale: grayscale(100%);
  backdrop-filter: var(--tw-backdrop-filter);
}

Breaking changes

The primary breaking change here is that the filter and backdrop-filter utilities are now dependent on the @tailwind base layer because of where we inject the universal rule. If you are only using @tailwind utilities (probably because you don't want to use our reset styles), the transforms will stop working.

The solution is to make sure you do include @tailwind base, but explicitly disable our preflight styles if you don't want those:

  /* Your custom existing CSS here... */

+ @tailwind base;
  @tailwind utilities;
// tailwind.config.js
module.exports = {
  // ...
  corePlugins: {
    preflight: false,
  }
}

Aside from that, the main thing to understand is that there are no filter or backdrop-filter classes anymore, so any authoring patterns that relied on being able to use those to enable filters will break.

For example, if you were conditionally adding the filter class using JS while leaving classes like blur-lg applied permanently, that will no longer work:

{/* Won't work anymore */}
<div className={`blur-lg brightness-150 ${shouldTransform ? 'filter' : ''}`}>

Instead you would need to conditionally apply the actual transformations:

{/* Do this instead */}
<div className={`${shouldTransform ? 'blur-lg brightness-150' : ''}`}>

Another example is if you were using the filter class to manually reset every filter to their default value at a specific breakpoint (instead of just using filter-none you fucking animal). I would be shocked if anyone is doing this in a real project in the wild:

<div class="filter blur-lg md:filter">

Instead you should write this:

<div class="blur-lg md:filter-none">

@adamwathan adamwathan merged commit 34d0551 into master Jun 10, 2021
@adamwathan adamwathan deleted the no-filter-toggles branch June 10, 2021 15:36
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

Successfully merging this pull request may close these issues.

2 participants