How to get width 100% right in overlay with CSS [duplicate] - css

This question already has answers here:
CSS: Width in percentage and Borders
(5 answers)
How do I add 1px border to a div whose width is a percentage?
(3 answers)
Closed 3 years ago.
I am creating an overlay but the width ends up wrong on the right. Where do I go wrong? In the end I want some buttons that are 100% width of the screen, minus some margin.
body
{
width: 100%;
margin: 0px;
}
.a1
{
background-color: rgba(0, 0, 0, 0.7);
position: fixed;
width: 100%;
height: 100%;
z-index: 1;
}
.a2 {
width: 100%;
border: 5px solid blue;
}
<div class="a1">
<div class="a2">The width is going to far on the right</div>
</div>

You don't need to specify width: 100% on the child div a2. As a block element, it will automatically fill the available width of the parent element, which is set at 100%.
Your a2 CSS becomes:
.a2 {
border: 5px solid blue;
}
In this way your margins are respected and work as expected:
* {
box-sizing: border-box;
}
body
{
width: 100%;
margin: 0px;
}
.a1
{
background-color: rgba(0, 0, 0, 0.7);
position: fixed;
width: 100%;
height: 100%;
z-index: 1;
}
.a2 {
border: 5px solid blue;
}
<div class="a1">
<div class="a2">The width is going to far on the right</div>
</div>
Following OP comment about sizing of elements
I notice that you don't specifically mention that you are using border-box as your box-sizing methods. I have added this into the snippet now.
Using border-box means that when you specify the size of a box, you are including the borders inside that size.
For example, if the width is set to 100%, this is 100% including any borders you have on your elements. Most normalized stylesheets set box-sizing to border-box by default.

Related

Why is this CSS code overflowing inside my inner box even though it fits my outer box?

