Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: tailwindlabs/tailwindcss
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 7ce3641e20740cff15409995704cbb07ac459e65
Choose a base ref
...
head repository: tailwindlabs/tailwindcss
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: da60fb87019fa118a6525f69a4b6b4c89c149bb2
Choose a head ref
  • 12 commits
  • 57 files changed
  • 5 contributors

Commits on Sep 24, 2024

  1. Only apply hover on devices that support hover (#14500)

    This PR updates the `hover` variant to only apply when `@media (hover:
    hover)` matches.
    
    ```diff
      .hover\:bg-black {
        &:hover {
    +     @media (hover: hover) {
            background: black;
    +     }
        }
      }
    ```
    
    This is technically a breaking change because you may have built your
    site in a way where some interactions depend on hover (like opening a
    dropdown menu), and were relying on the fact that tapping on mobile
    triggers hover.
    
    To bring back the old hover behavior, users can override the `hover`
    variant in their CSS file back to the simpler implementation:
    
    ```css
    @import "tailwindcss";
    @variant hover (&:hover);
    ```
    
    I've opted to go with just `@media (hover: hover)` for this because it
    seems like the best trade-off between the available options. Using
    `(any-hover: hover)` would mean users would get sticky hover states when
    tapping on an iPad if they have a mouse or trackpad connected, which
    feels wrong to me because in those cases touch is still likely the
    primary method of interaction.
    
    Sites built with this feature in mind will be treating hover styles as
    progressive enhancement, so it seems better to me that using an iPad
    with a mouse would not have hover styles, vs. having sticky hover styles
    in the same situation.
    
    Of course users can always override this with whatever they want, so
    making this the default isn't locking anyone in to a particular choice.
    
    ---------
    
    Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
    Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
    3 people authored Sep 24, 2024
    Configuration menu
    Copy the full SHA
    abde4c9 View commit details
    Browse the repository at this point in the history
  2. Add CSS codemods for migrating @layer utilities (#14455)

    This PR adds CSS codemods for migrating existing `@layer utilities` to
    `@utility` directives.
    
    This PR has the ability to migrate the following cases:
    
    ---
    
    The most basic case is when you want to migrate a simple class to a
    utility directive.
    
    Input:
    ```css
    @layer utilities {
      .foo {
        color: red;
      }
    
      .bar {
        color: blue;
      }
    }
    ```
    
    Output:
    ```css
    @Utility foo {
      color: red;
    }
    
    @Utility bar {
      color: blue;
    }
    ```
    
    You'll notice that the class `foo` will be used as the utility name, the
    declarations (and the rest of the body of the rule) will become the body
    of the `@utility` definition.
    
    ---
    
    In v3, every class in a selector will become a utility. To correctly
    migrate this to `@utility` directives, we have to register each class in
    the selector and generate `n` utilities.
    
    We can use nesting syntax, and replace the current class with `&` to
    ensure that the final result behaves the same.
    
    Input:
    ```css
    @layer utilities {
      .foo .bar .baz {
        color: red;
      }
    }
    ```
    
    Output:
    ```css
    @Utility foo {
      & .bar .baz {
        color: red;
      }
    }
    
    @Utility bar {
      .foo & .baz {
        color: red;
      }
    }
    
    @Utility .baz {
      .foo .bar & {
        color: red;
      }
    }
    ```
    
    In this case, it could be that you know that some of them will never be
    used as a utility (e.g.: `hover:bar`), but then you can safely remove
    them.
    
    ---
    
    Even classes inside of `:has(…)` will become a utility. The only
    exception to the rule is that we don't do it for `:not(…)`.
    
    Input:
    ```css
    @layer utilities {
      .foo .bar:not(.qux):has(.baz) {
        display: none;
      }
    }
    ```
    
    Output:
    ```css
    @Utility foo {
      & .bar:not(.qux):has(.baz) {
        display: none;
      }
    }
    
    @Utility bar {
      .foo &:not(.qux):has(.baz) {
        display: none;
      }
    }
    
    @Utility baz {
      .foo .bar:not(.qux):has(&) {
        display: none;
      }
    }
    ```
    
    Notice that there is no `@utility qux` because it was used inside of
    `:not(…)`.
    
    ---
    
    When classes are nested inside at-rules, then these classes will also
    become utilities. However, the `@utility <name>` will be at the top and
    the at-rules will live inside of it. If there are multiple classes
    inside a shared at-rule, then the at-rule will be duplicated for each
    class.
    
    Let's look at an example to make it more clear:
    
    Input:
    ```css
    @layer utilities {
      @media (min-width: 640px) {
        .foo {
          color: red;
        }
    
        .bar {
          color: blue;
        }
    
        @media (min-width: 1024px) {
          .baz {
            color: green;
          }
    
          @media (min-width: 1280px) {
            .qux {
              color: yellow;
            }
          }
        }
      }
    }
    ```
    
    Output:
    ```css
    @Utility foo {
      @media (min-width: 640px) {
        color: red;
      }
    }
    
    @Utility bar {
      @media (min-width: 640px) {
        color: blue;
      }
    }
    
    @Utility baz {
      @media (min-width: 640px) {
        @media (min-width: 1024px) {
          color: green;
        }
      }
    }
    
    @Utility qux {
      @media (min-width: 640px) {
        @media (min-width: 1024px) {
          @media (min-width: 1280px) {
            color: yellow;
          }
        }
      }
    }
    ```
    
    ---
    
    When classes result in multiple `@utility` directives with the same
    name, then the definitions will be merged together.
    
    Input:
    ```css
    @layer utilities {
      .no-scrollbar::-webkit-scrollbar {
        display: none;
      }
    
      .no-scrollbar {
        -ms-overflow-style: none;
        scrollbar-width: none;
      }
    }
    ```
    
    Intermediate representation:
    ```css
    @Utility no-scrollbar {
      &::-webkit-scrollbar {
        display: none;
      }
    }
    
    @Utility no-scrollbar {
      -ms-overflow-style: none;
      scrollbar-width: none;
    }
    ```
    
    Output:
    ```css
    @Utility no-scrollbar {
      &::-webkit-scrollbar {
        display: none;
      }
      -ms-overflow-style: none;
      scrollbar-width: none
    }
    ```
    
    ---------
    
    Co-authored-by: Jordan Pittman <jordan@cryptica.me>
    RobinMalfait and thecrypticace authored Sep 24, 2024
    Configuration menu
    Copy the full SHA
    d14249d View commit details
    Browse the repository at this point in the history
  3. Add CSS codemod for missing @layer (#14504)

    This PR adds a codemod that ensures that some parts of your stylesheet
    are wrapped in an `@layer`.
    
    This is a follow-up PR of #14411, in that PR we migrate `@tailwind`
    directives to imports.
    
    As a quick summary, that will turn this:
    ```css
    @tailwind base;
    @tailwind components;
    @tailwind utilities;
    ```
    
    Into:
    ```css
    @import 'tailwindcss';
    ```
    
    But there are a few issues with that _if_ we have additional CSS on the
    page. For example let's imagine we had this:
    ```css
    @tailwind base;
    
    body {
      background-color: red;
    }
    
    @tailwind components;
    
    .btn {}
    
    @tailwind utilities;
    ```
    
    This will now be turned into:
    ```css
    @import 'tailwindcss';
    
    body {
      background-color: red;
    }
    
    .btn {}
    ```
    
    But in v4 we use real layers, in v3 we used to replace the directive
    with the result of that layer. This means that now the `body` and `.btn`
    styles are in the incorrect spot.
    
    To solve this, we have to wrap them in a layer. The `body` should go in
    an `@layer base`, and the `.btn` should be in an `@layer components` to
    make sure it's in the same spot as it was before.
    
    That's what this PR does, the original input will now be turned into:
    
    ```css
    @import 'tailwindcss';
    
    @layer base {
      body {
        background-color: red;
      }
    }
    
    @layer components {
      .btn {
      }
    }
    ```
    
    There are a few internal refactors going on as well, but those are less
    important.
    RobinMalfait authored Sep 24, 2024
    Configuration menu
    Copy the full SHA
    d869442 View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    c094fad View commit details
    Browse the repository at this point in the history

Commits on Sep 25, 2024

  1. Improve missing layer codemod (#14512)

    This PR improves the missing layers codemod where everything after the
    last Tailwind directive can stay as-is without wrapping it in a `@layer`
    directive.
    
    The `@layer` at-rules are only important for CSS that exists between
    Tailwind directives.
    
    E.g.:
    ```css
    @tailwind base;
    
    html {}
    
    @tailwind components;
    
    .btn {}
    
    @tailwind utilities;
    
    .foo {}
    
    .bar {}
    ```
    
    Was transformed into:
    ```css
    @import "tailwindcss";
    
    @layer base {
      html {}
    }
    
    @layer components {
      .btn {}
    }
    
    @layer utilities {
      .foo {}
      
      .bar {}
    }
    ```
    
    But the last `@layer utilities` is already in the correct spot, so we
    can simplify this to just this instead:
    ```css
    @import "tailwindcss";
    
    @layer base {
      html {}
    }
    
    @layer components {
      .btn {}
    }
    
    .foo {}
    
    .bar {}
    ```
    RobinMalfait authored Sep 25, 2024
    Configuration menu
    Copy the full SHA
    951f644 View commit details
    Browse the repository at this point in the history
  2. WIP

    philipp-spiess committed Sep 25, 2024
    Configuration menu
    Copy the full SHA
    4d5d023 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    c767e02 View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    a132a08 View commit details
    Browse the repository at this point in the history
  5. Configuration menu
    Copy the full SHA
    141cd39 View commit details
    Browse the repository at this point in the history
  6. Configuration menu
    Copy the full SHA
    8846fb4 View commit details
    Browse the repository at this point in the history
  7. Configuration menu
    Copy the full SHA
    c8fc77b View commit details
    Browse the repository at this point in the history
  8. Configuration menu
    Copy the full SHA
    da60fb8 View commit details
    Browse the repository at this point in the history
Loading