1

I wonder if it's possible to have a div stretch to 100vw, while being inside a relative parent div with limited width. And in the process also not losing it's height inside the document, as it would when setting position to absolute.

Is it possible with pure css? Or do I need some jQuery / JS?

body {
  background: #f0f0f0;
  text-align: center;
}

.parent {
  max-width: 300px;
  height: 300px;
  margin: auto;
  position: relative;
  background: white;
}

p {
  padding: 20px;
}

#banner {
  padding: 20px;
  background: black;
  color: white;
}
<div class="parent">
  <p>My relative parent container,<br>with a fixed width.</p>
  <div id="banner">
    My full width banner
  </div>
  <p>...</p>
</div>

Anyone has any experience in getting this to work? Any and all tips are much appreciated. Thanks!

TVBZ
  • 564
  • 1
  • 4
  • 15

2 Answers2

2

Yes, you can use 100vw width. To correct the position, you can add margin-left: calc(-50vw + 50%);, which moves it half of the screen width to the left and then back 50% of its own width to the right, thereby "centering" it again, which in this case results in a full-width element:

body {
  background: #f0f0f0;
  text-align: center;
}

.parent {
  max-width: 300px;
  height: 300px;
  margin: auto;
  position: relative;
  background: white;
}

p {
  padding: 20px;
}

#banner {
  padding: 20px;
  background: black;
  color: white;
  width: 100vw;
  margin-left: calc(-50vw + 50%);
}
<div class="parent">
  <p>My relative parent container,<br>with a fixed width.</p>
  <div id="banner">
    My full width banner
  </div>
  <p>...</p>
</div>

There is one problem remaining however: As soon as the contents are longer than the window height, a horizontal scrollbar will appear. I previously brought up that problem in this question, but I haven't really found a solution or got a satisfying answer for it.

Johannes
  • 64,305
  • 18
  • 73
  • 130
  • Aahhh... Such elegant and simple solution. Many thanks @Johannes ! :) Too bad about the horizontal scrollbar. – TVBZ Feb 12 '20 at 02:09
  • I read your post, interesting! I guess I will just ad `body{overflow-x: hidden}` untill a better solution is found. – TVBZ Feb 12 '20 at 02:22
  • 1
    Adding this codepen as additional reference: https://codepen.io/bassplayer7/pen/egZKpm. If offers a solution using some JavaScript. – TVBZ Feb 13 '20 at 12:39
  • @TVBZ That's a very cool patch you made there - thanks for sharing that! Although I really would like to find a CSS-only solution for this problem (which however is probably impossible), this is a great way to work around that problem. – Johannes Feb 14 '20 at 15:58
  • Some credit goes to the author @bassplayer7 offcourse :) I would also prefer pure css. But for now, this will have to do :) – TVBZ Feb 15 '20 at 19:21
1

I use relative with margin and left right to achieve this

body {
  background: #f0f0f0;
  text-align: center;
  overflow: hidden;
}

.parent {
  max-width: 300px;
  height: 300px;
  margin: auto;
  position: relative;
  background: white;
}

p {
  padding: 20px;
}

#banner {
  padding: 20px;
  background: black;
  color: white;
  width: 100vw;
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
}
<div class="parent">
  <p>My relative parent container,<br>with a fixed width.</p>
  <div id="banner">
    My full width banner
  </div>
  <p>...</p>
</div>

Reference

Awais
  • 4,752
  • 4
  • 17
  • 40
  • That's also an interesting and elegant approach. It has the same results as Johannes his example. And you hide horizontal scrollbar by setting `overflow-x: hidden`? Or do you have any other suggestions for that? – TVBZ Feb 13 '20 at 08:08
  • @TVBZ Yes I agree, As `body` and `HTML` dont need to scroll – Awais Feb 13 '20 at 08:45