css border changes the div size completely? [duplicate] - html

This question already has answers here:
Impact of border property on top margin
(3 answers)
Closed 7 years ago.
EDIT: found a very good link explaining all about border collapse:
border collapse explained with examples
End of edit. Enjoy :)
I am failing to understand this...
Why applying a 1px solid black border to my div changes the div's size by a lot?
(without the border I can see a relatively thin line as my back ground color, with the border the רectangle of the background color is much wider, see the pictures)
this pic is without applying the border:
and now look at this photo (the only difference is the border...)
can someone explain how the border influences so much on the div size / what is really happening here?!
style:
#header {
background-color: yellow;
color: white;
text-align: center;
border: 1px solid black;
}
here is a fiddle so you can play around:
my fiddle
Thanks a lot,
Jimmy.

That's because of margin collapsing.
The margin is not part of the element iself, it's the distance between the element and surrounding elements, or between the element and containing borders or paddings.
In the first image the margins of your header element (a h1 perhaps?) is collapsing outside the div. The margins doesn't affect the size of the div, instead it pushes the surrounding elements away.
When you add a border to the div, then the margins of the header element will push the border away from the header element instead of pushing surrounding elements away. The margins of the header element determine the size of the div.

The Header size is same, just the background will not fill the area specified as element margin. Your h1 has default margin at top and bottom which is not calculated by browser to be filled. In order to force it you can use overflow: hidden; on Header, an old trick that covers 99% of famous clearfix class (for float fix):
#header {
background: yellow;
overflow: hidden;
}
#sidebar {
float: left;
width: 30%;
background: green;
}
#content {
float: left;
width: 70%;
background: lime;
}
<div id="header">
<h1>Header</h1>
</div>
<div id="sidebar">
<h1>Sidebar</h1>
</div>
<div id="content">
<h1>Content</h1>
</div>
The other way would be to avoid h1 margin and use padding instead, or fixed height:
#header {
background: yellow;
}
#sidebar {
float: left;
width: 30%;
background: green;
}
#content {
float: left;
width: 70%;
background: lime;
}
h1 {
margin: 0;
padding: .8em 0;
}
<div id="header">
<h1>Header</h1>
</div>
<div id="sidebar">
<h1>Sidebar</h1>
</div>
<div id="content">
<h1>Content</h1>
</div>

You can add box-sizing to prevent this from happening. Not every browser supports it though.
html {
-moz-box-sizing: border-box;
box-sizing: border-box;
}
*, *:before, *:after {
-moz-box-sizing: inherit;
box-sizing: inherit;
}

The total size of an element is going to be defined by:
Margin>Border>Padding>Actual element size
Your browser's developer console should allow you to see the value of all of these so try and see which one is changing between those two instances. From the pictures provided it looks like the padding may be changing as you manually adjust the border.
Try manual setting these values:
#header{
border: 1px;
border-color: black;
margin: 0;
padding: 0;
}

Set margin on the h1 tag to 0:
h1 {
margin:0;
}
I updated your fiddle here

Perfect example why sometimes using outline instead of border can solve a lot of headache.
Outlines differ from borders in the following ways:
Outlines do not take up space, they are drawn above the content.
With much respect to all other solutions (which are important to understand), try using the following as an easy fix:
outline: 1px solid black;
instead of
border: 1px solid black;
JSFiddle
Cheers!

div {
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
border: 1px solid yellow;
}

Related

I tried to align 2 identical boxes with border using negative margin but it's off by a little