So I created a box with 2 div tags, namely: outer div and box div.
The total width(content block) of my outer div is 600w+50padLeft+50padRight= 700px. Meanwhile the total width of my box div (containing block) is 500w+98padL+98padR+4border = 700px.
Yet, my box is overflowing in the outer div.
Here is the image:
https://www.flickr.com/photos/183721425#N02/48599642452/in/dateposted-public/
aside,
article,
section,
header,
footer,
nav {
display: block;
}
div,
p {
margin: 0;
padding: 0;
}
html {
background: #ccc;
}
.outer {
/* TOTAL WIDTH: 700px */
width: 600px;
margin: 0 auto;
background: #9CF;
padding: 50px;
}
.box {
background: #B7D19C;
/* TOTAL WIDTH: 700px */
width: 500px;
padding: 98px;
border: 2px black solid;
}
p {
background: #FF9;
height: 100%;
/* here */
}
<div class="outer">
<div class="box">
<p>Here we'll need to calculate the width of this interior div element. This may seem simple at first, but as we begin to add box model properties, and as the overall width of the parent element and the div conflict with one another, we'll need to understand
how each of the properties combine to effect the overall width (and height) of page elements.
</p>
</div>
</div>
Use box-sizng:border-box property.
It defines how the width and height of an element are calculated, should they include padding and borders, or not. Margin is not considered. Usually the size (width or height) of the element not include border or padding
*{
box-sizing: border-box;
}
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>calculating element dimensions</title>
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<style>
aside,
article,
section,
header,
footer,
nav {
display: block;
}
div,
p {
margin: 0;
padding: 0;
}
html {
background: #ccc;
}
.outer {
/* TOTAL WIDTH: 700px */
width: 600px;
margin: 0 auto;
background: #9CF;
padding: 50px;
}
.box {
background: #B7D19C;
/* TOTAL WIDTH: 700px */
width: 500px;
padding: 98px;
border: 2px black solid;
}
p {
background: #FF9;
height: 100%;
/* here */
}
/*add styles here*/
</style>
</head>
<body>
<div class="outer">
<div class="box">
<p>Here we'll need to calculate the width of this interior div element. This may seem simple at first, but as we begin to add box model properties, and as the overall width of the parent element and the div conflict with one another, we'll need to
understand how each of the properties combine to effect the overall width (and height) of page elements.
</p>
</div>
</div>
</body>
</html>
Problem :
Your issue is with the box model itself as by default the border and the padding are not included in the actual elements width :
.outer has a width of 600px and has a 50px of padding (total width is 600px + 50px right padding + 50px left padding = 700px) so the .box will be shifted 50px to the right.
.box has 500px for the width, 98px for the padding and a 2px border which results in a 500px + 98px right padding + 98px left padding + 2px left border + 2px right border =700px.
the widths are equal but don't forget about the 50px of padding on the .outer that results on an overflow.
Solution :
The solution is very simple, add box-sizing: border-box on the two divs (better to use it on all the elements) which includes the padding and border on the width (meaning the padding and border won't overflow the declared width).
* {
box-sizing: border-box; /** that's it ! **/
}
aside,
article,
section,
header,
footer,
nav {
display: block;
}
div,
p {
margin: 0;
padding: 0;
}
html {
background: #ccc;
}
.outer {
/* TOTAL WIDTH: 700px */
width: 600px;
margin: 0 auto;
background: #9CF;
padding: 50px;
}
.box {
background: #B7D19C;
/* TOTAL WIDTH: 700px */
width: 500px;
padding: 98px;
border: 2px black solid;
}
p {
background: #FF9;
height: 100%;
/* here */
}
<div class="outer">
<div class="box">
<p>Here we'll need to calculate the width of this interior div element. This may seem simple at first, but as we begin to add box model properties, and as the overall width of the parent element and the div conflict with one another, we'll need to understand
how each of the properties combine to effect the overall width (and height) of page elements.
</p>
</div>
</div>

3 column layout with inline block not working- the divs aren't lining up correctly

I have a div which contains three child div's, and for some reason the first child div is properly positioned within its parent, but the other two children are positioned lower from the first child. The more content I add to the first child the lower the other children become positioned relative to the top of the container parent.
Heres a jfiddle showing you my problem: http://jsfiddle.net/gY72a/7/
the three children arent on the same line here but you can see the problem when you look at how high the first child is positioned compared to the second one.
Code is already in the jfiddle, but here is the css I am using:
/*Parent div in which all three children are nested*/
#main {
width: 80%;
min-width: 1000px;
background-color: #FFFFFF;
margin: 1% auto;
border-radius: 1px;
border: 0px solid rgba(0, 0, 0, 0.15);
box-shadow: 2px 2px 2px 0px rgba(0, 0, 0, 0.2);
}
/*First child*/
#leftside {
display: inline-block;
width: 18%;
margin: 10px 1% 8px;
padding: 1em;
background-color: rgba(0, 0, 0, 0.1);
}
/*Second Child*/
#innermain {
display: inline-block;
width: 50%;
margin: 10px 1% 8px;
padding:1em;
background-color: #eaeaea;
border-radius: 1px;
border: 0px solid rgba(0, 0, 0, 0.15);
box-shadow: 2px 2px 2px 0px rgba(0, 0, 0, 0.2);
}
/*Third child*/
#rightside {
width: 20%;
min-width: 320px;
padding: 1em 0px;
display: inline-block;
background: #FFFFFF;
margin: 10px 1% 8px ;
border-radius: 1px;
border: 1px solid rgba(0, 0, 0, 0.15);
}
The main problem here is that you are using `display:inline-block" and also that you are using a combination of percentages and margins with ems. Now, theoretically, you could have 3 blocks, and add their widths and the padding, and the margin - to all equal 100, but even if you wanted to go that route, you are using the inline-block method - which by default leaves a little unwanted space between each block, and throws off that number. Beyond that, padding and margins add to the size of the box, so if you have a box that is 20% wide, and has a padding of 1em and a margin of 1% - then it's 20%+2%+2em (+total border width) - and what does that equal? Well, I don't know - and the browser isn't going to love dealing with that either, because depending on window size, that number is going to be different. So, if you want to know the problem, those are the factors leading to the problems.
If you want a solution, then you have a few routes, but they depend on what you need to do. It doesn't appear as though you are building this site responsively. So in that case, you are working with a 1000px wide canvas. - and in that case, then there is no reason why you cant just use px to add up margin/padding/box size etc to equal 100. leave the boxes as display: block; and float them left.
If you want to come into the present, and start using a bit of modern stuff - you should read about box-sizing: border-box - What that does is change the box model so that the padding and borders of boxes moves inside the box and therefore doesn't add to it's size. It's really great and makes working with css a pleasure. Then you don't have to add stuff up to determine the box's size. - so - unless you need to support IE 7 - I would suggest you make it standard in your overall approach to CSS from now on. http://www.paulirish.com/2012/box-sizing-border-box-ftw/
If you are going to float the columns in their "wrapper" thing - then that wrapper thing is no longer going to regognize them in the same way, so you are going to have to look up clearfixing the div, or use overflow:hidden; (which has some issues) or float that wrapper itself to get them to live in the same world again, because floating takes the elements out of the regular flow.
In the case that you can go with box-sizing, then you still have to worry about margins(they don't move inside the box). So, you'll need to have those in percentages, or get another fancy way of making consistent gutter widths, but since you have a static sized site - I'm not going to go into that.
Here is a fiddle without all of your styles - to show how it works.
HTML
<div class="content-wrapper">
<div class="column what">
<h2>What We do</h2>
<p>Bla bla bla</p>
</div>
<div class="column main-content">
<h2>Latest News and Events</h2>
</div>
<div class="column where">
<h2>Where To Find Us</h2>
</div>
</div> <!-- .content-wrapper -->
CSS
*, *:before, *:after {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.content-wrapper {
width: 1000px;
margin-right: auto;
margin-left: auto;
border: 1px solid red;
overflow: hidden; /* should be clearfix instead */
}
.column { /* what the columns have in common */
float: left;
padding: 1em;
}
.what {
width: 25%;
margin-right: 1%;
background-color: orange;
}
.main-content {
width: 48%;
margin-right: 1%;
background-color: yellow;
}
.where {
width: 25%;
background: red;
}
You have specified display:inline-block for the divs below which should align them properly in a row with the widths given. But the width is taken by the content section of the div and the div adds the margins given to them with the width. This is why the blocks are jumping below one another.
When you apply box-sizing: border-box; to the divs, the width of the div will be calculated including the margins given to the corresponding divs.
Hope this helps you.
#main, #leftside, #innermain{
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box; /* Opera/IE 8+ */
}
This should do what you want:
#main div {
float: left;
}

How to add borders to div without messing up the layout?

I have the following elements:
<body>
<div id="container">
<div id="sidebar1"></div>
<div id="content">
<h3>Lorem ipsum</h3>
<p>Whatnot.</p>
</div>
<div id="sidebar2"></div>
</div>
</body>
Following this style:
/* ~~ this fixed width container surrounds all other divs~~ */
#container {
width: 960px;
background-color: #FFF;
margin: 0 auto;
overflow: hidden;
}
#sidebar1 {
float: left;
width: 180px;
/*border: 2px solid black;*/
background-color: #EADCAE;
padding: 0px 0px 100% 0px;
}
#content {
padding: 10px 0;
width: 600px;
float: left;
}
#sidebar2 {
float: left;
width: 180px;
/*border: 2px solid black;*/
background-color: #EADCAE;
padding: 0px 0px 100% 0px;
}
I am trying to achieve this layout: http://jsfiddle.net/QnRe4/
But as soon as I un-comment the borders it turns into this: http://jsfiddle.net/FZxPQ/
** Solved **
The border width was added to each element's total width making them too wide to fit in the container. Removing 2x the border width from each column's width solves the problem: http://jsfiddle.net/FZxPQ/4/
CSS box-sizing to the rescue! This property
alters the default CSS box model used to calculate widths and heights of elements
The border-box value means that
the width and height properties include the padding and border
/* support Firefox, WebKit, Opera and IE8+ */
#container, #sidebar1, #sidebar2 {
box-sizing: border-box;
-moz-box-sizing: border-box;
}
However, browser support is not 100% standardized.
As other answers have already mentioned the extra width which pushes the sidebars out of alignment is because the width calculation includes the border width. box-sizing simply tells the browser that an element with a given width/height should include any border and padding values into the final width/height calculations.
The problem is that when you add in the boarder, the size of the outer divs increased by 4, 2px on each size. So, your container needs to grow in size by 8px.
So change your container to:
#container {
width: 970px;
background-color: #FFF;
margin: 0 auto;
overflow: hidden;
}
See: http://jsfiddle.net/QnRe4/13/
When you apply the borders, that goes outer the divs, so the sidebars will have 184px width which doesn't fits to the container. try addig width: 176px
http://jsfiddle.net/QnRe4/12/
#sidebar1 {
float: left;
width: 176px;
border: 2px solid black;
background-color: #EADCAE;
padding: 0px 0px 100% 0px;
}
Like this? http://jsfiddle.net/QnRe4/3/
What's happening is that your elements are losing their block display properties when you remove the borders.
So, adding display: block to those elements resolves that.
I've also adjusted your element's widths by 4px in width to retain the layout, since removing those borders essentially reduces the space that those elements occupy on-page.

How do you vertically align an empty div inside a full height div?

Big picture: I'm trying to make a bar graph made up of discrete units. Each unit will be a div. The bar will grow from bottom to top.
Details: I have a container div that holds all of the unit divs, or blocks. The container has a vertical-align of bottom to do this.
This is what it should look like: https://jsfiddle.net/hpf4h/1/
<div id="container">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
#container {
height: 100px;
width: 10px;
padding: 1px;
background-color: #00f;
display: table-cell;
vertical-align: bottom;
}
.block {
height: 10px;
width: 10px;
margin: 1px 0px 1px 0px;
background-color: #0f0;
}
That works fine, but I need the container to have a height of 100%. Which makes this happen: https://jsfiddle.net/7n7ZH/1/
I'd prefer to find a way to do this with CSS, preferably not too hacky. I'm already using jQuery for the behavior in my project, so I could use that as a last resort.
Edit: Also, all parent tags also have a height of 100%, including HTML and body.
Make #container's container element display:table like this : https://jsfiddle.net/7n7ZH/2/
html, body { height: 100%; margin:0; }
body { display:table; }
#container {
height: 100%;
width: 10px;
padding: 1px;
background-color: #00f;
display: table-cell;
vertical-align: bottom;
}
.block {
height: 10px;
width: 10px;
margin: 1px 0px 1px 0px;
background-color: #0f0;
}
<div id="container">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
When you use display:table-cell the browser looks for ancestor elements being display:table-row, display:table-row-group and display:table. If it can't find them, it creates pseudo elements to stand in for them. That's what's happening here.
So when you say display:table-cell; height:100%, that's 100% of the created pseudo element that is display:table. But that pseudo element is only as high as its content, and there's no way in CSS to say "make the pseudo-element have height that's 100% the height of its parent instead".
But it is possible to have a real element be display:table and set its height to 100%, in which case the browser will use that and not create the display:table pseudo element.
Applying display:table-cell; and height at the same time rarely gives the results you'd expect. I see that you're trying to use vertical-align which is probably why you added the table-cell. Try css positioning instead:
Remove display:table-cell; and vertical-align from your container.
Add height:100%; to both the body and html elements so your container has room to grow.
Set the container to position:relative; which will make it the origin of all positioned children rather than the document root (body tag). This will allow you to move your container around without screwing up the child positions.
Add a wrapper around your blocks (you could use ul, li for this rather than divs).
Position the block container as position:absolute; bottom:0;
Here's the code...
#container {
height: 100%;
width: 10px;
padding: 1px;
background-color: #00f;
position:relative;
}
.blockContainer
{
position:absolute;
bottom:0px;
}
.block {
height: 10px;
width: 10px;
margin: 1px 0px 1px 0px;
background-color: #0f0;
}
body { height:100% }
html { height: 100%}#container {
height: 100%;
width: 10px;
padding: 1px;
background-color: #00f;
position:relative;
}
.blockContainer
{
position:absolute;
bottom:0px;
}
.block {
height: 10px;
width: 10px;
margin: 1px 0px 1px 0px;
background-color: #0f0;
}
body { height:100% }
html { height: 100%}
...and here's the fiddle...
https://jsfiddle.net/kPEnL/1/
I'm unable to provide assistance with doing it in the way you have started, but taking your original big picture of trying to make a vertical progressbar, here's an alternative which uses the progressbar in Twitter Bootstrap. In its existing form, it doesn't do vertical progress bars, but this modification does.
I originally suggested using stacked bars, but this doesn't work with the vertical implementation. Instead, I've got a solution which uses CSS gradients to draw the blocks in, but still uses the normal bootstrap progress bar.
.progress.discrete {
background-image: linear-gradient(0deg,
black 0%, green 5%, green 95%, black 100%);
background-size: 100% 10%;
background-repeat: repeat-y;
}
/* Bar is used to cover up the blocks, so make it look like a background */
.progress.discrete .bar {
background-image: linear-gradient(to right, #f5f5f5, #f9f9f9);
}
I assumed you wanted your blocks to be a percentage of the bar height rather than an absolute size - this means I can't apply the gradient to the bar. Instead, it can be applied to the background, and the bar used to cover it up (i.e. set width of the bar to 100-progress%). I've also included an example which uses a fixed block size applied to the bar if that's what you wanted.
http://jsfiddle.net/BHTXZ/3/
It needs a little tidying up, but does the trick.

Keeping/scaling DIV Ratio with percentages

At the moment I have a layout that pulls a number of thumbnails into a grid - each is defined by a style that keeps them a fixed ratio, (roughly 16:9) which is defined by pixel dimensions (389px x 230px) but they are looking a bit small on high-res screens.
The images are actually pulled into the DIV as a background that covers 100% width and height of the DIV and then the DIV's obviously control the aspect and size.
What I am looking to do is have these DIV's dynamically resize based on the page size of the device but to keep the ratio of the DIV's.
Is this possible?
My thoughts would be to set the width based on the percentage of the page but then I'm not sure how I would set the height and keep the correct aspect ratio (due to different resolutions etc.)
What would be the best way to do this?
EDIT - Thanks for all your ideas so far, thought maybe I should show you how I'm pulling in the data at the moment.
In my HTML I've got the following code which generated the grid
<a class="griditem" href="../video.php?video=13" style="background-image:url(../video/Relentless/Relentless.jpg); background-size:100% 100%;">
<div class="titles">
<h5>Relentless Short Stories</h5>
<h6>Frank Turner: The Road</h6>
</div>
This is styled with the following CSS
.griditem {
position: relative;
float: left;
margin-right: 17px;
margin-bottom: 17px;
background-color: #777;
-webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.5);
-moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.5);
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.5);
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
width: 389px;
height: 230px;
text-align: left;
}
.titles {
padding: 5px;
position: absolute;
bottom: 10px;
left: -1px;
right: -1px;
background: transparent url(../images/layout/white80.png) top left;
-moz-border-radius: 1px 1px 0 0;
border-radius: 1px 1px 0 0;
text-align: left;
}
The reason I'm implementing it this way is so that the Div can float over the bottom of the image.
Just a quick idea which might be useful for you.
It is based on the fact that vertical padding/margin use the WIDTH of the parent box when it is set to percentages, so it is possible to resize a div relative its parent box
http://jsfiddle.net/xExuQ/2/
body,html { height:100%; }
.fixed-ratio-resize {
width: 50%; /* child width = parent width * percent */
padding-bottom: 50%; /* child height = parent width * percent */
height: 0; /* well, it is not perfect :) */
}
​If you want to put some (non-background) content into this nicely resized box, then put an absolutely positioned div inside it.
Reference:
http://www.w3.org/TR/CSS2/box.html#margin-properties and
http://www.w3.org/TR/CSS2/box.html#padding-properties says:
Margins: "The percentage is calculated with respect to the width of the generated box's containing block. Note that this is true for 'margin-top' and 'margin-bottom' as well. If the containing block's width depends on this element, then the resulting layout is undefined in CSS 2.1."
Paddings:"The percentage is calculated with respect to the width of the generated box's containing block, even for 'padding-top' and 'padding-bottom'. If the containing block's width depends on this element, then the resulting layout is undefined in CSS 2.1."
EDIT
http://jsfiddle.net/mszBF/6/
HTML:
<a class="griditem" href="#" style="background-image: url(http://pic.jpg);">
<span class="titles">
<span class="name">Unicomp Studios</span>
<span class="title">Springs Buckling (2012)</span>
</span>
</a>
CSS:
.griditem {
float: left;
margin-right: 17px;
margin-bottom: 17px;
min-width: 100px; /* extremely narrow blocks ==> crap looking */
width: 30%;
background: blue no-repeat;
background-size: contain; /* from IE9 only: https://developer.mozilla.org/en/CSS/background-size */
border: 1px solid transparent; /* prevent .titles:margin-top's margin collapse */
}
.titles {
/* <a> elements must only have inline elements like img, span.
divs, headers, etc are forbidden, because some browsers will display a big mess (safari) */
display: block; /* so display those inline elements as blocks */
padding: 5px;
margin: 0 auto;
margin-top: 105%;
background: yellow;
}
.titles > span {
display: block;
}​
I know this might not be the best solution, but
<html>
<style type="text/css">
#cool{
width:40%;
background:blue;
padding-bottom:10%;
}
</style>
<div id="cool" >
</div>
</html>
Here Ive used padding-bottom, to maintain its height relative to its width. U can set padding-bottom as a percentage. Hope this helped.

Resources