1

I'm trying to set up a page layout with flexbox such as the one illustrated here: https://jsfiddle.net/axedre/o6xw7pfg/, but I can't figure out why the .main div (as per the example) does not add padding to the right of the .content div when the latter grows beyond allotted space.
You can see what I mean by un-commenting line 30 in the SCSS section of the fiddle and scrolling the .main div all the way to the right.
Even if I remove the padding property from .main and add the same values to a margin property on .content I can't get the desired result, which is to have a space on the right-hand side of .content even when one scrolls to the right end of .main.
Any help is greatly appreciated, cheers!

Asons
  • 84,923
  • 12
  • 110
  • 165
Andrea Aloi
  • 971
  • 1
  • 17
  • 37

2 Answers2

2

Here is a simple fix for that, where to make .content display as inline-block and use margin instead of padding

This works on Firefox, Edge, IE11, but not on Chrome. Luckily though, by simply add a padding, e.g. padding-right: 0.1px;, to .main fixes that.

Updated fiddle

Stack snippet

body,
html {
  height: 100%;
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 0;
  margin: 0;
}

.top {
  border: 2px solid lime;
  display: flex;
  flex: 1;
}
.top .firstcol {
  border: 1px solid red;
  display: flex;
  flex-direction: column;
  overflow: auto;
}
.top .firstcol .header {
  border: 1px solid yellow;
}
.top .firstcol .main {
  border: 1px solid navy;
  flex: 1;
  padding-right: 0.1px;                   /*  fix for Chrome  */
  overflow: auto;
}
.top .firstcol .main .content {
  display: inline-block;                  /*  added  */
  margin: 1rem 2rem;                      /*  added here as margin instead  */
  border: 2px solid maroon;
  width: 1000px;
}

.top .firstcol .footer {
  border: 1px solid magenta;
}
.top .secondcol {
  border: 1px solid red;
}
.top .secondcol .othercontent {
  border: 1px solid yellow;
  width: 350px;
}
<div class="top">
  <div class="firstcol">
    <div class="header">header</div>
    <div class="main">
      <div class="content">content</div>
    </div>
    <div class="footer">
      <code>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</code>
    </div>
  </div>
  <div class="secondcol">
    <div class="othercontent">fixed</div>
  </div>
</div>

Another solution would be to add an extra wrapper, displayed as inline-block, which might be more hack free than the previous.

Updated fiddle 2

Stack snippet 2

body,
html {
  height: 100%;
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 0;
  margin: 0;
}

.top {
  border: 2px solid lime;
  display: flex;
  flex: 1;
}
.top .firstcol {
  border: 1px solid red;
  display: flex;
  flex-direction: column;
  overflow: auto;
}
.top .firstcol .header {
  border: 1px solid yellow;
}
.top .firstcol .main {
  border: 1px solid navy;
  flex: 1;
  overflow: auto;
}
.top .firstcol .main .fix-right-margin {
  display: inline-block;
}
.top .firstcol .main .content {
  border: 2px solid maroon;
  width: 1000px;
  margin: 1rem 2rem;
}

.top .firstcol .footer {
  border: 1px solid magenta;
}
.top .secondcol {
  border: 1px solid red;
}
.top .secondcol .othercontent {
  border: 1px solid yellow;
  width: 350px;
}
<div class="top">
  <div class="firstcol">
    <div class="header">header</div>
    <div class="main">
      <div class="fix-right-margin">
        <div class="content">content</div>
      </div>
    </div>
    <div class="footer">
      <code>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</code>
    </div>
  </div>
  <div class="secondcol">
    <div class="othercontent">fixed</div>
  </div>
</div>
Asons
  • 84,923
  • 12
  • 110
  • 165
  • Actually, just setting `display: inline-block` to `.content` and leaving everything else as-is (padding on `.main` and no margin on `.content`) fixes the problem and is hack-free! See updated fiddle: https://jsfiddle.net/axedre/597tn4oo/3/, great idea! Thanks! – Andrea Aloi Jan 29 '18 at 07:27
  • P.S. Works on Chrome 64, by the way! – Andrea Aloi Jan 29 '18 at 07:28
  • @AndreaAloi Yes, but that doesn't work on Firefox and Edge. – Asons Jan 29 '18 at 07:29
  • Right, will run a few more tests but browser-compatibility is not my main concern at the moment! :) – Andrea Aloi Jan 29 '18 at 10:33
0

Figured it out thanks to this article, and jotted down this css class that does the trick:

.ensure-padding {
    position: relative;
}

.ensure-padding::after {
    content: "";
    position: absolute;
    left: 100%;
    width: 2rem;
    height: 1px;
}

Now one simply needs to add the .ensure-padding class to leave some space to the right of an element when it overflows its container, as shown here. The only downside is that the value for the width property on the ::after pseudo-class has to equal the value of the padding-right property on the .main container, so when the the latter changes the .ensure-padding property has to be updated accordingly.

Andrea Aloi
  • 971
  • 1
  • 17
  • 37