Hidden on Custom Breakpoint Breaks All Breakpoints' Display Value in Tailwind - css

Here is the Tailwind Play code.
I have a configuration as below, mind the custom breakpoint:
const colors = require("tailwindcss/colors");
module.exports = {
darkMode: "media", // or 'media' or 'class'
theme: {
extend: {
screens: {
xs: "320px", // here i have xs
},
colors: {
orange: colors.orange,
},
},
},
variants: {
extend: {},
},
plugins: [],
};
Then I have some elements as below:
<div class="bg-gray-500 xs:hidden sm:hidden md:flex">
<h1>foo</h1>
</div>
I want the div to display on screens above md, otherwise it should be hidden.
The weird thing about the code above is this totally works with built-in breakpoint, sm. For example, if you remove xs:hidden in Tailwind Play. You will see the behavior I want to have.
However, I also want to include xs:hidden. Why does this happen?
Thanks in advance.
Environment
"postcss": "^7.0.39",
"tailwindcss": "npm:#tailwindcss/postcss7-compat#^2.2.17"
Using with React.

To hide and element until a specific width use hidden to hide the element and another display class with responsive modifier (e.g. md:flex) to show it again.
So basically this should fit your needs:
<div class="bg-gray-500 hidden md:flex">
<h1>foo</h1>
</div>
See https://play.tailwindcss.com/Nb0QOhn9E7 for a working snippet.
Combining a responsive hidden (e.g. xs:hidden) and with another responsive display class (e.g. md:flex) doesnt work as the specifity of both css selectors is the same (both use a single class selector inside a mediaquery) so the md:flex does not overwrite it.
Therefore use non-responsive hidden (single class selector) which is less specific then md:flex (single class selector inside a mediaquery) so it gets overwritten for md upwards.
Theres also a issue in tailwind-css github regarding this behaviour:
https://github.com/tailwindlabs/tailwindcss/issues/841

Related

TailwindCSS breakpoints are not triggering when hitting certain breakpoints

I am working on a Next js + tailwindcss project, where I am trying to make my site responsive.
This is my component: <div className="flex md:hidden">
According to the rules, this div should start with its display set as flex, but as soon as it hits screen size "md" it should hide.
but it keeps itself hidden for some reason, and flex property never got applied.
Similarly, in 2nd case:
`<div className="bg-red-200 xs:bg-blue-500 sm:bg-pink-600 md:bg-green-400 lg:bg-gray-50"`
only background color of "md" screen size is applied for every screen size while testing.
I tried custom values as well but it didn't solve anything, here is my tailwind.config.js file:
/** #type {import('tailwindcss').Config} */
module.exports = {
content: [
"./app/**/*.{js,ts,jsx,tsx}",
"./pages/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
],
theme: {
screens: {
'xs': '320px',
'sm': '576px',
'md': '960px',
'lg': '1440px',
'xl': '1280px',
'2xl': '1536px',
},
extend: {},
},
plugins: [],
}
I have gone through docs, many StackOverflow questions & Youtube videos but I don't have any idea why this is happening, please help me find its cause, Thanks.
it happens because it's not max display but minimum so if you use md it will affect lg and md display, i had the same problem, and the solution i found was using max-md
md:hidden
to
max-md:hidden
using max makes it only work up to that display

Add gradient as a class in Tailwind css

