2

I don't do frontend but currently we have a requirement for a header component where we need to overlay a non-rectangular bar with an inset image over the hero image. Here is an example of what I'm talking about:

enter image description here

I've got a working proof of concept by layering 3 divs, but I think it's janky and I'm looking for advice on best practice on how to best take advantage of CSS for what I'm trying to achieve.

I've put together a quick codepen with holder images to show the proof of concept, any help would be greatly appreciated

https://codepen.io/anon/pen/zQvjBP

html:

 <div id="content">
  <div id="innerTop"></div>
  <div id="thing"></div>
  <div id="thing2"/>
</div>

CSS:

#content {
  background-image:url("https://iep.challenges.org/wp-content/uploads/sites/26/2015/11/header-image-5.jpg");
  height:500px;
}

#thing {
  width:100%;
  height:30%;
  background-color:rgba(215, 217, 221, .9);
}

#thing2 {
  margin: 0 auto;
  width:300px;
  height:8em;
  background-color:rgba(215, 217, 221, .9);
  border-radius:0 0 25px 25px;
}
#innerTop {
  float:left;
  width:100%;
  height:100%;
  background-image: url('https://www.freelogodesign.org/Content/img/logo-ex-3.png');
  background-repeat: no-repeat;
  background-position: top; 
  background-size: 300px 300px;
}
salty
  • 594
  • 4
  • 6
  • 18

3 Answers3

2

This flexbox approach may be better than the floats.

#content {
  background-image:url("https://iep.challenges.org/wp-content/uploads/sites/26/2015/11/header-image-5.jpg");
  height:500px;
}
.logobar {
  height: 278px;
  display: flex;
}
.logobar-side {
  flex: 1 0 auto;
  background-color: rgba(215, 217, 221, .9);
  height: 150px;
}
.logobar-logo {
  flex: 0 0 300px;
  background-color: rgba(215, 217, 221, .9);
  border-radius: 0 0 25px 25px;
}
 <div id="content">
  <div class="logobar">
    <div class="logobar-side"></div>
    <div class="logobar-logo">
      <img class="logo" src="https://www.freelogodesign.org/Content/img/logo-ex-3.png" />
    </div>
    <div class="logobar-side"></div>
  </div>
</div>
BugsArePeopleToo
  • 2,976
  • 1
  • 15
  • 16
  • nice approach! It still has some layout markup but it is an elegant solution to avoid the half-height background under the logo – ludovico May 08 '19 at 21:28
2

You can have all this using one element and multiple background (without the radius)

#content {
  background:
    /* Gradient or image                                              position / size*/
    url('https://www.freelogodesign.org/Content/img/logo-ex-3.png')  top center/300px 300px,
    linear-gradient(rgba(215, 217, 221, .9),rgba(215, 217, 221, .9)) 50% 150px /300px 8em,
    linear-gradient(rgba(215, 217, 221, .9),rgba(215, 217, 221, .9)) top       /100% 150px,
    url("https://iep.challenges.org/wp-content/uploads/sites/26/2015/11/header-image-5.jpg") center/cover;
  background-repeat:no-repeat;
  height:500px;
}
<div id="content">
 
</div>

With radius you can add more layers:

#content {
  background:
    url('https://www.freelogodesign.org/Content/img/logo-ex-3.png') top center/300px 300px,
    
    linear-gradient(rgba(215, 217, 221, .9),rgba(215, 217, 221, .9)) 50% 150px/300px 7em,
    
    linear-gradient(rgba(215, 217, 221, .9),rgba(215, 217, 221, .9)) 50% calc(150px + 7em)/250px 25px,
    radial-gradient(circle at top right,rgba(215, 217, 221, .9) 24px,transparent 25px) calc(50% - 150px + 12.5px) calc(150px + 7em)/25px 25px,
    radial-gradient(circle at top left ,rgba(215, 217, 221, .9) 24px,transparent 25px) calc(50% + 150px - 12.5px) calc(150px + 7em)/25px 25px,
    
    linear-gradient(rgba(215, 217, 221, .9),rgba(215, 217, 221, .9)) top/100% 150px,
    url("https://iep.challenges.org/wp-content/uploads/sites/26/2015/11/header-image-5.jpg") center/cover;
  background-repeat:no-repeat;
  height:500px;
}
<div id="content">
 
</div>

To better understand the layout give a different color to each gradient and it will be easy to identify them:

#content {
  background:
    url('https://www.freelogodesign.org/Content/img/logo-ex-3.png') top center/300px 300px,
    
    linear-gradient(red,red) 50% 150px/300px 7em,
    
    linear-gradient(green,green) 50% calc(150px + 7em)/250px 25px,
    radial-gradient(circle at top right,blue 24px,transparent 25px) calc(50% - 150px + 12.5px) calc(150px + 7em)/25px 25px,
    radial-gradient(circle at top left ,purple 24px,transparent 25px) calc(50% + 150px - 12.5px) calc(150px + 7em)/25px 25px,
    
    linear-gradient(yellow,yellow) top/100% 150px,
    url("https://iep.challenges.org/wp-content/uploads/sites/26/2015/11/header-image-5.jpg");
  background-repeat:no-repeat;
  height:500px;
}
<div id="content">
 
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Thank you! I especially appreciate the colored sections snippet, that really helped me to understand how this is built. If I begin modifying sizes (moving up, down, shrinking, etc) is it correct that I would need to adjust the calc numbers accordingly? For example if I shrink the height of the yellow bar by 20%, I'd adjust all the other calcs for the 20% shift? – salty May 09 '19 at 01:51
  • @salty yes exactly, if you change one value you need to adjust all of them, this is the tricky part here and you need to pay attention to pixel versus percentage value as they don't behave the same. Here is a good reading to better understand how everything work: https://stackoverflow.com/a/51734530/8620333 – Temani Afif May 09 '19 at 09:33
1

You're taking a good approach. The main challenge here is to prevent the background of the logo from overlapping with the background of the horizontal bar at the top.

You can avoid unnecessary markup, using CSS pseudoelements (before/after).

Also, you can use this technique to center align with position:absolute + transform:translateX()

#content {
  background-image:url("https://iep.challenges.org/wp-content/uploads/sites/26/2015/11/header-image-5.jpg");
  height:500px;
  position: relative;
}

#logo img {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  background-color:rgba(215, 217, 221, .9);
  border-radius:0 0 25px 25px;
}

#logo:before, #logo:after {
  content: "";
  display: block;
  height: 150px;
  width: calc(50% - 150px);
  position: absolute;
  top: 0;
  background-color:rgba(215, 217, 221, .9);
}
#logo:before {
  left: 0;
}
#logo:after {
  right: 0;
}
<div id="content">
  <div id="logo">
  <img src="https://www.freelogodesign.org/Content/img/logo-ex-3.png" alt="Company name"/>
  </div>
</div>

To avoid the different backgrounds overlapping, the logo container has two pseudoelements (:before and :after), one on each side of the logo.

The width of those is calculated using calc(): width: calc(50% - 150px); (see browser support here)

CodePen: https://codepen.io/anon/pen/wbKROz

ludovico
  • 2,103
  • 1
  • 13
  • 32