nextui
nextui copied to clipboard
[BUG] - CardHeader z-index =10 by default
NextUI Version
2.4.1
Describe the bug
It is weird that CardHeader is the only component to my knowledge to have a z-index of 10. CardBody doesn't and behaves as expected, but not CardHeader as you can see in this screenshot :
I cloned nextui and think I found it there :
Your Example Website or App
No response
Steps to Reproduce the Bug or Issue
- Create a sticky header with z-index = 2
- Create a scrollable column that is supposed to go under the header
- Add cards with a CardHeader and whatever you want in it to the column
- Scroll and watch the CardHeader be visible on top of the sticky header
Expected behavior
As a developer, I expect the CardHeader to behave like CardBody or CardFooter, and not having a different z-index
Screenshots or Videos
No response
Operating System Version
WSL
Browser
Chrome
Hi @AntoineArt, are you using NextUI's Navbar component?
The top bar is indeed a navbar component, therefore it is even weirder that a CardHeader can be displayed on top of it
Hi @AntoineArt,
I am unable to reproduce this issue on my end, have you added any custom styling to your card header, can you please share the minimal code to reproduce the issue.
Hi @alphaxek here is a minimal example : app/temp/page.js :
import { Content } from '@/components/temp/content';
const Temp = () => {
return <Content />;
};
export default Temp;
components/temp/content.js :
'use client';
import {
Card,
CardBody,
CardHeader,
Input,
Navbar,
NavbarContent,
} from '@nextui-org/react';
export const Content = () => {
return (
<div className='h-screen overflow-auto'>
<div className='sticky top-0 z-[0]'>
<Navbar
isBordered
className='w-full'
classNames={{
wrapper: 'w-full max-w-full',
}}
>
<NavbarContent className='w-full max-md:hidden'>
<Input
isClearable
className='w-full todo relative'
classNames={{
input: 'w-full',
mainWrapper: 'w-full',
}}
placeholder='Rechercher...'
/>
</NavbarContent>
</Navbar>
</div>
<div className='flex flex-col max-w-[500px]'>
{Array(20)
.fill(0)
.map((_, i) => (
<Card key={i}>
<CardHeader>This is a header</CardHeader>
<CardBody>Content</CardBody>
</Card>
))}
</div>
</div>
);
};
I invite you to change "z-[0]" to z-[1 to 10] then z-[11], you will see that :
- With z-[0] : The cards appear completely over the navbar
- With z-[1 to 10] : Only the Cardheader's content appears over the navbar
- With z-[11] : The cards are (as initially intended), totally under the navbar
Here's a link to a video if needed : https://sharing.clickup.com/clip/p/t4510566/26d0e2ba-83c7-4727-9e9e-e051703c3803/screen-recording-2024-06-12-11%3A45.webm
I find it very weird that cardheader is not treated the same way as a cardbody. I struggle finding a use case for that. I think the default should be z-0, which would be optimal 99% of the time, and that wouldn't prevent me from tuning z-index manually if I really need to.
Hi @AntoineArt,
I would suggest to have correct layout and segregated components, having correct layout and structure helps in lot of areas like debugging.
Please refer this sample link: https://codesandbox.io/s/nervous-waterfall-4hmmly
My Sample Test:
Code:
import React from "react";
import {
Navbar,
NavbarBrand,
NavbarContent,
NavbarItem,
Link,
Button,
Card,
CardHeader,
CardBody,
Image,
} from "@nextui-org/react";
import { AcmeLogo } from "./AcmeLogo.jsx";
export default function App() {
return (
<div className="relative flex flex-col h-screen w-screen dark">
<Navbar>
<NavbarBrand>
<AcmeLogo />
<p className="font-bold text-inherit">ACME</p>
</NavbarBrand>
<NavbarContent className="hidden sm:flex gap-4" justify="center">
<NavbarItem>
<Link color="foreground" href="#">
Features
</Link>
</NavbarItem>
<NavbarItem isActive>
<Link href="#" aria-current="page">
Customers
</Link>
</NavbarItem>
<NavbarItem>
<Link color="foreground" href="#">
Integrations
</Link>
</NavbarItem>
</NavbarContent>
<NavbarContent justify="end">
<NavbarItem className="hidden lg:flex">
<Link href="#">Login</Link>
</NavbarItem>
<NavbarItem>
<Button as={Link} color="primary" href="#" variant="flat">
Sign Up
</Button>
</NavbarItem>
</NavbarContent>
</Navbar>
<main>
<section className="flex flex-col items-center justify-center gap-4 py-8 md:py-10">
<Card className="py-4">
<CardHeader className="pb-0 pt-2 px-4 flex-col items-start">
<p className="text-tiny uppercase font-bold">Daily Mix</p>
<small className="text-default-500">12 Tracks</small>
<h4 className="font-bold text-large">Frontend Radio</h4>
</CardHeader>
<CardBody className="overflow-visible py-2">
<Image
alt="Card background"
className="object-cover rounded-xl"
src="https://nextui.org/images/hero-card-complete.jpeg"
width={270}
/>
</CardBody>
</Card>
<Card className="py-4">
<CardHeader className="pb-0 pt-2 px-4 flex-col items-start">
<p className="text-tiny uppercase font-bold">Daily Mix</p>
<small className="text-default-500">12 Tracks</small>
<h4 className="font-bold text-large">Frontend Radio</h4>
</CardHeader>
<CardBody className="overflow-visible py-2">
<Image
alt="Card background"
className="object-cover rounded-xl"
src="https://nextui.org/images/hero-card-complete.jpeg"
width={270}
/>
</CardBody>
</Card>
<Card className="py-4">
<CardHeader className="pb-0 pt-2 px-4 flex-col items-start">
<p className="text-tiny uppercase font-bold">Daily Mix</p>
<small className="text-default-500">12 Tracks</small>
<h4 className="font-bold text-large">Frontend Radio</h4>
</CardHeader>
<CardBody className="overflow-visible py-2">
<Image
alt="Card background"
className="object-cover rounded-xl"
src="https://nextui.org/images/hero-card-complete.jpeg"
width={270}
/>
</CardBody>
</Card>
</section>
</main>
</div>
);
}
import React from "react";
import ReactDOM from "react-dom/client";
import { NextUIProvider } from "@nextui-org/react";
import App from "./App";
import "./styles.css";
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<NextUIProvider>
<div className="w-screen h-screen flex items-start justify-center overflow-y-scroll">
<App />
</div>
</NextUIProvider>
</React.StrictMode>,
);
Thanks for your answer but I am not beginning a new project, the product I'm working on is already 18 months in the development and my example was of course a minimal working example. As you know real world applications often cannot purely stick to a template due to incremental changes in scope and requirements.
Also whatever structure is used, it doesn't explain why there is a fixed z-10 in the code as my original post mentioned :
Hi @AntoineArt,
Try this, I just merged your code, made minor changes
Note: By default Navbar is sticky so you can avoid that
'use client';
import {
Card,
CardBody,
CardHeader,
Input,
Navbar,
NavbarContent,
} from '@nextui-org/react';
export const Content = () => {
return (
<div className="relative flex flex-col h-screen w-screen dark">
<Navbar isBordered position="sticky">
<NavbarContent>
<NavbarItem className="w-full">
<Input
isClearable
className="todo relative"
placeholder="Rechercher..."
/>
</NavbarItem>
</NavbarContent>
</Navbar>
<section className="flex flex-col items-center justify-center gap-4 py-8 md:py-10">
{Array(10)
.fill(0)
.map((_, i) => (
<Card key={i}>
<CardHeader>This is a header</CardHeader>
<CardBody>Content</CardBody>
</Card>
))}
</section>
</div>
);
};
import React from "react";
import ReactDOM from "react-dom/client";
import { NextUIProvider } from "@nextui-org/react";
import App from "./App";
import "./styles.css";
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<NextUIProvider>
<div className="w-screen h-screen flex items-start justify-center overflow-y-scroll">
<App />
</div>
</NextUIProvider>
</React.StrictMode>
);
Visual:
Hi, I was able to reproduce the issue in the sandbox : https://codesandbox.io/p/devbox/affectionate-bhaskara-8855xt
The problem only seem to be visible when the navbar has a z-index of exactly 10
Hi @Cajuteq, did you change the z-index of Card component's header?
Hi @alphaxek, I didn't change the z-index of anything in the Card.
As visible in the demo link, the Card, CardHeader and CardBody have no additionnal classes
and no custom CSS.
@AntoineArt I'm curious why you need to add an extra wrapper here. <Navbar /> has z-index=40 and by default it is sticky.
<div className='sticky top-0 z-[0]'>
<Navbar
isBordered
className='w-full'
classNames={{
wrapper: 'w-full max-w-full',
}}
>
<NavbarContent className='w-full max-md:hidden'>
<Input
isClearable
className='w-full todo relative'
classNames={{
input: 'w-full',
mainWrapper: 'w-full',
}}
placeholder='Rechercher...'
/>
</NavbarContent>
</Navbar>
</div>
Demo: Sticky default navbar + card