How to stop background scroll of Fixed element in React? - css

I'm using NextJS with tailwind. and I'm creating a drawer, popup and modal with position: fixed. so when i implement this and scroll on it the background component will scroll as well. even if the fixed is scrollable when the scroll end the back element starts to scroll. how can I make it stop for the background to be not scrollable and clickable?
function Drawer() {
const toggle = useSelector(selectMenu);
const dispatch = useDispatch();
const handleOnClose = (e) => {
if (e.target.id === "container") dispatch(toggleMenu(!toggle));
};
return (
<div
id="container"
onClick={handleOnClose}
className={`md:hidden h-full w-full backdrop-blur-sm fixed ${
!toggle && "hidden"
}`}
>
<div
className={`${
toggle ? " translate-x-0" : "translate-x-full"
} md:hidden fixed h-screen w-3/4 ease-in-out duration-300 bg-white z-50 bottom-0 top-0 right-0 flex flex-col px-4 py-3 space-y-5 shadow-2xl`}
>
<Link
href="/"
className="cursor-pointer flex px-2 space-x-4"
onClick={() => dispatch(toggleMenu(!toggle))}
>
<HomeModernIcon className="h-6 w-6 text-black" />
<h1>Dashboard</h1>
</Link>
<div className=" h-[1px] w-full bg-gray-600" />
<Link
href="/clients"
className="cursor-pointer flex px-2 space-x-4"
onClick={() => dispatch(toggleMenu(!toggle))}
>
<TruckIcon className="h-6 w-6 text-black" />
<h1>Clients</h1>
</Link>
<div className=" h-[1px] w-full bg-gray-600" />
<Link
href="/employee"
className="cursor-pointer flex px-2 space-x-4"
onClick={() => dispatch(toggleMenu(!toggle))}
>
<PuzzlePieceIcon className="h-6 w-6 text-black" />
<h1>Employee</h1>
</Link>
<div className=" h-[1px] w-full bg-gray-600" />
<Link
href="/services"
className="cursor-pointer flex px-2 space-x-4"
onClick={() => dispatch(toggleMenu(!toggle))}
>
<WrenchIcon className="h-6 w-6 text-black" />
<h1>Services</h1>
</Link>
</div>
</div>
);
}

Inside Modal component add this useEffect. since you are using tailwind-css, add overflow-hidden className to the body element
useEffect(() => {
// this will disable the scroll if our back page was scrollable
document.body.classList.add("overflow-hidden");
// when you close the modal, remove this class
return () => {
document.body.classList.remove("overflow-hidden");
};
}, []);

Related

Button not clickable with div in negative z index in tailwind css

I'm using Next.js with typescript and Tailwind CSS. (T3 stack)
I'm having trouble making the button clickable here is the code. I susspect that the div page is blocking the div and making all unclickable but I don't know how to do it. I think that the fix may be making the div where I call the component somehow not clickable
import React, { useRef, useContext, useState, useCallback } from "react";
import Image from "next/image";
import { FaChevronDown } from "react-icons/fa";
import { ScrollContext } from "../utils/scroll-observer";
const Masthead: React.FC = () => {
const refContainer = useRef<HTMLDivElement>(null);
const { scrollY } = useContext(ScrollContext);
let progress = 0;
const { current: elContainer } = refContainer;
if (elContainer) {
progress = Math.min(scrollY / elContainer.clientHeight, 1);
}
return (
<div
ref={refContainer}
className="min-h-screen flex flex-col items-center justify-center sticky top-0 -z-10"
style={{
transform: `translateY(-${progress * 20}vh)`,
}}
>
<video
autoPlay
loop
muted
playsInline
className="bg-white absolute w-full h-full object-cover"
>
<source src="/assets/background_video.mp4" />
</video>
<div className={`flex-grow-0 pt-10 transition-opacity duration-1000`}>
<Image src="/logoLiteContract.png" width={70} height={70} alt="logo" />
</div>
<div className="p-12 font-bold z-10 text-white drop-shadow-[0_5px_3px_rgba(0,0,0,0.4)] text-center flex-1 flex items-center justify-center flex-col">
<h1 className="mb-6 text-4xl xl:text-5xl">Lite contract</h1>
<h2 className="mb-2 text-2xl xl:text-3x tracking-tight">
<span>Registrate y empieza subir tus contratos</span>
</h2>
{/* Create a div in z-10 to make the button clickable */}
{/* Create a button for registration with hover effect and animation ensure that the button is on top of the video */}
{/* Space between the buttons*/}
<div className="h-10"></div>
<button className="bg-gray-700 hover:bg-black text-white font-bold py-2 px-4 rounded-full">
Registrate
</button>
{/* Space between the buttons*/}
<div className="h-10"></div>
{/* Create a button for login with hover effect and animation */}
<button className="bg-gray-500 hover:bg-gray-900 text-white font-bold py-2 px-4 rounded-full">
Iniciar sesiĆ³n
</button>
</div>
<div className="flex-grow-0 pb-20 md:pd-10 transition-all duration-1000">
<FaChevronDown className="w-10 h-10 text-white animate-bounce" />
</div>
</div>
);
};
export default Masthead;
Any Ideas?

