Animating a background moving between grid elements

I made this simple switch but I wanna animate the background moving from left to right instead of having it disappear and reappear. Right now the background is just a css class applied when the item is active, but I was thinking of creating a grid item that overlaps the other two with the same width to achieve this. Couldn't get it working though, any tips on how I can do this? This is my current component
<script lang="ts" setup>
defineProps<{
first: string
second: string
}>()
const enabled = ref(false)

function toggle() {
enabled.value = !enabled.value
}
</script>

<template>
<Switch
v-model="enabled"
class="relative grid grid-cols-2 bg-grey-900 gap-2 border-box-border rounded-full border p-1 cursor-pointer"
@click="toggle"
>
<span
class="select-none text-center rounded-full px-2 py-1 text-xs transition-all"
:class="enabled ? 'bg-purple-500' : ''"
>{{ first }}</span>
<span
class="select-none text-center rounded-full px-2 py-1 text-xs transition-all"
:class="!enabled ? 'bg-purple-500' : ''"
>{{ second }}</span>
</Switch>
</template>
<script lang="ts" setup>
defineProps<{
first: string
second: string
}>()
const enabled = ref(false)

function toggle() {
enabled.value = !enabled.value
}
</script>

<template>
<Switch
v-model="enabled"
class="relative grid grid-cols-2 bg-grey-900 gap-2 border-box-border rounded-full border p-1 cursor-pointer"
@click="toggle"
>
<span
class="select-none text-center rounded-full px-2 py-1 text-xs transition-all"
:class="enabled ? 'bg-purple-500' : ''"
>{{ first }}</span>
<span
class="select-none text-center rounded-full px-2 py-1 text-xs transition-all"
:class="!enabled ? 'bg-purple-500' : ''"
>{{ second }}</span>
</Switch>
</template>
6 Replies
Giuliopime
GiuliopimeOP•9mo ago
Basically something like this but for the background
Mike
Mike•9mo ago
I don't know that you need to use grid for this (the example below doesn't use grid).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #1a1a1a;
}
button{
color: rgba(255,255,255, 0.7);
border: 2px solid rgba(255,255,255, 0.7);
background-color: transparent;
width: 100px;
height: 50px;
font-size: 20px;
border-radius: 16px;
cursor: pointer;
z-index: 1;
}
.slider{
position: absolute;
width: 100px;
height: 50px;
background-color: #d946ef;
transition: 0.15s ease-in-out;
left: 0px;
border-radius: 16px;
}
.wrapper{
border: white;
display: inline-flex;
position: relative;
gap: 5px;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="slider"></div>
<button>
one
</button>
<button>
two
</button>
<button>
three
</button>
</div>
<script>
const buttons = document.querySelectorAll('button');
const slider = document.querySelector('.slider');
buttons.forEach((button, index) => {
button.addEventListener('click', () => {
slider.style.left = `${(index * 105)}px`;
});
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #1a1a1a;
}
button{
color: rgba(255,255,255, 0.7);
border: 2px solid rgba(255,255,255, 0.7);
background-color: transparent;
width: 100px;
height: 50px;
font-size: 20px;
border-radius: 16px;
cursor: pointer;
z-index: 1;
}
.slider{
position: absolute;
width: 100px;
height: 50px;
background-color: #d946ef;
transition: 0.15s ease-in-out;
left: 0px;
border-radius: 16px;
}
.wrapper{
border: white;
display: inline-flex;
position: relative;
gap: 5px;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="slider"></div>
<button>
one
</button>
<button>
two
</button>
<button>
three
</button>
</div>
<script>
const buttons = document.querySelectorAll('button');
const slider = document.querySelector('.slider');
buttons.forEach((button, index) => {
button.addEventListener('click', () => {
slider.style.left = `${(index * 105)}px`;
});
});
</script>
</body>
</html>
No description
Mike
Mike•9mo ago
hopefully that's helpful 😄
Giuliopime
GiuliopimeOP•9mo ago
that's fixed width unfortunately but thank you
Mike
Mike•9mo ago
yep, it's fixed width right now, but can you think of any way to make this work for dynamic width buttons?
0xffff
0xffff•9mo ago
Manu Arora
Navbar Hover - Code Snippet
A collection of code snippets – including serverless functions, Node.js scripts, and CSS tricks.
Want results from more Discord servers?
Add your server