htmlcssbackground-image

Background Image Gradient Stops a Pixel Short


const headerEl = document.querySelector('.header');

window.addEventListener('scroll', () => {
  if (window.scrollY > 50) {
    headerEl.classList.add('header-scrolled')
  } else if (window.scrollY <= 50) {
    headerEl.classList.remove('header-scrolled')
  }
});
/* Body */

body {
  margin: 0;
  padding: 0;
}

/* Header & Nav Bar */

.header {
  position: fixed;
  width: 100%;
  transition: all 0.2s;
}

.header-scrolled {
  background-color: #4B4A1E;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.15);
  border-bottom-left-radius: 15px;
  border-bottom-right-radius: 15px;
}

nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-left: 25px;
  padding-right: 35px;
}

nav img {
  width: 50px;
  padding: 8px;
}

nav ul {
  list-style: none;
}

nav ul li {
  display: inline-block;
}

nav ul li a {
  color: #C5C3C3;
  text-decoration: none;
  font-family: Arial, Helvetica, sans-serif;
  font-weight: bold;
  padding: 10px;
}

nav ul li a:hover {
  background-color: #79512E;
  border-radius: 8px;
}

.activenav {
  text-decoration: underline;
  text-decoration-color: #79512E;
  text-decoration-thickness: 3px;
  text-underline-offset: 3px;
}

.activenav:hover {
  text-decoration-color: #4B4A1E;
}



/* Hero Section */

.hero-image {
  background-image: linear-gradient(0deg, rgba(75, 74, 30, 1) 0%, rgba(255, 255, 255, 0) 70%, rgba(0, 0, 0, 0.75) 100%), url(Images/Headers/Header1.jpg);
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
  overflow: hidden;
  height: 80vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.hero-text {
  display: flex;
  flex-direction: column;
  align-items: center;
  color: #C5C3C3;
}

.hero-text h1 {
  font-family: Arial, Helvetica, sans-serif;
  font-weight: bold;
  font-size: 60px;
  margin-bottom: 0;
}

.hero-text p {
  font-family: Comfortaa, sans-serif;
  font-size: 25px;
}

.hero-text button {
  border-radius: 15px;
  border: none;
  background-color: #79512E;
  height: 40px;
  width: 250px;
  color: #C5C3C3;
  font-family: Arial, Helvetica, sans-serif;
  font-weight: bolder;
}



/* Shopping Perks Section */

.shoppingperk {
  background-color: #4B4A1E;
}

.perkrow {
  background-color: #4B4A1E;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 100px;
  height: 120px;

}

.perk {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 70px;
  width: 300px;
  background-color: #C5C3C3;
  border-radius: 15px;
}
<header class="header">
  <nav>
    <a href="index.html"><img src="Images/Brand/Logo.png" alt="Bloom Valley Nursery Logo"></a>
    <ul>
      <li><a href="index.html" class="activenav">Home</a></li>
      <li><a href="gallery.html">Shop</a></li>
      <li><a href="about.html">About Us</a></li>
      <li><a href="community.html">Community</a></li>
    </ul>
  </nav>
</header>
<section id="hero">
  <div class="hero-image">
    <div class="hero-text">
      <h1>Bloom Vallery Nursery</h1>
      <p>Rooted in Nature. Grown with Care.</p>
      <button>Shop Now</button>
    </div>
  </div>
</section>
<section class="shoppingperk">
  <div class="perkrow">
    <div class="perk">
      <p><i class="fa-solid fa-seedling"></i><span style="padding-left: 10px;">Eco-Conscious from Root to Leaf.</span></p>
    </div>
    <div class="perk">
      <p><i class="fa-solid fa-trowel"></i><span style="padding-left: 10px;">Expert Grown. Garden-Ready.</span></p>
    </div>
  </div>
</section>

I am building my first HTML/CSS/JavaScript project for my Web Development class. I have been learning a lot and thoroughly enjoy the problem-solving aspect of figuring out why things don't work and how to fix it. But this one issue currently has me stumped.

My hero image has a linear gradient applied over it. The gradient seems to stop a pixel short from the bottom of the image. At first, I thought it was a space between the hero section, and the section following it, but after deeper investigation, I realized it is the gradient stopping short as I can see details of the image in that strip. If I remove the gradient, the hero section and the section below it are touching.

Line With Image and Gradient

Line Without Image

No Gradient and No Line

/* Hero Section */

.hero-image {
    background-image: linear-gradient(0deg,rgba(75, 74, 30, 1) 0%, rgba(255, 255, 255, 0) 70%, rgba(0, 0, 0, 0.75) 100%), url(Images/Headers/Header1.jpg);
    background-size: cover;
    background-repeat: no-repeat;
    background-position: center center;
    overflow: hidden;
    height: 80vh;
    display: flex;
    justify-content: center;
    align-items: center;
}

.hero-text {
    display: flex;
    flex-direction: column;
    align-items: center;
    color: #C5C3C3;
}

.hero-text h1 {
    font-family: Arial, Helvetica, sans-serif;
    font-weight: bold;
    font-size: 60px;
    margin-bottom: 0;
}

.hero-text p {
    font-family: Comfortaa, sans-serif;
    font-size: 25px;
}

.hero-text button {
    border-radius: 15px;
    border: none;
    background-color: #79512E;
    height: 40px;
    width: 250px;
    color: #C5C3C3;
    font-family: Arial, Helvetica, sans-serif;
    font-weight: bolder;
}

I tried adding an additional step to the gradient with no change:

.hero-image {
    background-image: linear-gradient(0deg,rgba(75, 74, 30, 1) 0%, rgba(75, 74, 30, 1) 1% rgba(255, 255, 255, 0) 70%, rgba(0, 0, 0, 0.75) 100%), url(Images/Headers/Header1.jpg);
    background-size: cover;
    background-repeat: no-repeat;
    background-position: center center;
    overflow: hidden;
    height: 80vh;
    display: flex;
    justify-content: center;
    align-items: center;
}

Before realizing that it was the gradient not extending all the way, I was also messing with the margins and padding of neighboring elements with no success.


Solution

  • It was interesting to look into your question. It seems like the issue comes from how the CSS background-image property works when combining a gradient and an image.

    Browsers handle gradients and images slightly differently, especially when it comes to pixel alignment. On high-resolution screens (like Retina displays), even a 1-pixel difference can show up due to how CSS pixels are scaled and rounded to actual screen pixels.

    Here are two ways to fix it:

    1. Use background-attachment: fixed;

    This can solve the problem if it fits your layout. It makes the background stay fixed relative to the viewport, which can help avoid rounding issues.

    1. Use a ::before pseudo-element for the gradient

    This method separates the gradient from the background image, which gives you more control and avoids the mismatch. Here's an example:

    .hero-image {
      position: relative;
      height: 80vh;
      background: url('Images/Headers/Header1.jpg') center center / cover no-repeat;
      overflow: hidden;
    }
    
    .hero-image::before {
      content: "";
      position: absolute;
      inset: 0;
      background: linear-gradient(0deg, rgba(75, 74, 30, 1) 0%, rgba(255, 255, 255, 0) 70%, rgba(0, 0, 0, 0.75) 100%);
      z-index: 1;
      pointer-events: none;
      mix-blend-mode: overlay;
    }