Reputation: 1
I'm trying to recreate a navbar and hero section that I've seen in this website https://www.thetailorssonsf.com/ where the navbar and hero section seems to be equal to 100% of viewport height and is very responsive. However, I am experiencing the hero section/image to never fit into a section and instead it will be more than 100% of the view height. Im not the best at HTML and CSS but I am trying to implement this design to my own website using next.js, react, and tailwind css.
This is my navbar component:
useEffect(() => {
const handleScroll = () => {
if (window.scrollY > 0) {
setScrolled(true);
} else {
setScrolled(false);
}
};
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);
const handleMenu = () => {
setOpen(false);
};
return (
<nav className={`w-full flex items-center justify-between z-50 text-xl font-bold transition-all duration-300 ${scrolled ? "fixed top-0 p-5 text-black bg-white " : "absolute top-0 p-10 bg-white text-shadow text-black"}`}>
{/* Larger Screens */}
<Link href="/" className="hidden md:flex sm:mx-10">
LOGO
</Link>
<ul className="hidden sm:flex justify-end sm:mx-10 items-center">
{links.map((link, index) => (
<li key={index} className="sm:mx-5 py-5">
{link.label === "RESERVATIONS" ? (
<Link href={link.href} target="_blank" rel="noopener noreferrer" className="border border-black px-4 py-2 hover:bg-yellow-500 hover:text-white hover:transition-all hover:duration-300 ">{link.label}</Link>
) : (
<Link href={link.href} className="hover:text-gray-300 hover:transition-all hover:duration-300">{link.label}</Link>
)}
</li>
))}
</ul>
</nav>
Since I am using nextjs, I put the navbar in the layout directory of my src
folder so it persists in all of my pages.
I want my hero component to be reusable and used in several pages but not every page so i import it to the pages I use it in.
Here is my hero component:
<Slider {...settings}>
{images.map((img, index) => (
<div key={index} className="relative h-screen bg-cover bg-center">
<div className="absolute inset-0 bg-black bg-opacity-30 flex flex-col items-center justify-center">
<Image
src={`${carousel ? img : src}`}
alt="Hero Image"
layout="fill"
objectFit="cover"
className="-z-50"
/>
<div className="absolute inset-0 flex items-center justify-center">
<div
className="text-5xl font-bold text-center text-white overflow-hidden"
style={{ textShadow: "3px 3px 10px rgba(0, 0, 0, 0.5)" }}
>
{label}
</div>
</div>
</div>
</div>
))}
</Slider>
Now this is a page where I want the navbar and hero to be:
<section className="min-h-screen">
<Hero src="/Food1.jpg" label="Placeholder" carousel={true}/>
<section className="h-1/2 flex">
{... other data}
</section>
</section>
On the page I tried putting the navbar and hero into its own section but doesnt work.
<section>
<section className="h-screen">
<Navbar/>
<Hero src="/Food1.jpg" label="Placeholder" carousel={true}/>
</section>
{...other data}
</section>
I also tried taking out the hero component and just using a nextjs Image component. However this leads to the image being stretched more than 100vh and taking over other sections. Taking out the fill
property and giving the image a width and height wouldn't make it responsive like in the reference site.
<section>
<section className="h-screen">
<Navbar/>
<Image src='/Food1.jpg' fill objectFit="cover"/>
</section>
{...other data}
</section>
I feel like the problem has to do with the Hero/Image component. I cant configure it the way I want it to like in the reference site. Is there a solution?
Upvotes: 0
Views: 746
Reputation: 53
I don't know your full code, but let me try to get you on the right path. If you are looking to have the nav and hero take up the screen, they should be wrapped in a div with className="h-screen w-screen flex flex-col". You can then set your nav size to "h-[desired height] flex flex-row" and your hero size to "h-[desired height] flex flex-row". A few ways to do that. If you are adding your hero on select pages, I'd suggest wrapping your children in your layout like this:
<div className="h-screen w-screen flex flex-col">
<Nav />
{children}
</div>
This will allow you to have a Nav component on each page, and then the remainder can be filled by the page content. So, on each page where you have a hero component, you might wrap your hero like this:
<div className="flex flex-row h-full">
{heroContent ? heroContent : pageContent}
</div>
This will make the component fill the space. You could then make everything "h-full" all the way down. In fact, I'd probably suggest using Tailwind classes on your Image component like this:
<Image
src={HeaderImage}
quality={100}
alt="Header Image"
className="object-cover w-full h-full"
/>
The "layout" and "object-fit" params on the Image component have been removed in favor of using className or Style. I added flex-col on the wrapper div, and would suggest flex-row on the nav and header. Instead of 'h-full', you could also be more precise about the sizing of your nav and hero. Something like 'h-1/4', for example. However, this may depend on how you want that nav to look at certain break points.
Speaking of break points, I want to briefly address how you attempted to use them here, particularly this line:
<Link href="/" className="hidden md:flex sm:mx-10">
LOGO
</Link>
That "sm:mx-10" would work just the same if it was "md:mx-10" or even just "mx-10". Why? because there is no display until the md breakpoint is hit. Tailwinds "hidden" class is equivalent to CSS display: none, which removes the element from the dom. I point this out in case it's another point of pain for you. For Tailwind breakpoints, you will have a default, then the changes will happen once the screen size grows to the breakpoint. So, in your example above, you are saying "remove this completely until the screen size is md or above, then use display: flex and apply other styles."
Let me know if this helps, or if you want to chat more about it.
Upvotes: 0