csstailwind-csstailwind-css-4

Porting complex custom breakpoint from tailwind.config.js to tailwind.css


I'm porting our v3 Tailwind app to v4, and have hit a hurdle right at the end of the process.

In tailwind.config.js (which I'm trying to eliminate), we have the following declaration:

theme: {
    screens: {
      xxs: '300px',
      xs: '400px',
      sm: '640px',
      md: '768px',
      lg: '926px',
      xl: '1080px',
      xxl: '1280px',
      '2xl': '1560px',
      
      'desktop-nav': { raw: '(min-width: 800px) and (min-height: 520px)' },
      'landscape-mobile-tablet': {
        raw: '(max-width: 1024px) and (orientation: landscape)',
      },
    },
...

I've managed to get the basic breakpoints ported over like so:

@theme {
  --breakpoint-xxs: 300px;
  --breakpoint-xs: 400px;
  --breakpoint-sm: 640px;
  --breakpoint-md: 768px;
  --breakpoint-lg: 926px;
  --breakpoint-xl: 1080px;
  --breakpoint-xxl: 1280px;
  --breakpoint-2xl: 1560px;
}

...but the complex (raw) ones are eluding me. As far as I can see, the docs don't cover using widths, heights and orientations together in custom breakpoints. I'd prefer not to have to change the markup if it can be avoided - has anyone else faced this issue and found a solution?


Solution

  • These weren't best breakpoints in v3 either. In v4, the API has become more consistent. Use the @custom-variant directive to declare any special variants.

    @theme {
      --breakpoint-xxs: 300px;
      --breakpoint-xs: 400px;
      --breakpoint-sm: 640px;
      --breakpoint-md: 768px;
      --breakpoint-lg: 926px;
      --breakpoint-xl: 1080px;
      --breakpoint-xxl: 1280px;
      --breakpoint-2xl: 1560px;
    }
    
    @custom-variant desktop-nav (@media (min-width: 800px) and (min-height: 520px));
    @custom-variant landscape-mobile-tablet (@media (max-width: 1024px) and (orientation: landscape));
    

    Pro tip: Since you're using px-based breakpoints, it's a good idea to disable all default rem-based breakpoints. TailwindCSS can't account for the relationship between rem and px during the compiled CSS generation - which makes sense, because rem is a dynamic value in production. As a result, Tailwind might treat even 1rem as a stronger (higher) breakpoint than 999px, since it can't resolve the actual size during build time.

    @theme {
      --breakpoint-*: initial;
      --breakpoint-xxs: 300px;
      --breakpoint-xs: 400px;
      --breakpoint-sm: 640px;
      --breakpoint-md: 768px;
      --breakpoint-lg: 926px;
      --breakpoint-xl: 1080px;
      --breakpoint-xxl: 1280px;
      --breakpoint-2xl: 1560px;
    }
    
    @custom-variant desktop-nav (@media (min-width: 800px) and (min-height: 520px));
    @custom-variant landscape-mobile-tablet (@media (max-width: 1024px) and (orientation: landscape));