Recommended way of hiding elements until animation is complete Tailwind CSS?

Demo
The text expands in width with the sidebar, when ideally, the transition is much smoother. Maybe delayed so it tricks the eye to thinking it appears only when fully expanded.
How should I think about achieving this?
<div className="flex flex-col items-center space-y-4 w-full mt-8">
<Logo open={open} />
{open && <div className="h-auto w-3/4 text-xs text-slate-400">This looks weird when the line is super long</div>}
....
Should I attach a delay? transition-delay does nothing on the inner div.
I made an over simplified example, hopefully can help finding a good solution.
This one uses a cross delay approach to make the transition smooth when opening and closing the drawer.
There is a state open controls the drawer. On the drawer container:
open ? "w-52 delay-0" : "w-12 delay-300"
And the inside element uses a reversed delay value, something like:
open ? "opacity-100 delay-300" : "opacity-0 delay-0"
This way, during both opening and closing transition, parent and child elements will have properly ordered animation.
Live demo is here: stackblitz
import React, { useState } from "react";
import "./App.css";
const list = ["Option 1", "Option 2", "Option 3", "Option 4", "Option 5"];
const ListItem = ({ open, text, index }) => {
return (
<li className={`bg-teal-100 h-12 flex justify-end`}>
<div
className={`${
open ? "w-24" : "w-12"
} flex justify-center align-center p-3 transition-all duration-300 ease-in-out`}
>
{index + 1}
</div>
<div
className={`${
open ? "opacity-100 delay-300" : "opacity-0 delay-0"
} flex justify-center align-center p-3 flex-1 transition-all duration-300 ease-in-out`}
>
{text}
</div>
</li>
);
};
const SlideDrawer = ({ open }) => {
return (
<div
className={`${
open ? "w-52 delay-0" : "w-12 delay-300"
} absolute left-0 top-0 bottom-0 transition-all duration-300 ease-in-out overflow-hidden flex justify-start bg-pink-200`}
>
<div className={`w-52 flex flex-col justify-start align-end`}>
<div
className={`${
open ? "w-52 p-6 delay-300" : "w-12 p-3 delay-0"
} h-72 flex flex-col justify-start align-center transition-all duration-300 ease-in-out `}
>
<figure
className={`${
open ? "w-40 h-40 delay-300" : "w-6 h-6 delay-0"
} transition-all bg-teal-100 rounded-full duration-300 ease-in-out`}
></figure>
</div>
<ul className="w-full flex flex-col list-none">
{list.map((item, index) => (
<ListItem key={item} open={open} index={index} text={item} />
))}
</ul>
</div>
</div>
);
};
function App() {
const [drawerOpen, setDrawerOpen] = useState(false);
return (
<>
<div className="w-full flex justify-end">
<button
className="m-6 p-3 rounded-lg bg-slate-300"
onClick={() => setDrawerOpen((prev) => !prev)}
>
Open drawer
</button>
</div>
<SlideDrawer open={drawerOpen} />
</>
);
}
export default App;

Navbar with Tailwind Hover Has Stopped Working

