(margin/padding)-right does not create space for overflow container - html

For some reason, in an overflown container, the padding on the right side is not shown.
.parent {
background-color: orange;
width: 150px;
height: 50px;
overflow: auto;
padding-right: 15px;
}
.child {
background-color: blue;
width: 250px;
height: 100%;
margin: 0 10px;
}
body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
<div class="parent">
<div class="child">
</div>
</div>
I expected the orange color to show up when I scrolled to the very end (right)

Let's start without applying any overflow property. We clearly have the element outside of it's parent container (add padding of the container will remain inside):
.parent {
background-color: orange;
width: 150px;
height: 100px;
padding:15px;
}
.child {
background-color: blue;
width: 250px;
height: 100%;
}
body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
<div class="parent">
<div class="child">
</div>
</div>
Now by adding overflow:scroll or overflow:auto you will simply add the scroll to see the overflowing part and you won't have the padding as excepted:
.parent {
background-color: orange;
width: 150px;
height: 100px;
overflow:auto;
padding:15px;
}
.child {
background-color: blue;
width: 250px;
height: 100%;
}
body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
<div class="parent">
<div class="child">
</div>
</div>
Same logic with the margin right. When the element is overflowing there is no room to add margin between the inner element and the parent element.

I have checked in also Mozilla Firefox. and it's working fine.
.parent {
background-color: orange;
width: 150px;
height: 50px;
overflow-y: hidden;
overflow-x: auto;
padding-right: 15px;
}
.child {
background-color: blue;
width: 250px;
height: 100%;
margin: 0 10px;
display: inline-block;
}
body {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
<div class="parent">
<div class="child">
</div>
</div>

You should use below CSS. It's working for me.
.parent {
background-color: orange;
width: 150px;
height: 50px;
padding-right: 15px;
overflow-y: hidden;
overflow-x: auto;
}
.child {
background-color: blue;
width: 250px;
height: 100%;
margin: 0 10px;
display: inline-block;
}

Related

Why overflow-y may affect horizontal layout in flex?

Consider the following flex layout:
body {
margin: 0;
}
.container {
background: red;
color: white;
height: 100vh;
display: flex;
}
.left {
flex-grow: 1;
height: 100%;
padding: 1em;
}
.main-content {
background: blue;
height: 130%;
}
.right {
height: 100%;
}
.side-content-upper {
padding: 1em;
height: 50%;
}
.side-content-lower {
padding: 1em;
height: 60%;
background: black;
}
<div class="container">
<div class="left">
<div class="main-content">some some some some some some some some some some some some some some some some some some some some some</div>
</div>
<div class="right">
<div class="side-content-upper">more</div>
<div class="side-content-lower">more</div>
</div>
</div>
Since heights of .main-content and of .side-content-upper plus that of .side-content-lower are greater than 100%, we get vertical overflow. Now let's make the first column fit the screen height and scroll separately by adding box-sizing: border-box; overflow-y: scroll; (to make this more compact, I align unchanged CSS into single lines):
body { margin: 0; }
.container { background: red; color: white; height: 100vh; display: flex; }
.left {
flex-grow: 1;
height: 100%;
padding: 1em;
box-sizing: border-box;
overflow-y: scroll;
}
.main-content { background: blue; height: 130%; }
.right {
height: 100%;
}
.side-content-upper { padding: 1em; height: 50%; }
.side-content-lower { padding: 1em; height: 60%; background: black; }
<div class="container">
<div class="left">
<div class="main-content">some some some some some some some some some some some some some some some some some some some some some</div>
</div>
<div class="right">
<div class="side-content-upper">more</div>
<div class="side-content-lower">more</div>
</div>
</div>
Works fine, doesn't it? Let's now apply the same style to the .right container:
body { margin: 0; }
.container { background: red; color: white; height: 100vh; display: flex; }
.left {
flex-grow: 1;
height: 100%;
padding: 1em;
box-sizing: border-box;
overflow-y: scroll;
}
.main-content { background: blue; height: 130%; }
.right {
height: 100%;
box-sizing: border-box;
overflow-y: scroll;
}
.side-content-upper { padding: 1em; height: 50%; }
.side-content-lower { padding: 1em; height: 60%; background: black; }
<div class="container">
<div class="left">
<div class="main-content">some some some some some some some some some some some some some some some some some some some some some</div>
</div>
<div class="right">
<div class="side-content-upper">more</div>
<div class="side-content-lower">more</div>
</div>
</div>
If your screen resolution is not too high, you'll see what I'm not expecting: the right column not only fits height and gets vertical scroll, but also shrinks and gets horizontal scroll. Why is that? It doesn't seem just the width of the vertical scrollbar: switch overflow-y of .right from scroll to hidden and you again will get .right deformed. I'm puzzled how to reason about this. Just in case, here's what I see with hidden:
Here are two 'fixes' for what it's worth - I know you're looking for an explanation more than a solution but hopefully this will help explain by example. I'm not confident I can detail the intricacies of what is happening here but it is basically do with the way scroll bars interact with with the box model, and how flex handles dimensions. If anyone more knowledgeable can shed some light please chime in.
Give the right div it's own flex property:
body { margin: 0; }
.container { background: red; color: white; height: 100vh; display: flex; }
.left {
flex: 5;
height: 100%;
padding: 1em;
box-sizing: border-box;
overflow-y: scroll;
}
.main-content { background: blue; height: 130%; }
.right {
flex: 1;
height: 100%;
box-sizing: border-box;
overflow-y: scroll;
}
.side-content-upper { padding: 1em; height: 50%; }
.side-content-lower { padding: 1em; height: 60%; background: black; }
<div class="container">
<div class="left">
<div class="main-content">some some some some some some some some some some some some some some some some some some some some some</div>
</div>
<div class="right">
<div class="side-content-upper">more</div>
<div class="side-content-lower">more</div>
</div>
</div>
Give the .side-content-upper and .side-content-lower a box-sizing: border-box property.
body { margin: 0; }
.container {
background: red;
color: white;
height: 100vh;
display: flex;
}
.left {
flex: 1;
height: 100%;
padding: 1em;
box-sizing: border-box;
overflow-y: scroll;
}
.main-content { background: blue; height: 130%; }
.right {
height: 100%;
box-sizing: border-box;
overflow-y: scroll;
}
.side-content-upper { padding: 1em; box-sizing: border-box; height: 50%; width: 100%; }
.side-content-lower { padding: 1em; box-sizing: border-box; height: 60%; background: black; width: 100%;}
<div class="container">
<div class="left">
<div class="main-content">some some some some some some some some some some some some some some some some some some some some some</div>
</div>
<div class="right">
<div class="side-content-upper">more</div>
<div class="side-content-lower">more</div>
</div>
</div>
One final note: when you give overflow to both the left and right divs, the container loses its implicit overflow: auto which was spacing your elements for you. This was causing the shrink issue - if you add overflow-y: scroll back on the container in your last demo the elements will regain their original proportions.
can use java script to help you by available screen height
add jquery.js in first
<script type="text/javascript">
$(document).ready(function(){
var y = screen.availHeight;
$(".container").css('height',y +'px');
$(".left").css('height',y +'px');
$(".right").css('height',y +'px');
$(".main-content").css('height',(y * 1.3) +'px');
$(".side-content-upper").css('height',(y * .5)
+'px');
$(".side-content-lower").css('height',(y * .6)
+'px');
});
</script>
<style type="text/css">
body { margin: 0; }
.container{
background: red;
color: white;
display: flex;
flex-wrap:wrap;
}
.left {
flex-grow: 1;
padding: 1em;
box-sizing: border-box;
overflow-y:scroll;
}
.main-content{ background: blue;}
.right{box-sizing: border-box;overflow-y: scroll;}
.side-content-upper { padding: 1em; }
.side-content-lower { padding: 1em; background:
black; }
</style>

Why is the vertical scroll bar attached to HTML when overflow: scroll is assigned to body?

If you run the following code, you will see that the vertical scrollbar gets attached to html and not body, which i expect.
I expect that because body has height defined as 800px but div.a has height of 1500px. So with overflow: scroll on body, scrollbar should appear on body and not html.
Can anybody shed some light on this ?
html {
background: black;
margin: 20px;
}
body {
background: red;
padding: 0;
margin: 0;
height: 800px;
overflow: scroll;
}
.a {
width: 500px;
height: 1500px;
background: yellow;
}
.b {
width: 500px;
height: 1000px;
background: blue;
}
<div class="a">
<div class="b">
</div>
</div>
I have managed to get this to work by telling the html to not show the overflow. Passing the burden over to its child to deal with.
* {
position: relative;
box-sizing: border-box;
}
html {
background: black;
margin: 20px;
overflow: hidden;
}
body {
width: 400px;
height: 100%;
max-height: 200px;
background: red;
padding: 20px;
margin: 0 auto;
overflow-y: scroll;
}
.a {
width: 300px;
height: 1500px;
padding: 20px;
margin: 0 auto;
background: yellow;
overflow-y: scroll;
}
.b {
width: 200px;
height: 3000px;
margin: 0 auto;
background: blue;
}
<div class="a">
<div class="b">
</div>
</div>

How do I achieve this simple boxes layout

I'm trying to create the following layout using only regular CSS display properties (block, inline..) not using flex or grid.
The top thing(bandeau) should have a height of 100px and horizontal margins that are 50px.
Both the left and right columns should have a width of 100px.
The footer thingy(pied) should have a height of 80px and horizontal margins of 75px.
body {
margin: 0;
padding: 0;
background: black;
min-height: 100%;
}
.bandeau {
height: 100px;
background: white;
margin: 0 50px;
}
.menuGauche {
width: 50px;
background: lightblue;
height: calc(100% - 80px);
margin: 0 0 80px 0;
position: absolute;
}
.ecran {
background: lightgreen;
width: calc(100% - 100px);
height: calc(100% - 80px);
position: absolute;
margin: 0 50px;
}
.menuDroite {
width: 50px;
background: lightblue;
height: calc(100% - 80px);
margin: 0 0 80px 0;
position: absolute;
left: calc(100% - 50px);
}
.pied {
height: 80px;
background: white;
margin: 0 75px;
width: 100%;
position: absolute;
bottom: 0;
}
<div class="bandeau"></div>
<div class="menuGauche"></div>
<div class="ecran"></div>
<div class="menuDroite"></div>
<div class="pied"></div>
When I am doing this kind of layout, I try to group them horizontally, so the two columns will be wrapped in another div. similar to this:
<!DOCTYPE html>
<html>
<head>
<style>
.main {
background-color: black;
}
.top {
margin: 0 50px;
height: 100px;
background-color: white;
}
.mid {
height: 500px;
background-color: green;
}
.left-col,
.right-col {
height: 100%;
width: 100px;
background-color: blue;
}
.left-col {
float: left;
}
.right-col {
float: right;
}
.bottom {
margin: 0 75px;
height: 80px;
background-color: white;
}
</style>
</head>
<body>
<div class="main">
<div class="top"></div>
<div class="mid">
<div class="left-col"> </div>
<div class="right-col"> </div>
</div>
<div class="bottom"> </div>
</div>
</body>
</html>
I've used float and assume a height for the middle section as it was not specified. Here is a plunk. Hope this helps!
As a beginner, you should avoid using absolute positionning and learn display , then float.
Nowdays display flex makes it easier.
You may also use tags which can be meaningfull for the contents they hold.
Here an example via flex:
html {
height: 100%;
}
body {
margin: 0;
padding: 0;
background: black;
min-height: 100%;
display: flex;
flex-direction: column;
}
main {
flex: 1;
display: flex;
}
.bandeau {
height: 100px;
background: white;
margin: 0 50px;
}
.menuGauche {
width: 50px;
background: lightblue;
}
.ecran {
background: lightgreen;
flex: 1;
}
.menuDroite {
width: 50px;
background: lightblue;
}
.pied {
height: 80px;
background: white;
margin: 0 75px;
}
<header class="bandeau"></header>
<main>
<div class="menuGauche"></div>
<div class="ecran">Play the snippet full page or play with:https://codepen.io/anon/pen/rJMrgz.</div>
<div class="menuDroite"></div>
</main>
<footer class="pied"></footer>
Here is a tutorial (among others) to start with : https://css-tricks.com/snippets/css/a-guide-to-flexbox/
( 101 advises : for french readers https://www.alsacreations.com/article/lire/53-guide-de-survie-du-positionnement-css.html )
You can use the display:table on some elements to achieve the result. so wrap your main content then display it as table.
html,
body {
height: 100%;
}
body{
margin: 0;
padding: 0;
background: black;
}
.bandeau{
height: 100px;
background: white;
margin: 0 50px;
}
.content-wrapper {
display: table;
height: calc(100% - 180px);
width: 100%;
}
.content-wrapper > div{
display:table-cell;
}
.menuGauche,
.menuDroite{
width: 100px;
background: lightblue;
}
.ecran{
background: lightgreen;
}
.pied{
height: 80px;
background: white;
margin: 0 75px;
}
<body>
<div class="bandeau"></div>
<div class="content-wrapper">
<div class="menuGauche"></div>
<div class="ecran"></div>
<div class="menuDroite"></div>
</div>
<div class="pied"></div>
</body>

Child elements expanding outside parent element with flex

I have used CSS flex to display two divs side by side which are contained inside a wrapper and I have been trying so that inside #myClippetWrapper is where I set the height, so in the child elements of #myClippetWrapper I can just set height: 100%;.
But as you can see from running the snippet below all of the elements inside #myClippetWrapper go outside of the main section, they are all hanging out of the main content div?
I don't want to use overflow: auto because I do not want a scroll bar there, I just need the child elements of #myClippetWrapper to not be outside of the main section/ div.
main {
margin: 0 auto;
margin-top: 10px;
margin-bottom: 10px;
padding: 8px;
background-color: red;
width: 100%;
max-width: 50%;
height: auto;
}
#myClippetWrapper {
display: flex;
height: 700px;
}
#clippetNav {
padding: 10px;
width: 250px;
height: 100%;
background-color: #222222;
margin-right: 10px;
}
#codeAndNotesWrapper {
display: flex;
width: 100%;
}
#codeAndNotesWrapper>div {
flex-basis: 100%;
height: 100%;
}
#codeView {
padding: 10px;
/*flex: 0 0 40%;*/
height: 100%;
background-color: #222222;
margin-right: 10px;
}
#noteView {
padding: 10px;
/*flex: 1;*/
height: 100%;
background-color: #222222;
}
#codeNotesEditor {
height: 100%;
background-color: #EAEAEA;
}
<main>
<div id="myClippetWrapper">
<div id="clippetNav">
</div>
<div id="codeAndNotesWrapper">
<div id="codeView">
</div>
<div id="noteView">
<div id="codeNotesEditor">
</div>
</div>
</div>
</div>
</main>
In many cases, flexbox eliminates the need to use percentage heights.
An initial setting of a flex container is align-items: stretch. This means that in flex-direction: row (like in your code) flex items will automatically expand the full height of the container.
Alternatively, you can use flex-direction: column and then apply flex: 1 to the children, which can also make a flex item expand the full height of the parent.
main {
max-width: 50%;
margin: 10px auto;
padding: 8px;
background-color: red;
}
#myClippetWrapper {
display: flex;
height: 700px;
}
#clippetNav {
display: flex;
padding: 10px;
width: 250px;
margin-right: 10px;
background-color: #222222;
}
#codeAndNotesWrapper {
display: flex;
width: 100%;
}
#codeAndNotesWrapper>div {
display: flex;
flex-basis: 100%;
}
#codeView {
display: flex;
padding: 10px;
margin-right: 10px;
background-color: #222222;
}
#noteView {
display: flex;
flex-direction: column;
padding: 10px;
background-color: #222222;
}
#codeNotesEditor {
flex: 1;
background-color: #EAEAEA;
}
<main>
<div id="myClippetWrapper">
<div id="clippetNav"></div>
<div id="codeAndNotesWrapper">
<div id="codeView"></div>
<div id="noteView">
<div id="codeNotesEditor"></div>
</div>
</div>
</div>
</main>
jsFiddle
Add
box-sizing: border-box;
To your child elements. This will make the padding show on the inside of the box rather than the outside and will not increase the overall size.
Add the box-sizing property..
* {
box-sizing: border-box;
}
main {
margin: 0 auto;
margin-top: 10px;
margin-bottom: 10px;
padding: 8px;
background-color: red;
width: 100%;
max-width: 50%;
height: auto;
}
#myClippetWrapper {
display: flex;
height: 700px;
}
#clippetNav {
padding: 10px;
float: left;
width: 250px;
height: 100%;
background-color: #222222;
margin-right: 10px;
}
#codeAndNotesWrapper {
display: flex;
width: 100%;
}
#codeAndNotesWrapper>div {
flex-basis: 100%;
height: 100%;
}
#codeView {
padding: 10px;
/*flex: 0 0 40%;*/
height: 100%;
background-color: #222222;
margin-right: 10px;
}
#noteView {
padding: 10px;
/*flex: 1;*/
height: 100%;
background-color: #222222;
}
#codeNotesEditor {
height: 100%;
background-color: #EAEAEA;
}
<main>
<div id="myClippetWrapper">
<div id="clippetNav">
</div>
<div id="codeAndNotesWrapper">
<div id="codeView">
</div>
<div id="noteView">
<div id="codeNotesEditor">
</div>
</div>
</div>
</div>
</main>
A big factor with setting your
display: flex;
Is padding and height can make a nasty couple;
Take this example into account:
display: flex;
height: 100%;
padding-top: 1vh;
This would essentially make your element the pages height, plus 1% of the view height, and of course give you a child element thats taller than its parent element.
This isn't a direct answer to your question, instead one to people looking here for why their child elements may be acting up.

