5

What I'm trying to do, is to create several colored boxes which are aligned horizontally.

<div class="outer">
  <div class="bg bg1">
  </div>
  <div class="bg bg2">
  </div>
  <div class="bg bg3">
  </div>
  <div class="bg bg4">
  </div>
</div>

--> complete code on Codepen


several facts:

  1. outer's position : relative
  2. bg's position : absolute
  3. left of bg1 to bg4 are different

If I set the width of "outer" to 100vw, everything will be fine.

But if it's greater than 100vw, for example 101vw, there will be a little extra space I can scroll down(strangely, there is no vertical scrollbar).

And if it's 300vw, where I can see three boxes from left to right, the vertical scrollbar will appear.


So my question is:

How come the width will affect the vertical scrollbar?

And if can't avoid that, is there any other way of implementing my idea? (I guess creating several divs is not a good way)

squiiiid
  • 93
  • 7
  • 2
    The lack of a vertical scrollbar when you change from 100vw to 101vw seems like a bug, because it appears at 102vw and changing back to 101vw keeps it there. That aside, the vertical scrollbar appears because the horizontal one takes up space when it appears. – Niet the Dark Absol Aug 02 '18 at 14:15
  • 2
    vh and vw includes the scroll bar height/width ... so if the scroll apper horizontally you will create the vertical one – Temani Afif Aug 02 '18 at 14:19

2 Answers2

2

The viewport unit are relative to the viewport so if a horizontal scroll bar appear it means that this scroll bar will take space thus we need the vertical scroll in order to see the part hidden by the horizontal one.

To avoid this keep using only the vw unit and use % instead of vh so the height will be relative to the parent instead of the viewport. I have also removed the margin and adjusted the top and left values to make the block centred

* {
  padding: 0;
  margin: 0;
}

body,
html {
  height: 100%;
}

.outer {
  position: relative;
  top: 0;
  left: 0;
  height: 100%;
  width: 105vw; /* This won't create a vertical scroll*/
  overflow: hidden;
  background-color: lightyellow;
}

.bg {
  height: 80%;
  width: 80vw;
  top: 50%;
  transform: translateY(-50%);
  position: absolute;
}

.bg1 {
  background-color: #80c9be;
  left: 10vw;
}

.bg2 {
  background-color: #e99790;
  left: 110vw;
}

.bg3 {
  background-color: #f2e2cd;
  left: 210vw;
}

.bg4 {
  background-color: #48697f;
  left: 310vw;
}
<div class="outer">
  <div class="bg bg1">
  </div>
  <div class="bg bg2">
  </div>
  <div class="bg bg3">
  </div>
  <div class="bg bg4">
  </div>
</div>

In case you need a better way you can use flexbox like this:

* {
  padding: 0;
  margin: 0;
}

body,
html {
  height: 100%;
}

.outer {
  position: relative;
  height: 100%;
  display:flex;
  background-color: lightyellow;
}

.bg {
  height: 80%;
  width: 80vw;
  margin:auto 10vw;
  flex-shrink:0;
}

.bg1 {
  background-color: #80c9be;
}

.bg2 {
  background-color: #e99790;
}

.bg3 {
  background-color: #f2e2cd;
}

.bg4 {
  background-color: #48697f;
}
<div class="outer">
  <div class="bg bg1">
  </div>
  <div class="bg bg2">
  </div>
  <div class="bg bg3">
  </div>
  <div class="bg bg4">
  </div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Thanks it really helps me a lot. But why `top: 50%` and `transform: translateY(-50%)` instead of just `top:10%` ? Is it because it's more semantic? (I'm not sure if it's the right way to use this word, semantic, haha) – squiiiid Aug 02 '18 at 14:56
  • 1
    @squiiiid you are right both are the same in this case, but to be more generic and precise it's better use top:50% with translate to center for all the height in case you will change the height later – Temani Afif Aug 02 '18 at 14:59
1

As has been said in the comments, the vertical scrollbar is due to vw and vh including the scrollbar. If you use 100% on body, html instead, you get the same effect without the scrollbar appearing.

* {
  padding: 0;
  margin: 0;
}

body,
html {
  height: 100%;
}

.outer {
  position: relative;
  top: 0;
  left: 0;
  padding: 0;
  margin: 0;
  height: 100%;
  width: 300vw;
  /*try modifying the width with larger value*/
  overflow: hidden;
  background-color: lightyellow;
}

.bg {
  margin: 10vh 10vw;
  height: 80%;
  width: 80vw;
  top: 0;
  position: absolute;
}

.bg1 {
  background-color: #80c9be;
  left: 0;
}

.bg2 {
  background-color: #e99790;
  left: 100vw;
}

.bg3 {
  background-color: #f2e2cd;
  left: 200vw;
}

.bg4 {
  background-color: #48697f;
  left: 300vw;
}
<div class="outer">
  <div class="bg bg1">
  </div>
  <div class="bg bg2">
  </div>
  <div class="bg bg3">
  </div>
  <div class="bg bg4">
  </div>
</div>
Maharkus
  • 2,841
  • 21
  • 35