I created my layout with css grid with two columns:
.app {
height: 100vh;
display: grid;
grid-template-columns: 260px 1fr;
grid-template-rows: 56px 1fr 40px;
grid-template-areas: "menu header" "menu content" "menu footer";
}
Now I want to add a smooth transition. I did the following: When I click on header component's toggle button, I hide my sidebar component.
.hide-menu {
grid-template-areas:
"header header"
"content content"
"footer footer";
}
The problem is that the layout is breaking.
I don't know what to pass as a parameter in translateX of layout component. I guess this is my issue.
.openMain {
transform: translateX(-260px); <<<<<<<<
transition: all 500ms linear;
}
Could you help me find out where I'm going wrong?
Full code
Layout component
<template>
<div class="app" :class="{ 'hide-menu': ! isMenuVisible, closeMain: isMenuVisible, openMain: ! isMenuVisible}">
<lheader />
<lmenu />
<main class="main p-5" style="overflow: auto">
<slot />
</main>
<lfooter />
</div>
</template>
<script>
import Lheader from "./Lheader.vue";
import Lfooter from "./Lfooter.vue";
import Lmenu from "./Lmenu.vue";
import { mapState } from "vuex";
export default {
name: "Layout",
computed: mapState(["isMenuVisible"]),
components: {
Lheader,
Lfooter,
Lmenu,
},
};
</script>
<style>
.app {
height: 100vh;
display: grid;
grid-template-columns: 260px 1fr;
grid-template-rows: 56px 1fr 40px;
grid-template-areas: "menu header" "menu content" "menu footer";
}
.main {
grid-area: content;
background-color: #ebedef;
}
.hide-menu {
grid-template-areas:
"header header"
"content content"
"footer footer";
}
.openMain {
transform: translateX(-260px);
transition: all 500ms linear;
}
.closeMain {
transform: translateX(0);
transition: all 500ms linear;
}
</style>
Menu (sidebar) component
<template>
<aside :class="{ openSidebar:isMenuVisible, closeSidebar:!isMenuVisible }" class="menu text-white border-r
border-gray-400">
<div class="flex justify-center items-center h-14 bg-gray-800">
Brand
</div>
<div class="flex flex-col">
<ul>
<inertia-link href="/">
<li class="flex items-center p-5 hover:bg-gray-700 cursor-pointer "
:class="isUrl('') ? 'bg-gray-700' : ''">
<i class="fas fa-tachometer-alt mr-2"></i>Dashboard
</li>
</inertia-link>
<li class="flex flex-col p-5 hover:bg-gray-700 cursor-pointer"
:class="isUrl('users/index') ? 'bg-gray-700' : ''">
<a href="#" class="flex items-center" @click="usersMenu = !usersMenu">
<div class="flex-grow">
<i class="fas fa-users mr-2"></i>Users
</div>
<div>
<i class="fas" :class="{'fa-angle-down': usersMenu, 'fa-angle-left': !usersMenu }">
</i>
</div>
</a>
<ul class="flex flex-col pt-5" :class="{ hidden: usersMenu }">
<inertia-link href="/users/index">
<li class="flex items-center h-14 px-6 hover:bg-gray-600 cursor-pointer rounded
transition duration-500 ease-in-out"
:class=" isUrl('users/index') ? 'bg-gray-600' : ''" >
<i class="fas fa-list mr-2"></i>List
</li>
</inertia-link>
<inertia-link href="/users/report">
<li class="flex items-center h-14 px-6 hover:bg-gray-600 cursor-pointer rounded
transition duration-500 ease-in-out"
:class=" isUrl('users/report') ? 'bg-gray-600' : ''" >
<i class="fas fa-list mr-2"></i>Report
</li>
</inertia-link>
</ul>
</li>
</ul>
</div>
</aside>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: "Menu",
computed: mapState(['isMenuVisible']),
data() {
return {
usersMenu: true
};
},
methods: {
isUrl(...urls) {
let currentUrl = this.$page.url.substr(1);
if (urls[0] === "") {
return currentUrl === "";
}
return urls.filter((url) => currentUrl.startsWith(url)).length;
}
},
};
</script>
<style>
.menu {
grid-area: menu;
background-color: #3c4b64;
}
.openSidebar {
position: static;
opacity: 1;
visibility: visible;
transform: translateX(0);
transition: all 500ms linear;
}
.closeSidebar {
position: absolute;
opacity: 0;
visibility: hidden;
transform: translateX(-260px);
transition: all 500ms linear;
}
</style>