Align divs with position relative horizontally

I have 3 divs inside a div and I want these 3 divs to align horizontally. I was able to do this by giving absolute position but I want them to have relative position. Why I want it to have relative position is, if I zoom out or zoom in, the div size won't change but the elements inside these divs change. I want the div to zoom out/in as well. That is why I want them to have relative position.
.body_clr {
background-color: #eceff1;
position: fixed;
overflow-y: scroll;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
.test_div {
width: 20em;
height: 20em;
margin-left: 2em;
margin-top: 20%;
position: relative;
background-color: #f5f5f5;
display: inline-block;
float: left;
z-index: 1;
}
.ff {
width: 40em;
height: 100%;
padding-top: 10%;
position: relative;
background-color: #2aabd2;
float: left;
margin-left: 20%;
margin-right: 20%;
display: inline-block;
}
.overview {
width: 20em;
height: 35%;
background-color: black;
margin-top: 20%;
float: left;
margin-right: 5%;
position: relative;
display: inline-block;
z-index: 1;
}
<div className="body_clr">
<div className="test_div"></div>
<div className="ff"></div>
<div className="overview"></div>
</div>
Right now my divs are not aligned horizontally.
I would use flexbox for this. Take a look at this example I made: https://jsfiddle.net/cfLfLnLx/.
Also use class and not className to specify the classes of HTML elements.
A more extensive guide to using flexbox:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
You have some mistakes in your css:
You can't use display: inline-block with float: left ( you have to use float: left or display: inline-block )
If you use float: left you have to put a clear after the 2 floated divs ( always ) .
My solve with table-cell
* { box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; }
.body_clr { width: 100%; height: 100%; display: table; }
.col1 { height: 100%; display: table-cell; padding: 0 10px; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; }
.ff { width: 100%; height: 40px; display: block; background: #000;}
.test_div { width: 100%; height: 40px; display: block; background: red;}
.overview { width: 100%; height: 40px; display: block; background: blue;}
<div class="body_clr">
<div class=" col1">
<div class="test_div"></div>
</div>
<div class="col1">
<div class="ff"></div>
</div>
<div class="col1">
<div class="overview"></div>
</div>
</div>
With float:
.body_clr { width: 100%; height: 100%; display: block; }
.clear { width: 0; height: 0; padding: 0; margin: 0; display: block; visibility: hidden; overflow: hidden; font-size: 0; line-height: 0; clear: both; }
.col1 { width: 33.33%; height: 100%; display: block; float: left; padding: 0 10px; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; }
.ff { width: 100%; height: 40px; display: block; background: #000;}
.test_div { width: 100%; height: 40px; display: block; background: red;}
.overview { width: 100%; height: 40px; display: block; background: blue;}
<div class="body_clr">
<div class=" col1">
<div class="test_div"></div>
</div>
<div class="col1">
<div class="ff"></div>
</div>
<div class="col1">
<div class="overview"></div>
</div>
<div class="clear"></div>
</div>