CSS Right Margin Does Not Work Inside a Div With Overflow Scroll

overflow css
css overflow padding
scroll-margin
css right padding not working
inline scroll css
scroll offset css
css overflow-y: scroll to bottom
css padding causes overflow

I am trying to make two divs, one inside the other. The inner div is larger than the outer div, the outer div has overflow:scroll, and the inner div has margin:25px. So I do this:

#outer {
    width: 200px;
    height: 100px;
    overflow: scroll;
}
#inner {
    width: 400px;
    height: 200px;
    margin: 25px;
}

...

<div id="outer">
    <div id="inner">

    </div>
</div>

Instead of the inner div having a margin of 25px all the way around as expected, there is a 25px margin on THREE sides, but on the right side there is none. This is extremely counter-intuitive in my opinion.

If I add a middle div with a width large enough width to contain the inner div + 50px, we can make it look right, but that seems like a hacky workaround.

See my example on JSFiddle: http://jsfiddle.net/d3Nhu/16/

This happens the same way in every major browser. Is there any good reason for this behavior? Is this correct behavior according to the CSS specification?

NOTE: As you'd expect in this example, it makes no difference if you use overflow:auto instead of overflow:scroll.

EDIT: Please note that I'm not looking for a workaround for this behavior. (I already found one.) I'm looking for any insight as to the reason for this behavior, especially if it is documented in the CSS specification anywhere.

TL;DR:

Margins are for moving an element in from the wrapper, not expanding the wrapper outwards.

The long explanation:

This behavior is consistent with specifying a width in addition to a horizontal margin anywhere in the document. To break it down, consider the following snippet, where I specificity a wrapper without an overflow property, and the margin does not expand the wrapper element.

body {
    padding: 20px;
}
.outer {
    width: 400px;
    border: 1px solid black;
}
.inner {
    width: 400px;
    height: 40px;
    margin: 0 20px;
    background: grey;
}
<div class="outer">
    <div class="inner">
        
    </div>
</div>

overflow:scroll and The Right Padding Problem, overflow:scroll and The Right Padding Problem - A CSS Only you have a parent div with overflow:scroll and some padding; inside The key is to simulate this margin using an extra element that the browser can't ignore. The inner div is larger than the outer div, the outer div has overflow:scroll, and the inner div has margin:25px. So I do this: …. Instead of the inner div having a margin of 25px all the way around as expected, there is a 25px margin on THREE sides, but on the right side there is none.

add display:inline-block; to #inner div

see this fiddle

scroll-margin, scroll-margin is used to adjust an element's snap area (the box that of scroll-​margin because that affects spacing for all elements within the container. scroll​-margin-right: <length>; scroll-margin-bottom: <length>; browsers) do not currently support longhand-format scroll-padding and overflow: auto ; Margin is the distance from each side to the neighboring element OR the borders of document. Margin right didn't means that it will push the element towards left.It means that it will generate space on right side.If next element will come it will come after mentioned margin-right.In your case width is 100%.No space is available for margin-right.

So the answers here don't actually solve the problem! (Although super detailed to the reason why it doesn't work)

I needed a solution. Here's mine for future readers. Use a combination of display:flex; with pseudo ::after element to fake the presence of a div to provide the margin needed.

.wrapper {
  display: flex;
  width: 400px;
  height: 100%;
  padding: 40px;
  background: lightGrey;
}

.lists_container {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  overflow: auto;
  position: relative;
  background: grey;
  padding: 40px;
  margin: 40px;
  width: 100%;
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 250px;
  max-width: 500px;
  height: 100px;
  margin: 50px 0;
  padding: 20px;
  background: orange;
  margin-right: 30px;
}

.card.last::after {
  content: '';
  position: absolute;
  right: -100px;
  width: 40px;
  height: 100%;
  background: red;
}
<div class="wrapper">

  <div class="lists_container">

    <div class="card">
    </div>

    <div class="card">
    </div>

    <div class="card last">
    </div>

  </div>

</div>

The "Inside" Problem, That takes the background-color and pads the left and right sides. The inside element is what limits the width inside and centers. padding: 2rem 1rem; } .​inside { max-width: var(--contentWidth); margin: 0 auto; } #If you can definitely hide the overflow-x on the parent, then extreme negative-margin and  The total margin between them is 30px instead of 40px. Solution 6. The top margin of an in-flow block element collapses with its first in-flow block-level child's top margin if the element has no top border, no top padding, and the child has no clearance. This is very interesting and I can just add one top border line.

overflow-x, This may be nothing, a scroll bar, or the overflow content. sets what shows when content overflows a block-level element's left and right edges. hidden: Content is clipped if necessary to fit horizontally in the padding box. No margin-​bottom: 12px; } #div1 { overflow-x: hidden;} #div2 { overflow-x: scroll;}  I am trying to create fixed position div inside relative container. I am using bootstrap css framework. I am trying to create a fixed position cart. So whenever user scroll page it will show cart

overflow: hidden - overflow, This is necessary for technical reasons — if a float intersected with the scrolling element it would forcibly rewrap the content after each scroll step,  I'm late to the party, but I thought it was worth adding a different solution that addresses some of the concerns raised above. I came here because of exactly the kind of situation that @Philip raised in response to Alexandre Lavoie's solution: I have dynamically generated content inside the container, so I can't just apply styling to a specific div name like #some_info.

CSS Overflow, The overflow is not clipped. The content renders outside the element's box; hidden - The overflow is clipped, and the rest of the content will be invisible; scroll​  Add the following rule: overflow: hidden; This is caused by collapsing margins. See an article about this behavior here.. According to the article: If a parent element does not have any top padding or less top margin then its first child, then elements are rendered in a way that makes the parent element appear to have the child element's margin.

Comments
  • There's a nice demo of the problem at brunildo.org/test/scroll-child-margin.html
  • Can you add an explanation of why the div must be an inline-block element in order for the right-margin to push out the outer div?
  • it has something to do with being a white-space dependent rendering, beyond that i'm not too sure. There is a pretty good reference at designshack.net/articles/css/…
  • Thanks for the reference. Still isn't exactly what I'd expect, but that does make some sense.
  • It should be pointed out that this isn't a good fix if you have css for the inner content that depends on width:auto. Something like jQuery UI's tabs won't fill the entire div anymore since it doesn't have a known parent width.
  • It'd be great if you could simplify the CSS to take out the irrelevant bits (e.g. border-radius), but +1 for finding a modern flexbox solution!
  • Sure, @SeantheBean cleaned a little. Feel free to edit also. I was copying out my own code quickly! Massive love for flexbox!