I would like to write these media queries in TailwindCSS in a custom CSS file:
@media screen and (max-width: 766px) or {} @media screen and (min-width: 767px) {}
I figured out that the correct way is to write @screen md (or sm), however I can't add min or max width.
@screen is actually quietly deprecated and thus is not documented for Tailwind v3. Instead, consider using screen() like:
@media screen(sm) {
/* … */
}
Which would compile to:
@media (min-width: 640px) {
/* … */
}
If you want max-width, you could consider configuring screens:
const defaultTheme = require('tailwindcss/defaultTheme')
/** @type {import('tailwindcss').Config} */
module.exports = {
theme: {
screens: {
foo: { 'max': '800px' },
...defaultTheme.screens,
},
},
};
Then this would enable you to do:
@media screen(foo) {
/* … */
}
Which would compile to:
@media (max-width: 800px) {
/* … */
}
We use theme.screens instead of the typical theme.extend.screens since order can be important. Also please note that min-* and max-* variants would no longer work with this customization.
Otherwise, you could consider using not with @media which can be used to emulate max-width without needing to add extra screens configuration:
@media not all and screen(sm) {
/* … */
}
Which would compile to:
@media not all and (min-width: 640px) {
/* … */
}
Which is similar to:
@media (max-width: 639px) {
/* … */
}
The use of @screen will be deprecated. Instead, the globally introduced @variant can be used to define any variant or a combination of multiple variants. See:
@variant directive - TailwindCSS v4 Docs.my-element {
display: hidden;
@variant lg {
display: block;
}
}
But as I mentioned, this new directive is not only useful for screen, but for anything else as well—in fact, it can even be nested.
/* my-element = bg-white dark:hover:bg-black */
.my-element {
background: white;
@variant dark {
@variant hover {
background: black;
}
}
}
Moreover, with the new @custom-variant directive, you can create your own directives by simply defining when they should be valid. For example, the lg variant is valid by default for screen widths of at least 1024px.
Similarly, you can create an md-to-lg variant that applies between 768px and 1024px. Or, you can define a completely different variant that only becomes valid when the parent element has the .coffee class.
@custom-variant directive - TailwindCSS v4 Docs@custom-variant md-to-lg (@media (width >= 768px) and (width <= 1024px));
/* or can use theme() function */
@custom-variant lg-to-3xl (@media (width >= theme(--breakpoint-lg)) and (width <= theme(--breakpoint-3xl)));
/* or can use other rules */
@custom-variant theme-coffee (&:where(.coffee, .coffee *));
/* my-element = w-[500px] bg-white xs:w-[600px] md-to-lg:w-[1000px]
lg-to-3xl:w-[1500px] dark:black dark:hover:bg-[#555]
theme-coffee:bg-[brown] */
.my-element {
width: 500px;
background: white;
/* from XS to overwrite -- it's default variant */
@variant xs {
width: 600px;
}
/* from MD to LG -- it's custom variant */
@variant md-to-lg {
width: 1000px;
}
/* from LG to 3XL -- it's custom variant */
@variant lg-to-3xl {
width: 1500px;
}
/* when dark theme activated -- it's default variant */
@variant dark {
background: black;
@variant hover {
background: #555;
}
}
/* when coffee theme activated -- it's custom variant */
@variant theme-coffee {
background: brown;
}
}
Returning to the code mentioned in the question, in v4 it could look like this:

<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@custom-variant only-sm-or-md (@media (width >= theme(--breakpoint-sm)) and (width <= theme(--breakpoint-md)));
.my-element {
background: blue;
@variant only-sm-or-md {
background: green;
}
}
</style>
Click the "Full page" button
<div class="hidden only-sm-or-md:block">block only in (sm or md)</div>
<div class="my-element only-sm-or-md:hover:!bg-red-500">blue by default; green only (sm or md)</div>
Related examples for @variand and @custom-variant directives:
If you don't want to give it a custom name — since that was primarily the question — in version 4 you have the option to specify a so - called "range". The starting breakpoint is the traditional one: sm:. The ending breakpoint (where you no longer want it to apply) is max-md: (meaning it won't apply at md).
So, if you want your class to apply only at sm, you can use: sm:max-md:.
If you want it to apply from sm up to lg, then you use: sm:max-xl: (where xl is no longer included in the range).
<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
.my-element {
background: blue;
/* works in sm and in md */
@variant sm {
@variant max-lg {
background: green;
}
}
}
</style>
Click the "Full page" button
<div class="hidden sm:max-lg:block">block only in (sm or md)</div>
<div class="my-element sm:max-lg:hover:!bg-red-500">blue by default; green only (sm or md)</div>
Follow Wongjn's answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With