I want to add this style:
background: linear-gradient(10deg, #AF8800 4.03%, #AA9F1F 6.02%, #A7B334 6.01%)
... to tailwind to be able to add it as a class name. I know that in tailwind we can create classes like this:
bg-[red]
Question: How to do the same action as above with the specified gradient?
you can easily use from and to in your class like
<div class="bg-gradient-to-r from-cyan-500 to-blue-500"></div>
from that's snippet you can gradient from color cyan 500, to blue 500
It is complex gradient so you have to use either arbitrary values or extend Tailwind configuration. Add CSS property almost as it is within square brackets - replace spaces with low dash _. Your class should looks like
<div class="bg-[linear-gradient(10deg,#AF8800_4.03%,#AA9F1F_6.02%,#A7B334_6.01%)] p-10"></div>
If you have less than 3 colors included it may be separated between few "stop-color" classes
<div class="p-10 bg-[linear-gradient(10deg,var(--tw-gradient-stops))] from-[#AF8800_4.03%] via-[#AA9F1F_6.02%] to-[#A7B334_6.01%]"></div>
I've also created this package so you can use bg-gradient-10 instead of bg-[linear-gradient(10deg,var(--tw-gradient-stops))]
If you want to avoid arbitrary variants you may extend configuration for background-image or create static utility plugin
const plugin = require('tailwindcss/plugin')
/** #type {import('tailwindcss').Config} */
module.exports = {
theme: {
extend: {
backgroundImage: {
'my-gradient': 'linear-gradient(10deg, #AF8800 4.03%, #AA9F1F 6.02%, #A7B334 6.01%)'
}
},
},
plugins: [
plugin(function({ addUtilities, addComponents, e, config }) {
addUtilities({
'.bg-my-uitility-gradient': {
'background-image': 'linear-gradient(10deg, #AF8800 4.03%, #AA9F1F 6.02%, #A7B334 6.01%)',
},
})
})
],
}
<div class="p-10 bg-my-gradient"></div>
<div class="p-10 bg-my-uitility-gradient"></div>
DEMO

Tailwindcss background-image not working in dark mode

I have my Tailwind classes defined like this:
<section class="dark:bg-gray-900 bg-hero-image bg-fixed">
So in the light version a background image is shown and on the dark version just gray-900 as background color.
The image is defined in tailwind.config.js like this:
theme: {
extend: {
backgroundImage: {
'hero-image': "url('/header.jpg')"
},
But this just doesn't work and still shows the image on dark mode.
You have to add backgroundImage to the variants in tailwind.config.js:
module.exports = {
variants: {
extend: {
backgroundImage: ["dark"],
},
},
ALSO you have to add dark:bg-none for the background-image to be set to none.
<section class="dark:bg-gray-900 dark:bg-none bg-hero-image bg-fixed">
This is also nessessary for things like invert and many other classes. Check the corresponding section in the docs, whether or not the variants are included by default.
By default, only responsive variants are generated for invert utilities.
https://v2.tailwindcss.com/docs/invert#variants

Alter background color of NavBar inserted in App.vue from within sibling router-view component

I am trying to change the background and text color of my navbar component depending on what page I am on in order to remove contrasting colors with the current pages background. Effectively wanting a light and dark theme variant for the TopNav component that is triggered by what page we are currently on.
My nav bar and page template is as below:
<template>
<v-app>
<TopNav /> ------> This is the navbar component whos css i want to alter
<v-content>
<router-view></router-view> -----> Depending on what the current page injected is.
</v-content>
<Footer />
</v-app>
</template>
Using <style> tags without the scoped attribute work on changing the navbar background but unfortunately it does not revert back after navigating to another page.
Changing state of a component from a sibling level or child level component is really an anti-pattern.
Your best bet is going to be using a well established pattern to get the functionality you're after.
One way to do this is to bring in Vuex, and place your light/dark mode in the Vuex store (shared application level state management)
Then, you could setup your TopNav component to bind to a value in Vuex state (this.$store.state.darkMode for example)
Then, from anywhere in the application, you could commit a mutation to specify light mode, dark mode, toggle, etc...
Or, if you want it to always be route-specific (kinda sounds like this is the case) then you can setup your route definition something like this:
const routes = [
{
path: '/light-component',
name: 'LightComponent',
component: () => LightComponent,
meta: {
darkMode: false,
},
},
{
path: '/dark-component',
name: 'DarkComponent',
component: () => DarkComponent,
meta: {
darkMode: true,
},
},
];
Then, in any component (your TopNav component for example) you could do something like:
<template>
<div :class="darkModeClass">
...
// inside <script> ...
computed: {
darkModeClass() {
return { dark: !!this.$route.meta?.darkMode };
}
}
...
<style scoped>
.dark {
/* css styles for dark mode */
}
</style>

Modifying hover in Tailwindcss

I've noticed that :hover in Tailwindcss uses the defaults hover selector which causes 'stuck' hover states on mobile. Is there a way to modify the :hover function to do a #media(hover:hover) instead?
update: There is now a better way. See this answer by Javier Gonzalez
original:
By far the simplest way is to add your own #media rule to the #responsive-class of rules in tailwind. How you can do that is described in the official tailwind documentation under the topic of custom media queries.
Simply add this to your config:
// tailwind.config.js
module.exports = {
theme: {
extend: {
screens: {
'hover-hover': {'raw': '(hover: hover)'},
}
}
}
}
This translates to #media (hover: hover) { ... } in css. And voila, you could use hover-hover:text-red to display red text only for devices that have hover ability.
To make your own, leave 'raw' as is and change the other two attributes to whatever media query you want. The first attribute hover-hover is what you use in tailwind. The second (hover: hover) is what your actual css #media query looks like. E.g.: hover: none or pointer: coarse.
Now, go ahead and use hover-hover:hover:text-red to modify your hover states.
Might be a bit late but the Tailwind team is already addressing this issue in Tailwind version 3 using a feature flag: https://github.com/tailwindlabs/tailwindcss/pull/8394
Once a new version is published with these changes Starting on tailwindcss v3.1.0, you could include a feature flag in your configuration to look like:
// tailwind.config.js
module.exports = {
future: {
hoverOnlyWhenSupported: true,
},
// ...
}
Yes, just generate the hover variant using a plugin that, besides adding the :hover pseudo-selector, also wraps all of the rules inside an #media(hover:hover) rule:
// tailwind.config.js
const plugin = require('tailwindcss/plugin');
const hoverPlugin = plugin(function({ addVariant, e, postcss }) {
addVariant('hover', ({ container, separator }) => {
const hoverRule = postcss.atRule({ name: 'media', params: '(hover: hover)' });
hoverRule.append(container.nodes);
container.append(hoverRule);
hoverRule.walkRules(rule => {
rule.selector = `.${e(`hover${separator}${rule.selector.slice(1)}`)}:hover`
});
});
});
module.exports = {
plugins: [ hoverPlugin ],
}
The responsive attributes like sm: md: lg: will do those media query job for you. Refer example in the docs. If you dont want to use hover state in mobile device. specify with eg:- sm:hover:no-underline
You can easily create your own hover like below:
// styles.css
#variants hover {
.banana {
color: yellow;
}
}
Then use it like class='hover:banana'
Using arbitrary variants
<button
type="button"
class="
[#media(hover:hover)]:opacity-0
[#media(hover:hover){&:hover}]:opacity-100
">
<!-- ... -->
</button>

Resources