DEV Community

Cover image for My First React Project(Part 2): Struggling with a Responsive Hero Section (CSS Lessons Learned)
Ayra Austine Baet
Ayra Austine Baet

Posted on

My First React Project(Part 2): Struggling with a Responsive Hero Section (CSS Lessons Learned)

In Part 1, I talked about building the header for the Frontend Mentor's Digital Bank Landing Page Challenge. At that point, I felt like I had momentum.

Then I met the Hero section... and yeah, it didn't go as smoothly as I expected.

This post is about that struggle, what went wrong, what I learned, and how I pushed through it. I'll also share a quick win with the Feature section that reminded me why I enjoy React.

Hero Section (a.k.a. where things got real)

At first, I thought:

"This is just a two-column layout. I've done this before. Easy"

It was not easy.

The JSX part? Totally fine. If you understand functional components in React, structuring this is pretty straightforward.

The real battle was CSS, specifically:

  • positioning
  • layering
  • responsiveness
  • making everything behave across screen sizes

I rewrote this section more times than I'd like to admit.

What Made It So Difficult?

The design doesn't look that complex, but under the hood:

  • There's an SVG background and a mockup image of four phones that need to be scaled and positioned correctly
  • The phones overlap the background
  • The layout changes depending on screen size
  • Elements behave differently across breakpoints

I ran into issues where:

  • Elements overlapped in unintended ways
  • Images were misaligned
  • Layouts looked fine on mobile but broke on desktop (and vice versa)
  • Overflow caused unwanted horizontal scrolling

What I Learned (The Hard Way)

1. Stop Hiding Image Elements in CSS

My first instinct was to use ::before pseudo-elements for decorative images.

It worked... until it didn't

I realized I needed full control over resizing, positioning, and layering across breakpoints. So, I made everything explicit in the markup:

.hero
 .hero__container
  .hero__visual
   .hero__bg-wrapper
    .hero__bg (SVG background)
   .hero__mockup (phone mockup)
  .hero__content (text + button)
Enter fullscreen mode Exit fullscreen mode

This made responsiveness much easier to manage.

2. Relative + Absolute Positioning = Power (and Pain)

This combo became the foundation of the layout:

.hero {
    position: relative; /* establishes positioning context */
    /* other hero styles */
}

@media (min-width: 1024px) {
    .hero__mockup {
        position: absolute;
        right: clamp(-120px, -8vw, -80px); /* positioning tweak */
        bottom: clamp(-110px, -8vw, -80px); /* positioning tweak */
        /* other hero__mockup styles */
    }
}
Enter fullscreen mode Exit fullscreen mode

Using position: absolute gave me precise control over layering and positioning. From there, I used the right and bottom properties to push the mockup slightly outside the hero section, though it involved a lot of trial and error.

3. clamp() Saved My Sanity

Fixed pixel values broke everything across screen sizes.

Switching to clamp() changed how I approached responsiveness:

.hero__mockup {
    /* positioning from earlier */
    width: clamp(280px, 75vw, 420px); /* responsive sizing */
    margin-top: clamp(-140px, 18vw, -110px); /* responsive sizing */
    /* other hero__mockup styles */
}

@media (min-width: 768px) {
    .hero__mockup {
        width: clamp(360px, 55vw, 520px); /* responsive sizing */
        margin-top: -clamp(150px, 20vw, 180px); /* responsive sizing */
    }
}

@media (min-width: 1024px) {
    .hero__mockup {
        /* positioning from earlier */
        right: clamp(-120px, -8vw, -80px); /* responsive offset */
        bottom: clamp(-110px, -8vw, -80px); /* responsive offset */
        width: clamp(540px, 45vw, 700px); /* responsive sizing */
    }
}
Enter fullscreen mode Exit fullscreen mode

Instead of chasing pixel-perfect values, I started thinking in terms of fluid scaling.

4. Use Grid (Only When It Makes Sense)

I didn't force CSS Grid everywhere.

I used it only where it helped.

@media (min-width: 1024px) {
    .hero__container {
        display: grid;
        grid-template-columns: 1fr 1.5fr;
        grid-template-areas: "content visual";
        /* other hero__container styles */
}
Enter fullscreen mode Exit fullscreen mode

A mobile-first + progressive enhancement approach worked much better.

5. Overflow Will Break Your Layout (If You Let It)

The mockup image needed to overflow, but the background shouldn't.

Here's what worked:

html, body {
    overflow-x: hidden;
}

.hero__bg-wrapper {
    overflow: hidden;
    /* other hero__bg-wrapper styles */
}
Enter fullscreen mode Exit fullscreen mode

Feature Section (Finally, A Win)

After the Hero section, the Feature section felt like a breath of fresh air.

Each feature shared the same structure:

  • icon
  • title
  • text

So instead of repeating markup, I used an array:

const features = [
    {
        id: 1,
        icon: onlineIcon,
        title: "Online Banking",
        text: "Our modern web and mobile applications allow you to keep track of your finances wherever you are in the world."
    },

    {
        id: 2,
        icon: budgetingIcon,
        title: "Simple Budgeting",
        text: "See exactly where your money goes each month. Receive notifications when you’re close to hitting your limits."
    },

    {
        id: 3,
        icon: onboardingIcon,
        title: "Fast Onboarding",
        text: "We don’t do branches. Open your account in minutes online and start taking control of your finances right away." 
    },

    {
        id: 4,
        icon: apiIcon,
        title: "Open API",
        text: "Manage your savings, investments, pension, and much more from one account. Tracking your money has never been easier."
    }
]
Enter fullscreen mode Exit fullscreen mode

Then mapped over it:

{features.map((feature) => (
    <div className="feature__item" key={feature.id}>
        <img className="feature__item-icon" src={feature.icon} alt="" />
            <h3>{feature.title}</h3>
            <p>{feature.text}</p>
    </div>
))}
Enter fullscreen mode Exit fullscreen mode

This reminded me why I enjoy React:

  • separating data from UI
  • building reusable patterns
  • using map() effectively

What This Project Taught Me

  • The Hero section isn't always the hardest part, CSS can be the real challenge
  • Positioning and scaling are just as important as component structure
  • React shines when handling repeated UI patterns

If you're also learning React and struggling with CSS, you're not alone. This part definitely tested me.

Feel free to check out the project on my Github repo: https://github.com/ayra-baet/bank-landing-page-react

What's Next?

In Part 3, I'll finish the landing page and hopefully break fewer things along the way.

Top comments (0)