I've been building this navbar this week and seem to have the layout working for the most part. However there are a couple of little functionality issues I have run in to with the hover effect and the links for the menu items on the left and the logo in the middle.
For some reason when the menu is at its full width the hover stops working, but when I collapse it to the hamburger menu it works just fine. I'm not too sure what I've miss here, and would welcome and suggestions on what I've done wrong to stop the hover and the links from working.
The accented-pink color is a custom configured color in my tailwind.config.js file
Navbar.jsx
import Link from "next/link";
import { useState } from "react";
import React from "react";
import Logo from "../Logo";
import headerLogo from "../../assets/images/headerImages/phreaquencyLogoPink.png";
import { FiGithub, FiMail, FiTwitter } from "react-icons/fi";
const NewNavbarLogoCenter = () => {
const [active, setActive] = useState(false);
const handleClick = () => {
setActive(!active);
};
return (
<>
<nav className="flex flex-row w-screen bg-yellow-100">
<div className="fixed top-0 flex text-center pl-[5vw] pr-[5vw] md:pl-[1.5vw] md:pr-[1.5vw] lg:pt-[3vw] pb-9 lg:px-[1.5vw] z-50 text-xl w-full align-baseline pt-[5vw]">
<div className="lg:absolute flex lg:left-0 lg:right-0 z-10 lg:mx-auto lg:inline-block md:top-[3vw] md:left-[1.5vw] md:w-[calc(131px+3vw)] md:block">
<Link href="/">
<a>
{" "}
<Logo
logoSrc={headerLogo}
logoAltSrc="phreaquency logo"
logoLayout="intrinsic"
logoObjectFit="contain"
logoWidth="172px"
logoHeight="50px"
className="relative items-center "
/>
</a>
</Link>
</div>
<button
className="inline-flex p-3 ml-auto rounded outline-none hover:text-pink-accented lg:hidden"
onClick={handleClick}
>
<svg
className="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 6h16M4 12h16M4 18h16"
/>
</svg>
</button>
<div
className={`${
active ? "" : "hidden"
} w-full lg:inline-flex lg:flex-grow lg:w-auto`}
>
<div className="">
<div className="flex flex-col lg:flex-row lg:justify-start">
<div className="items-center justify-center w-full mr-3 lg:flex lg:w-auto hover:text-pink-accented">
<Link href="/">
<a>Agency</a>
</Link>
</div>
<div className="items-center justify-center w-full mr-3 lg:inline-flex lg:w-auto hover:text-pink-accented">
<Link href="/">
<a>Work</a>
</Link>
</div>
<div className="items-center justify-center w-full mr-3 lg:inline-flex lg:w-auto hover:text-pink-accented">
<Link href="/">
<a>Services</a>
</Link>
</div>
<div className="items-center justify-center w-full mr-3 lg:inline-flex lg:w-auto hover:text-pink-accented">
<Link href="/">
<a>Insights</a>
</Link>
</div>
<div className="items-center justify-center w-full mr-3 lg:inline-flex lg:w-auto hover:text-pink-accented">
<Link href="/">
<a>Contact</a>
</Link>
</div>
</div>
<div className="lg:absolute lg:top-0 lg:right-0 flex flex-row text-center pt-[6vw] lg:pt-[3vw] lg:pb-9 px-[1.5vw] z-50 text-xl lg:items-center lg:justify-end w-full justify-center items-center content-center">
<div className="flex items-center justify-center w-full mr-3 lg:inline-flex lg:w-auto hover:text-pink-accented">
<Link href="/">
<a>
<FiGithub />
</a>
</Link>
</div>
<div className="flex items-center justify-center w-full mr-3 lg:inline-flex lg:w-auto hover:text-pink-accented">
<Link href="/">
<a>
<FiTwitter />
</a>
</Link>
</div>
<div className="flex items-center justify-center w-full lg:inline-flex lg:w-auto hover:text-pink-accented">
<Link href="/">
<a>
<FiMail />
</a>
</Link>
</div>
</div>
</div>
</div>
</div>
</nav>
</>
);
};
export default NewNavbarLogoCenter;
tailwind.config.js
const defaultTheme = require("tailwindcss/defaultTheme");
module.exports = {
darkMode: "class", //remove this to have dark mode switch automatically
content: [
"./pages/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
"./layouts/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {
height: {
"50v": "50vh",
"60v": "60vh",
"70v": "70vh",
"80v": "80vh",
"90v": "90vh",
},
fontFamily: {
sans: ["Poppins", ...defaultTheme.fontFamily.sans],
},
colors: {
"off-white": "#f8f8ff",
"off-black": "#2e343b",
"pink-accented": "#ed61a2",
"section-overlay": "rgba(0,0,0, .2)",
},
},
},
plugins: [],
};
The accented colors are used with forms as tailwind docs says
so if you deleted the -accent and specify the degree of color after pink you should be good to go
hover:text-pink-500
Works for me.
wide screen
smaller screen
Maybe u could use the dev tools to see what's going on when u hover on wide screen.
Little advice, try to loop through the data in an array rather than writing the same code multiple times.
Here's how I test the code, hope it helps.
import React,{ useState } from "react";
const Navbar = () => {
const [active, setActive] = useState(false);
const handleClick = () => {
setActive(!active);
};
const links = [
{
name:'Agency',
url:'/',
},
{
name:'Work',
url:'/',
},
{
name:'Services',
url:'/',
},
{
name:'Insights',
url:'/',
},
{
name:'Contact',
url:'/',
},
]
return (
<>
<nav className="flex flex-row w-screen bg-yellow-100">
<div className="fixed top-0 flex text-center pl-[5vw] pr-[5vw] md:pl-[1.5vw] md:pr-[1.5vw] lg:pt-[3vw] pb-9 lg:px-[1.5vw] z-50 text-xl w-full align-baseline pt-[5vw]">
<div className="lg:absolute flex lg:left-0 lg:right-0 z-10 lg:mx-auto lg:inline-block md:top-[3vw] md:left-[1.5vw] md:w-[calc(131px+3vw)] md:block">
<a href="/">
logo
</a>
</div>
<button
className="inline-flex p-3 ml-auto rounded outline-none hover:text-pink-accented lg:hidden"
onClick={handleClick}
>
burgerbutton
</button>
<div className={`${
active ? "" : "hidden"
} w-full lg:inline-flex lg:flex-grow lg:w-auto`}>
<div className="">
<div className="flex flex-col lg:flex-row lg:justify-start">
{
links.map((link)=>{
return (
<div className="items-center justify-center w-full mr-3 lg:flex lg:w-auto hover:text-pink-accented">
<a href={link.url}>{link.name}</a>
</div>
)
})
}
</div>
</div>
</div>
</div>
</nav>
</>
);
};
export default Navbar;

