I am trying to work with Tailwind CSS, where currently now I am trying to animate a background image. I tried different methods but have not yet figured out how to animate the background image in single direction from left to right.
Here is what I have done so far.
Added a custom background image
Added a repeat so that it fills the area.
What additionally I want to do, is show it like an animation, so it feels like it's moving. I had already implemented it in normal CSS but can't put it in Tailwind.
Following is the video for the animation that has been achieved in normal CSS: https://youtu.be/Jx8fg2MdG3Y
Following is the Tailwind playground for the background I have implemented so far: https://play.tailwindcss.com/jmoPHTdXAe
Current implemented code in Tailwind.
<div class="p-6 bg-gray-500 flex flex-col items-center min-h-screen justify-center bg-hero-pattern bg-repeat animate-ltr-linear-infinite">
<div class="text-white">
<h1 class="text-6xl">Some Text HERE</h1>
<h1 class="text-2xl">Background Not Animating</h1>
</div>
</div>
The following is the configuration I have tried so far in Tailwind.
theme: {
extend:{
backgroundImage: theme => ({
'hero-pattern': "url('img/bg.png')"
}),
animation:{
'ltr-linear-infinite': 'normal 100s linear infinite'
}
}
}
Following is the image I am using for repeat:
https://i.ibb.co/Qn5BR8N/bg.png
The problem
I couldn't see animation in your code. I see just the "timing-function".
Writing this:
animation: {
'ltr-linear-infinite': 'normal 100s linear infinite'
}
You tell Tailwind what he should define animation class like this:
.ltr-linear-infinite {
animation: normal 100s linear infinite;
}
It of course wouldn't work properly — there is no #keyframes normal.
The solution
Citation from docs:
To add new animation #keyframes, use the keyframes section of your theme configuration:
// tailwind.config.js
module.exports = {
theme: {
extend: {
keyframes: {
wiggle: {
'0%, 100%': { transform: 'rotate(-3deg)' },
'50%': { transform: 'rotate(3deg)' },
}
}
}
}
}
So, in your case it would be like this:
module.exports = {
theme: {
extend: {
// Define pattern
backgroundImage: theme => ({
'hero-pattern': "url('img/bg.png')"
}),
// Define animation class
animation: {
'ltr-linear-infinite': 'move-bg 10s linear infinite',
},
// Define keyframes
keyframes: {
'move-bg': {
'0%': { 'background-position': '0 0' },
'100%': { 'background-position': '256px 0'}
}
}
}
}
}
P.S. 100s makes background to move ~2.5px/s. Perhaps it is too slow, so I changed it to ~25px/s.
I had to add keyframes in the configuration of tailwind as well. to make it work.
following is the Working EXAMPLE
This is the updated code for reference if anyone needs in future.
theme: {
extend: {
backgroundImage: (theme) => ({
'hero-pattern': "url('https://i.ibb.co/Qn5BR8N/bg.png')",
}),
animation: {
'ltr-linear-infinite': 'ltr-linear-infinite 100s linear infinite',
},
keyframes: {
'ltr-linear-infinite': {
'from': { 'background-position': '0 0' },
'to': { 'background-position': '400% 0%' },
},
},
}
}
Related
How to do custom animate by blur in tailwind
module.exports = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {
keyframes: {
blur: {
'0%': {filter: blur(2px)} ,
'100%': {filter: blur(3px)},
},
},
animation: {
'blur': 'blur 2s linear ',
},
},
},
plugins: [],
}
That not work for me .
I want to make animation to my pop-up window with blur
You must wrap your blur(0px) parameter with parenthesis ("blur(0px)").
You can take a look at the examples provided on the documentation page.
In tailwind, the keyframe's key needs to get a string as its value:
HTML:
<div class="bg-red-500 animate-blur"> ~ Blurry text ~ <div>
Config:
/** #type {import('tailwindcss').Config} */
module.exports = {
theme: {
extend: {
keyframes: {
blur: {
'0%': { filter: "blur(0px)" },
'100%': { filter: "blur(5px)" },
}
},
animation: {
blur: 'blur 2s linear infinite',
}
},
},
plugins: [],
}
Tailwind-play
Is it possible to pass a value from html to the tailwind.config.js file?
I essentially want to do something similar to how we can pass a value from HTML to CSS using use custom properties. But instead passing it to the tailwind.config.js file.
For example, with HTML and CSS you can do:
.fill-color {
color: var(--color);
}
<div class="fill-color" style="--color: blue;">Test</div>
but in my project I need to pass in a variable like: 20 from the index.html file:
<div class="scroll" style="--variable-number: 20">Test</div>
So I can use it to set the keyframes percentage correctly: Tailwind.config.js file below
module.exports = {
extend: {
animation: {
scroll: 'scroll 25s linear infinite'
}
},
keyframes: {
scroll: {
'0%': {transform: 'translateX(0%)'},
'100%': {transform: 'translateX(NEED 20 VALUE HERE%)' },
}
},
}
Yes, you can do what you want to achieve, see this playground for a working example. Just add var(--percentage) to the translateX.
HTML:
<div class="animate-text-scroll" style="--percentage: 20%">Test</div>
Tailwind config:
module.exports = {
theme: {
extend: {
keyframes: {
'scroll': {
'0%': { transform: 'translateX(0)' },
'100%': { transform: 'translateX(var(--percentage))' },
},
},
animation: {
'text-scroll': 'scroll 2s linear infinite',
},
},
},
plugins: [],
}
Hope this helps.
You can achieve this using custom css variable and arbitrary values.
Heres a demo: https://play.tailwindcss.com/qEqKUVP8IQ
Whats happening:
First we define our custom keyframes and animation in the config. allowing it to read a css var like so:
extend: {
keyframes: {
scroll: {
'0%': {transform: 'translateX(0)'},
'100%': {transform: 'translateX(var(--scroll-distance))' },
}
},
animation: {
scroll: 'scroll 1s linear infinite'
},
},
then we can use arbitrary values in our class naming like so:
<div class="animate-scroll [--scroll-distance:20px]">Test</div>
<div class="animate-scroll [--scroll-distance:50px]">Test</div>
So same animation, but a custom distance on multiple elements.
The other option is to define a default value in the css file like so:
:root {--new-variable: red;}
and use it on an element
<div class="bg-[color:var(--new-variable)]">Test</div>
Hope that helps.
I have a div with text inside that has a gradient color scheme.
<div
className="bg-gradient-to-r bg-clip-text text-transparent from-indigo-500 to-purple-500"
>
SampleText
</div>
I want to animate it so that the gradient keeps smoothly changing between from-indigo-500 to-purple-500 and from-purple-500 to-indigo-500 infinitely with a set duration.
There is a simple way to achieve what you want, here is how :
1- First go to tailwind.config.js and add this inside extend
extend: {
'animation': {
'text':'text 5s ease infinite',
},
'keyframes': {
'text': {
'0%, 100%': {
'background-size':'200% 200%',
'background-position': 'left center'
},
'50%': {
'background-size':'200% 200%',
'background-position': 'right center'
}
},
}
},
2- Then add these classes to your div :
<div class="text-9xl font-semibold
bg-gradient-to-r bg-clip-text text-transparent
from-indigo-500 via-purple-500 to-indigo-500
animate-text
">
SampleText
</div>
Take a look HERE
I want to give click effect to a button like this:
.btn-translate-effect {
transition: transform .1s ease-in-out;
}
.btn-translate-effect:active {
transform: translateY(3px);
}
with tailwind utility classes.
But I'm not able to it figure it out. I tried this:
<button class="transform active:translate-y-4"></button>
It doesn't work. I also modified variant config tailwind.config.js like this:
variants: {
extend: {
transform: ['active']
},
}
But to no avail.
You need to replace transform with translate on tailwind config.
variants: {
translate: ['active'],
},
Working Example
Example is a functional component in which I am rendering a div conditionally. I want this div to fade-in when rendered conditionally and fade-out vice versa.
For that, I have maintained two local state variables: render and fadeIn which are computed based on show prop passed down to the Example component.
What I've done is:
When show prop it true, I set render as true, so the div renders conditionally and after a timeout of 10ms I set fadeIn as true which will set CSS classname for my div as show.
When show prop it false, I set fadeIn as false, which will set CSS classname for my div as hide and after a timeout of 200ms (transition time in CSS) I set render as false so the div is hidden conditionally.
Code:
interface Props {
show: boolean;
}
const Example: React.FC<Props> = ({ show, }) => {
const [render, setRender] = useState(false);
const [fadeIn, setFadeIn] = useState(false);
useEffect(() => {
if (show) {
// render component conditionally
setRender(show);
// change state to for conditional CSS classname which will
// animate opacity, I had to give a timeout of 10ms else the
// component shows up abruptly
setTimeout(() => {
setFadeIn(show);
}, 10);
} else {
// change state to change component classname for opacity animation
setFadeIn(false);
// hide component conditionally after 200 ms
// because that's the transition time in CSS
setTimeout(() => {
setRender(false);
}, 200);
}
}, [
show,
]);
return (
<div>
{render && (
<div className={`container ${fadeIn ? 'show' : 'hide'}`} />
)}
</div>
);
};
Stylesheet:
.container {
width: 100px;
height: 100px;
background-color: black;
transition: opacity 0.2s ease;
}
.show {
opacity: 1;
}
.hide {
opacity: 0;
}
I believe this is not a good coding practice to achieve the functionality and should maintain only one local state in my component. I need your suggestions on how I can solve this in a better way without using any 3rd Party Library.
Thanks :)
const [render, setRender] = useState(false);
useEffect(() => {
if(show) {
setTimeout(() => {
setRender(true);
}, 2000);
} else {
setRender(false);
}
}, [show]);
<div className={cs(s.render, render ? 'show' : undefined)}>
<p>{content}</p>
</div>
Css:
.render {
...,
visibility: hidden;
opacity: 0;
transition: all 0.6s ease;
}
.show {
visibility: visible;
opacity: 1;
}
Hope be helpful.