I tried to make 2 boxes with the same dimension, padding, and border align on one another, but it's off by a bit. They aren't perfectly on top of the other one.
Then, I tried the same thing but without borders. Turns out, they align perfectly.
before, without borders
after, without borders
before, with borders
after, with borders
<!DOCTYPE html>
<html>
<head>
<style>
html {
padding: 0rem;
margin: 0rem;
border: 0rem;
}
.one {
margin: -0rem;
margin-bottom: -0rem;
}
.two {
margin: -0rem;
margin-top: -10rem;
}
.container p {
width: 10rem;
height: 10rem;
border: 0.1rem solid blue;
background-color: ;
}
.container p:last-of-type {
background-color: ;
}
div{
margin: 10 rem;
}
</style>
</head>
<body>
<div class="container">
<p class="one">paragraph one.</p>
<p class="two">paragraph two.</p>
</div>
</body>
</html>
I'd appreciate it if you could tell me what I did wrong.
As Sean suggested, you have to take borders into account. .two is moved down not only by .one's height, but by the sum of its top and bottom border. Which means that the top margin should be sum of -10rem (height) -0.1rem (top border) -0.1rem (bottom border) = -10.2rem.
Answer:
.two {
margin: -10.2rem 0 0;
}
The second suggested solution also works - to add box-sizing: border-box;:
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
Here it is added to all elements in the document, which is a kind of usual way to do it. You can also try adding it only to paragraphs - put box-sizing: border-box; into .container p {, which also was in the comments.

Margin Overflow From Parent in CSS

Whenever I add margin to any element I get overflow, I tried adding box-sizing, position:relative. but nothing works
searched on google but nothing seems to help me
can anyone know why is this happening?
Sample Image
The margin is outside the element. One way to deal with it is to use calc on width as in the following snippet.
And note that margin is diferent from padding: paddingis inside the border (so it is included in the area covered by the background color), margin is outside:
.x {
box-sizing: border-box;
margin: 30px;
width: calc(100% - 60px);
background: yellow;
border: 5px solid red;
}
<div class="x">margin....</div>
With padding instead of margin, this would be:
.x {
box-sizing: border-box;
padding: 30px;
width: 100%;
background: yellow;
border: 5px solid red;
}
<div class="x">Padding....</div>
You can't add margin to a div that is a sibling of your container or else it'll create an overflow. Use padding instead. See how the text in the margin example shifts the text.
.parent {
width: 100px;
height: 100px;
background: red;
}
.padding-example {
padding: 10px;
}
.margin-example {
margin: 10px;
}
<div class="parent">
<div class="padding-example">Correct</div>
</div>
<hr>
<div class="parent">
<div class="margin-example">Wrong</div>
</div>

Chrome adding weird padding between inside of div and my CSS display: table

I am attempting to wrap a CSS table ( div, class of myTable, display:table) inside a div (class of index and display:block) but am having an issue with Chrome. Chrome is adding about one pixel's worth of padding between the wrapper and the table it is containing. This does not occur in Edge, Safari or Firefox.
What is odd is that Chrome only adds this padding:
on the right side, and
and random widths.
You can see it below, or in this codepen: http://codepen.io/ihatecoding/pen/xgRXMZ
No Weird Padding: the right hand border is truly red:
Weird Padding: The right hand side adds padding, appearing purple due to background color of blue:
The blue padding is visible in this zoomed image:
If you adjust your browser windows to different widths you will see that at some widths it is fine, with no added padding, and at others the weird padding appears on the right, you'll see the right edge turn purple.
But this change is hard to see.This purple that appears on the rigth is not a true purple, but only appears as purple. The background color inside the container is blue, and at only one pixel the eye mixes it with the red border of the containing div. You can verify this if you change the background-color of containing div (.index) in the CSS to any color you want.
Please do not suggest I remove the table and just display the two as table-cells. This would work if I only had one table, but actually I have a bunch of tables I am stacking vertically inside this wrapper. It is important that I keep the wrapper for both cells as (display: table), because I actually have other rows that are in this container that I am also displaying as tables. If I display them all as table-cell, all of my rows end up on the same line, which is not what I want.
I have recognized that this problem occurs even if there is only one table, as you can see in my example, it is not the product of stacking tables inside a div.
Can any of you help me to get Chrome to behave and stop adding that weird padding?
Thanks!
UPDATE 1: The weird padding only occurs if I have my border-right present. If i remove that border, the padding never appears.
UPDATE 2: If I change the row wrapper to display: block, I eliminate the mysterious gap, but I'll leave the question open, in case anyone wants a display:tablefriendly solution.
UPDATE 3: The only answers that have been submitted as of yet involve javaScript. Since I did not specify that I wanted a pure CSS solution, I'll give the user who submitted a functional answer credit, but if you like a challenge and see this question, please feel free to drive to derive a pure CSS solution. Thank you!
body {
width: 100%;
padding: 0;
margin: 0;
}
article {
width: 75%;
}
.index {
background-color: blue;
display:block;
padding: 0;
border-top: solid 2px red;
border-left: solid 2px red;
border-right: solid 2px red;
box-sizing: border-box;
vertical-align: middle;
}
.index > div {
display: table;
box-sizing: border-box;
width: 100%;
}
.myTable > div {
display: table-cell;
box-sizing: border-box;
}
.myTable {
background-color: rgb(40, 40, 40);
}
.myTable > div {
color: white;
text-align: right;
border-collapse: collapse;
border: none;
border-width: 0;
}
.myTable > div.date {
text-align: right;
padding: 2%;
vertical-align: middle;
}
.index .excerpt {
width: 92%;
}
<body>
<article id="post-1" >
<div class="index">
<div class="myTable">
<div class="date">
1 .10 .2017 </div>
<div class="excerpt">
<p>Notice there is about 1px padding to the right of this table and its containing div, but only at certain screen widths </p>
<p>over there -----></p>
<p>You'll see that when the unwanted padding appears (at random widths), the right border of the div and this table appears to turn purple. This purple is not a true purple, but only appears as purple. The background color inside the container is blue, and at only one pixel the eye mixes it with the red border of the containiing div. You can verify this if you change the background-color of ".index" in the css to any color you want. </p>
<p><span style="color:orange"> It is important that I keep the the wrapper for both cells as (display: table)</span>, because I actually have other rows that are in this container that I am also displaying as tables. If I display them all as table-cells, they all end up on the same line, which is not what I want. </p>
<p>However, I have recognized that this problem occurs even if there is only one table.</p>
<p>This only occurs in Chrome, not Edge, Safari or Firefox.</p>
</div>
</div>
</div>
</article>
</body>
var article = document.getElementById('post-1');
article.style.width = Math.round(article.parentElement.clientWidth * 3 / 4) + 'px';
window.addEventListener("resize", function() {
article.style.width = Math.round(article.parentElement.clientWidth * 3 / 4) + 'px';
});
body {
width: 100%;
padding: 0;
margin: 0;
}
article {
width: 75%;
}
.index {
background-color: blue;
display: block;
padding: 0;
border-top: solid 2px red;
border-left: solid 2px red;
border-right: solid 2px red;
box-sizing: border-box;
vertical-align: middle;
}
.index > div {
display: inline-block;
box-sizing: border-box;
width: 100%;
}
.myTable > div {
display: table-cell;
box-sizing: border-box;
}
.myTable {
background-color: rgb(40, 40, 40);
}
.myTable > div {
color: white;
text-align: right;
border-collapse: collapse;
border: none;
border-width: 0;
}
.myTable > div.date {
text-align: right;
padding: 2%;
vertical-align: middle;
}
.index .excerpt {
width: 92%;
}
<article id="post-1">
<div class="index">
<div class="myTable">
<div class="date">
1 .10 .2017</div>
<div class="excerpt">
<p>Notice there is about 1px padding to the right of this table and its containing div, but only at certain screen widths</p>
<p>over there -----></p>
<p>You'll see that when the unwanted padding appears (at random widths), the right border of the div and this table appears to turn purple. This purple is not a true purple, but only appears as purple. The background color inside the container
is blue, and at only one pixel the eye mixes it with the red border of the containiing div. You can verify this if you change the background-color of ".index" in the css to any color you want.</p>
<p><span style="color:orange"> It is important that I keep the the wrapper for both cells as (display: table)</span>, because I actually have other rows that are in this container that I am also displaying as tables. If I display them all as table-cells,
they all end up on the same line, which is not what I want.</p>
<p>However, I have recognized that this problem occurs even if there is only one table.</p>
<p>This only occurs in Chrome, not Edge, Safari or Firefox.</p>
</div>
</div>
</div>
</article>
This is a rounding problem, caused by a container with a width of 75%. Apparently the table isn't good at filling a space of, say, 657.75 pixels fully.
A simple workaround would be to give the parent div the same background color as its border color, or the same as the table's background color. But you probably already considered those...
The real solution is to round the width of the article to whole pixels, so that the table is able to fill it neatly without having three quarter pixel left over.
This can't be done with CSS, so we need JavaScript.
var article = document.getElementById('post-1');
article.style.width = Math.round(article.parentElement.clientWidth * 3 / 4) + 'px';
window.addEventListener("resize", function() {
article.style.width = Math.round(article.parentElement.clientWidth * 3 / 4) + 'px';
});
body {
width: 100%;
padding: 0;
margin: 0;
}
article {
width: 75%;
}
.index {
background-color: blue;
display: block;
padding: 0;
border-top: solid 2px red;
border-left: solid 2px red;
border-right: solid 2px red;
box-sizing: border-box;
vertical-align: middle;
}
.index > div {
display: table;
box-sizing: border-box;
width: 100%;
}
.myTable > div {
display: table-cell;
box-sizing: border-box;
}
.myTable {
background-color: rgb(40, 40, 40);
}
.myTable > div {
color: white;
text-align: right;
border-collapse: collapse;
border: none;
border-width: 0;
}
.myTable > div.date {
text-align: right;
padding: 2%;
vertical-align: middle;
}
.index .excerpt {
width: 92%;
}
<article id="post-1">
<div class="index">
<div class="myTable">
<div class="date">
1 .10 .2017</div>
<div class="excerpt">
<p>Notice there is about 1px padding to the right of this table and its containing div, but only at certain screen widths</p>
<p>over there -----></p>
<p>You'll see that when the unwanted padding appears (at random widths), the right border of the div and this table appears to turn purple. This purple is not a true purple, but only appears as purple. The background color inside the container is
blue, and at only one pixel the eye mixes it with the red border of the containiing div. You can verify this if you change the background-color of ".index" in the css to any color you want.</p>
<p><span style="color:orange"> It is important that I keep the the wrapper for both cells as (display: table)</span>, because I actually have other rows that are in this container that I am also displaying as tables. If I display them all as table-cells,
they all end up on the same line, which is not what I want.</p>
<p>However, I have recognized that this problem occurs even if there is only one table.</p>
<p>This only occurs in Chrome, not Edge, Safari or Firefox.</p>
</div>
</div>
</div>
</article>

Vertically align a varible height text box next to a fixed height image

very common question I know, but I'm still struggling having read similar questions.
I have two divs (containing a variable height text box paragraph and a fixed height image) within a container div, as follows:
<div class="error-row row">
<div class="error-value-col">
<p class="error-value">{{error.message}}</p>
</div>
<a class="cross-link">
<img class="cross" src="/assets/cross.png" alt="close">
</a>
</div>
The accompanying LESS file is:
.error-row {
border: 1px solid #po-yellow;
border-width: 0px 1px 1px 1px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
position: relative;
margin: 0px;
.error-value-col {
float:left;
vertical-align: middle;
display: inline-block;
width: calc(~'100% - 70px');
.error-value {
font-size: 10px;
padding: 5px;
p {
margin-bottom: 0px;
}
}
}
.cross-link {
padding: 0px;
float: right;
vertical-align: middle;
display: inline-block;
height: 70px;
img.cross {
margin: auto;
width: 70px;
height: 70px;
padding: 28.5px 27.5px 26.5px 27.5px;
color: black;
}
}
}
I've tried several different combinations of settings but none seem to work. I want whatever the element with the smallest height is (out of the image and text box) to centre alongside the taller element.
Thanks all.
EDIT: Clarification...I want the error-value-col and cross-link to be centred on the error-row container. This will of course be sized to the largest element out of the two, which could be either.
I changed approach and use display:table and display:table-cell to obtain desired behaviour. Look at this updated jsFiddle to see if it's acceptable for you (converted LESS in CSS there).
Apart design rules, relevant new ones to LESS code are the following:
.error-row {
...
display:table;
width:100%;
.error-value-col {
...
display:table-cell;
vertical-align:middle;
.error-value {
...
p {
...
}
}
}
.cross-link {
...
display:table-cell;
width:70px;
vertical-align:middle;
img.cross {
...
}
}
}
Please refer to jsFiddle to see all differences including erasing of floating.
ALTERNATIVES:
Vertical aligning is (strangely) an hard topic in CSS, at least if
you don't want to use relatively new Flexbox model.
Generally a very common method is to absolute positioning inner DIV
with top:50% but due to fact that reference point is top-left
corner, then you have to push up it of "half of its height" with a
negative margin-top. This requires to have a fixed height of inner
DIV, in order to set this negative margin to half of it.

Getting a 100% height/width border on main div(or body)

http://designobvio.us/vodka/ Live demo
I've set my html, container, main and 100% but nomatter what I do I cannot get the border to be 100% height without scroll bars?
How can I achieve an effect?
HTML
<div id="main">
</div>
CSS (not currently the live code but this is what i've tried )
html, body{height:100%; width:100%;}
#main{height:100%; position:absolute; top:0px; bottom:0px; left:0px; right:0px; border:5px solid #000;}
By default the borders, margin and padding are not part of width/height and are added on top. That's why you get scrollbars as the full dimensions of the box are 100% in height and width plus the border-width.
You can set the box-sizing property to border-box, which tells the browser to include the calculation for borders and padding in the width/height properties (in opposite to content-box, which is the default value):
#main {
box-sizing: border-box;
[...]
}
As especially IE8 and the earlier version of the other browser families don't support this css-property, it's a good idea to add some browser-specific definitions, too:
#main {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
Take a look at the mozilla doku for detailed information on box-sizing.
I know this is an old post, but as it pops up on Google first page... Here is my solution that seems to work fine cross browsers:
height: 0:
border-style: solid;
border-width: 8vw 0 0 100vw;
border-color: transparent transparent transparent red;
Just used it for an :after pseudo-element in order to turn it in a triangle shape and it works just fine (test down to ie10).
Simply use 100vw instead of 100% and it should do the trick.
Are you looking for a fixed border or dynamic border? The problem with your code is the W3C box-model. In the default model, padding, margin and border are added to the size of your element. So in your code what you're really telling it is "make the box 100% and then add 10px worth of border".
Normally an easy change would be to manually switch the box model, but unfortunately that property does not play nice with height: 100%. So you have a few options:
1) If you are looking for a fixed border, this is a good trick: http://css-tricks.com/body-border/
2) If you need a dynamic border, you need to somehow get around the additional height the border adds. Here is one way:
html,body { height:100%; padding: 0; margin: 0; }
#container {
min-height:100%;
border-right: 5px solid #000;
border-left: 5px solid #000;
position: relative; /* relative postion so we can absolutely position footer within it */
}
#header {
height: 100px;
border-top: 5px solid #000;
background-color: red;
}
#content { padding: 0 0 100px 0; } /*padding must be equal to the height of the footer*/
#footer {
height: 100px;
border-bottom: 5px solid #000;
background-color: blue;
position: absolute;
bottom: 0;
width: 100%; /* with absolute position, a width must be declared */
}
HTML
<div id="container">
<div id="header"></div>
<div id="content"></div>
<div id="footer"></div>
</div>
jsfiddle here: http://jsfiddle.net/Qw2cb/
You can give box-size:border-box; to 'main', like
#main{
box-size:border-box;
}
Doing so the border will be added to 100% height of main. Learn more about box sizing here
So, you are saying that you do not want to display scrollbars?
CSS:
#main
{
overflow: hidden;
height: 100%;
position: absolute;
margin: 0px;
}