CSS Flex - Set same width with TailwindCSS

I have the following React code (+Tailwind CSS):
<section className={"flex flex-col items-center"}>
{managers.map((manager) => (
<UserCard user={manager} />
))}
<section className={"flex flex-row"}>
{coWorkers.map((coWorker) => (
<UserCard user={coWorker} isMarked={user.id === coWorker.id} />
))}
</section>
{engineers.map((engineer) => (
<UserCard user={engineer} />
))}
</section>
While UserCard is simple as:
export default function Error({ user, isMarked }: Props) {
return (
<article
className={`bg-purple-500 shadow-lg m-3 p-3 text-white rounded-lg ${
isMarked && "border-4 border-purple-800 font-bold"
}`}
>
<h1>
{user.firstName} {user.lastName}
</h1>
<h2>{user.email}</h2>
</article>
);
}
The issue: the Cards are not in the same width, e.g:
Any idea how I can make sure they are in the same width using tailwindcss? (in each row/column)
You can specify a fix width to the main div
flex flex-col items-center w-1/3
Then for each child have full width
bg-purple-500 shadow-lg m-3 p-3 text-white rounded-lg w-full

Display Block not moving to next line

I'm trying to make a responsive nav bar with tailwind. I want to list my nav links with a single item in each row when I open the navigation menu. Right now, they are all on one row. I'm using tailwind:
function Navbar() {
const [isOpen, setIsOpen] = useState(false);
return (
<header>
<div className="flex flex-col max-w-screen-xl px-4 mx-auto md:items-center md:justify-between md:flex-row md:px-6 lg:px-8">
<div className="p-4 flex flex-row items-center justify-between">
<Link href="/">
<a className="text-lg font-semibold tracking-widest text-gray-900 uppercase rounded-lg dark-mode:text-white focus:outline-none focus:shadow-outline">
Header
</a>
</Link>
<button
className="md:hidden rounded-lg focus:outline-none focus:shadow-outline"
onClick={() => {
setIsOpen(!isOpen);
}}
>
Menu
</button>
</div>
<nav className={isOpen ? "flex" : "md:flex hidden"}>
<NavLink pathTo="/" displayText="Home" />
<NavLink pathTo="/" displayText="Page 1" />
<NavLink pathTo="/" displayText="Page 2" />
</nav>
</div>
</header>
);
}
export default Navbar;
My NavLink component is as follows:
import React from "react";
import Link from "next/link";
interface NavItem {
pathTo: string;
displayText: string;
}
function NavLink(item: NavItem) {
return (
<Link href={item.pathTo}>
<a className="block lg:p-4 px-4 py-2 mt-2 border-b-2 border-white text-sm bg-transparent dark-mode:bg-transparent dark-mode:hover:border-red-400 dark-mode:focus:border-red-400 dark-mode:focus:text-white dark-mode:text-gray-200 md:mt-0 md:ml-4 hover:text-gray-900 focus:text-gray-900 hover:border-red-400 focus:border-red-400">
{item.displayText}
</a>
</Link>
);
}
export default NavLink;
What am I missing? I want the NavLinks to have one item on each row when opened from the menu. I thought display:block would do it, but it seems not to. Why's that?
You need to add a flex direction to your nav links. Adding flex-col should do the trick.

Resources