Div box inside another div not appearing - html

I hope you are having a good day! I have created a div in where I put 3 info boxes. The boxes are just not appearing when I set the width and height with percentages. But if I set them with pixels, they appear. I want them to be in percentages, because I want the website to be fully responsive on every device it's accessed. Any tips?
HTML&CSS:
#info {
height: 50%;
background-color: red;
}
.infoBox {
width: 20%;
height: 35%;
background-color: blue;
float: left;
margin: 0 1%;
}
<div id="info">
<div class="infoBox" id="infoBox1">
</div>
<div class="infoBox" id="infoBox1">
</div>
<div class="infoBox" id="infoBox1">
</div>
</div>

Your boxe has an height calculated to 'auto' because #info's parent has no height explicitly specified.
https://www.w3.org/TR/CSS2/visudet.html#the-height-property
<percentage>
Specifies a percentage height. The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'. A percentage height on the root element is relative to the initial containing block. Note: For absolutely positioned elements whose containing block is based on a block-level element, the percentage is calculated with respect to the height of the padding box of that element. This is a change from CSS1, where the percentage was always calculated with respect to the content box of the parent element.
Usually, you manage to inherit viewport's height from html through body all the way to your container
html,
body {
height: 100%;
}
#info {
height: 50%;
background-color: red;
}
.infoBox {
width: 20%;
height: 35%;
background-color: blue;
float: left;
margin: 0 1%;
}
<div id="info">
<div class="infoBox" id="infoBox1">
</div>
<div class="infoBox" id="infoBox2">
</div>
<div class="infoBox" id="infoBox3">
</div>
</div>
NOTE
https://www.w3.org/TR/2011/WD-html5-20110525/elements.html#the-id-attribute
The id attribute specifies its element's unique identifier (ID). The value must be unique amongst all the IDs in the element's home subtree and must contain at least one character. The value must not contain any space characters.

check now it is blank div so you have to give height in pixel or add content
.infoBox {
width: 20%;
min-height:200px;
background-color: blue;
float: left;
margin: 0 1%;
background-color:red;
}
#info {
height: 50%;
background-color: red;
}
.infoBox {
width: 20%;
min-height:200px;
background-color: blue;
float: left;
margin: 0 1%;
background-color:red;
}
<div id="info">
<div class="infoBox" id="infoBox1">
</div>
<div class="infoBox" id="infoBox2">
</div>
<div class="infoBox" id="infoBox3">
</div>
</div>

Related

Why do "negative margin and float applied elements" overlap?

First of all, please look at this code.
I learned that this was a common way to realize liquid layout.
But I can not understand some of this code.
.container {
overflow: hidden;
}
main {
float: left;
width: 100%;
margin-right: -340px;
background: red;
}
.main-inner {
margin-right: 340px;
background: blue;
}
.sidebar {
float: right;
width: 340px;
background: green;
}
<div class="container">
<main>
<div class="main-inner">
<p class="main-title">Main</p>
</div>
</main>
<aside class="sidebar">
<div class="sidebar-inner">
sidebar
</div>
</aside>
</div>
Question 1
I understand that the negative margin has the effect of moving an element in the specified direction. However, when you run this code, the main element does not seem to be moving at all. Why is this?
Question 2
Since we set the width of the main element to 100%, I understand that the aside element hits the main element and that the main element and aside element can not be side by side.
So, I think that we prepare a horizontal width that can apply the aside element by applying negative margin, but the background color of the main element is applied in the same way as when the horizontal width is 100%. Why is the background color of the main element not (100% - aside width)? How is this series of rendering done?
Question 3
Which document on W3.org describes these actions? I tried looking, but I could not find any detailed information on them.
thank you.
Let's start by adding the properties one by one and see what is happening.
Intially we have this code with no margin applied and only float elements:
.container {
overflow: hidden;
background:yellow;
}
main {
float: left;
width: 100%;
background: red;
}
.main-inner {
background: blue;
}
.sidebar {
float: right;
width: 340px;
background: green;
}
<div class="container">
<main>
<div class="main-inner">
<p class="main-title">Main</p>
</div>
</main>
<aside class="sidebar">
<div class="sidebar-inner">
sidebar
</div>
</aside>
</div>
It's clear that you made the red element to be width:100% floating on the left and the green one to float on the right with a fixed width. You may also notice that p element is having a default margin that's why the blue is not totally covering the red.
Now if you add negative margin-right you will not move the element or decrease the width but you will pull the content from the right in order to overlap the element. Here is a basic illustration:
.box {
width: 200px;
height: 200px;
background: red;
float: left;
}
<div class="box" style="margin-right:-100px;height:220px">
</div>
<div class="box" style="background:blue;">
</div>
As you can see the blue box is overlapping the red one by exactly 100px because we applied -100px to the margin-right of the red box. Same logic will happen in your case, you applied a negative margin equal to the size of the sidebar so you created the need space to move the sidebar at the same level of the main element.
.container {
overflow: hidden;
background:yellow;
}
main {
float: left;
width: 100%;
background: red;
margin-right:-340px;
}
.main-inner {
background: blue;
}
.sidebar {
float: right;
width: 340px;
background: green;
}
<div class="container">
<main>
<div class="main-inner">
<p class="main-title">Main</p>
</div>
</main>
<aside class="sidebar">
<div class="sidebar-inner">
sidebar
</div>
</aside>
</div>
So the main element is still 100% width BUT the sidebar is overlapping it due to negative margin.
Now the last step is to add the margin inside the main and in this case it will reduce the width of the inner element to make the total (width + margin) always equal to the width of parent element (containing block)
.container {
overflow: hidden;
background:yellow;
}
main {
float: left;
width: 100%;
background: red;
margin-right:-340px;
}
.main-inner {
background: blue;
margin-right:340px;
}
.sidebar {
float: right;
width: 340px;
background: green;
}
<div class="container">
<main>
<div class="main-inner">
<p class="main-title">Main</p>
</div>
</main>
<aside class="sidebar">
<div class="sidebar-inner">
sidebar
</div>
</aside>
</div>
Here is another illustration of margin with block element non floated:
.container {
border: 2px solid;
max-width: 50vw;
margin: auto;
}
.first {
height: 100px;
background: red;
margin: 0 -50px;
}
.second {
height: 100px;
background: blue;
margin: 0 50px;
}
<div class="container">
<div class="first">
</div>
<div class="second">
</div>
</div>
In this case the width is increasing/decrasing due to margin because the logic is always: width + margin = width of containing block.
With elements like float and inline block the logic is the same but we won't have width changes because the width is defined either by the content or explicitly.
.container {
border: 2px solid;
display:inline-block;
}
.first {
float:left;
height: 100px;
background: red;
margin-right:-50px;
}
.second {
display:inline-block;
width:200px;
height: 120px;
background: blue;
margin-top:20px;
margin-right:-100px;
}
<div class="container">
<div class="first">
some text here
</div>
<div class="second">
</div>
</div>
Here the float element has a width defined by the content, the inline-block has a width equal to 200px. The negative margin is creating the overlap and the size of the parent element (the containing block) is equal to width + margins.
For the references:
8 Box model
9 Visual formatting model
10 Visual formatting model details
The above explanation is very simplifed. Refer to the specification links for a full and details explanation.
The odd placement from <main> comes from a browser css-rule
p {
display: block;
-webkit-margin-before: 1em;
-webkit-margin-after: 1em;
-webkit-margin-start: 0px;
-webkit-margin-end: 0px;
}
You can reset it using a css reset like normalize.css.
However, I recommend using display: flex. Some wonderful resources.
.container {
display: flex;
}
main {
width: 75%;
}
aside {
width: 25%;
}

Set width of element to width of sibling

I have a slightly unusual CSS challenge to overcome.
I have a two column layout, whereby the width of the left column is set by the width of a main image, and the right allowed to fill the remaining space. There is a container under the main image, which could have a natural width greater than the main image. However, I want this div to be the same width as the main image, and the overflow to be hidden. Here is my effort at attempting this:
.outer {
margin-right: 5px;
position: relative;
}
.left {
float: left;
}
.right {
width: auto;
overflow: hidden;
}
.contentOuter {
overflow: hidden;
}
.content {
width: 500px;
}
.inner {
background-color: grey;
color: white;
width: 100%;
height: 150px;
}
<div class="outer left">
<div class="image">
<img src="http://placehold.it/350x150" />
</div>
<div class="contentOuter">
<div class="content">
<img src="http://placehold.it/500x50" />
</div>
</div>
</div>
<div class="outer right">
<div class="inner">
Hello world!
</div>
</div>
But as you can see, .contentOuter stretches to the width of its contents, regardless of what I attempt.
One major caveat I have is that apart from .content having a fixed width, I don't want any other hard-coded widths in my CSS; everything should be completely fluid, and the dimensions of the columns determined by the dimensions of the .image img.
So, I am after something that visually looks like this, but without the hard-coded max-width on .content:
.outer {
margin-right: 5px;
position: relative;
}
.left {
float: left;
}
.right {
width: auto;
overflow: hidden;
}
.contentOuter {
overflow: hidden;
}
.content {
max-width: 350px; /* Hard-coded for demo purposes */
}
.inner {
background-color: grey;
color: white;
width: 100%;
height: 150px;
}
<div class="outer left">
<div class="image">
<img src="http://placehold.it/350x150" />
</div>
<div class="contentOuter">
<div class="content">
<img src="http://placehold.it/500x50" />
</div>
</div>
</div>
<div class="outer right">
<div class="inner">
Hello world!
</div>
</div>
One option, though that depends on further requirements you may have, it so simply add to the lower block:
position: absolute;
width: 100%;
This takes it out of the flow, and the enclosing element will not take its width into account for sizing, only that of the image on top. The overflow: hidden will then hide whatever overflows.
The drawback is that the height of the enclosing element (or the position or subsequent elements) will not take into account the size of this element.
jsFiddle: https://jsfiddle.net/jacquesc/rsz0hb1g/
A quick way to solve this would be to simply use some jQuery. It would only take two lines of code to achieve this.
var imgWidth = $('.image').width();
$('.content').width(imgWidth);

Issue with inline-block elements with unknown width

I'd like to line up two elements in a header:
<div class="col-md-3">
<div class="header">
<div class="icon"></div>
<div class="title"><h1>This is the title row</h1></div>
</div>
<p>This is some content text. This is some content text. This is some content text. This is some content text. This is some content text. </p>
</div>
To the left is a fixed width icon, and I want to the title to fill up the remaining width. (The title is broken in two lines because of the narrow columns):
.col-md-3 {
width: 200px; /*this width is just for illustrating the problem, in reality this is Bootstrap's 25% width column*/
}
.icon {
display: inline-block;
height:50px;
width: 50px;
background: red;
}
.title {
display: inline-block;
}
I can't get them to line up using inline-block. Any ideas why?
PLUNKER
UPDATE
I added a new plunker (see above) to better demonstrate the problem.
I'm looking for an explanation why inline-block doesn't work in this case, and a possible solution how to make it work. Any workarounds posted are really appreciated, but I'd really like to find out what's the deal with inline-blocks in this case.
If the content of the inline-block does not fit on a single row, it will try to fit as a whole on the next line. This is different from regular inline elements, that most of the time is allowed to wrap to the next line.
You might want to read up on this behaviour at the W3C specification about the 'normal flow'.
Not sure why everyone makes it so complex, why not use a float?
.icon {
float: left;
width: 50px;
height: 50px;
background-color: red;
}
.title {
padding: 0 10px;
overflow: hidden;
}
.title h1 {
line-height: 50px;
margin: 0;
}
<div class="col-md-3">
<div class="header">
<div class="icon"></div>
<div class="title"><h1>This is the title row erg erg erg erg erg erg er</h1></div>
</div>
<p>This is some content text. This is some content text. This is some content text. This is some content text. This is some content text. </p>
</div>
You could set .header as table, and set .icon and .title as table cell.
Updated JsFiddle
.header {
display: table;
width: 100%;
}
.header .icon, .header .title {
display: table-cell;
vertical-align: middle;
}
.header .icon {
width: 60px;
}
.header .icon span {
width: 50px;
height: 50px;
display: block;
background: red;
}
.header .title h1 {
margin: 0;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<div class="col-md-3">
<div class="header">
<div class="icon"><span></span></div>
<div class="title"><h1>This is the title row</h1></div>
</div>
<p>This is some content text. This is some content text. This is some content text. This is some content text. This is some content text. </p>
</div>
If you do not specify the width of the inline-block element then the default value is auto. Then the browser will try to calculate a shrink-to-fit width based on the containing blocks width, in your case the .header element which bases its width on your .col-md-3 width. The browser does not take into account your .icon elements width when calculating the width of your .title element. So to get what you want, still using display: inline-block, you have to specify a width for your .title element.
.title {
width: calc(100% - 50px);
}
You could also just use float on your .icon element. See this answer.
Another way is to use display: table for containing block and table-cell for child elements as mentioned in this answer.
From the W3C specification:
10.3.9 'Inline-block', non-replaced elements in normal flow
If 'width' is 'auto', the used value is the shrink-to-fit width as for floating elements.
...
Calculation of the shrink-to-fit width is similar to calculating the width of a table cell using the automatic table layout algorithm. Roughly: calculate the preferred width by formatting the content without breaking lines other than where explicit line breaks occur, and also calculate the preferred minimum width, e.g., by trying all possible line breaks. CSS 2.1 does not define the exact algorithm. Thirdly, find the available width: in this case, this is the width of the containing block minus the used values of 'margin-left', 'border-left-width', 'padding-left', 'padding-right', 'border-right-width', 'margin-right', and the widths of any relevant scroll bars.
Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).
I would try something like this instead :
HTML
<div class="col-md-3">
<h2>This is the title row</h2>
<p>This is some content text. This is some content text. This is some content text. This is some content text. This is some content text. </p>
</div>
CSS
.col-md-3 { width: 200px; }
h2 { position: relative; padding-left: 50px;}
h2::before { content:''; position: absolute; height:50px; width: 50px; left: 0; background: red;}
Here's the fiddle
Just add display property value of just inline to .col-md-3 and adjust as needed, then inline-block to both .icon and .title
.col-md-3 {
width: 200px;
display: inline;
vertical-align: middle;
}
.icon {
display: inline-block;
height:50px;
width: 50px;
background: red;
}
.title {
display: inline-block;
height: 50px;
position: absolute;
line-height: 5px;
left: 70px; /* Width of the icon plus 10px for space */
}
<div class="col-md-3">
<div class="header">
<div class="icon"></div>
<div class="title"><h1>This is the title row</h1></div>
</div>
<p>This is some content text. This is some content text. This is some content text. This is some content text. This is some content text. </p>
</div>
Note: You may need to further adjust it to suit your need.
Add a width to .title class
.title {
with: calc(100% - 55px);
}
where 55px is from the .icon width plus 5px.

How does this produce unequal height divs?

demo [Firefox & IE]
HTML:
<div class="content">
<div class="img">
<div class="divs">
<img src="path.jpg" alt="" />
</div>
<div class="divs">
<img src="path.jpg" alt="" />
</div>
<div class="divs">
<img src="path.jpg" alt="" />
</div>
<div class="divs">
<img src="path.jpg" alt="" />
</div>
</div>
</div>
CSS:
html, body {
height: 100%;
}
.content {
/* height: 100%; */
position: relative;
width: 100%;
}
.img {
height: 100%;
margin-left: 0.5%;
max-width: 100%;
width: 100%;
}
.content .divs {
border: 1px solid #b64024;
float: left;
height: 25.5%;
margin: 1% 0.5% 0;
overflow: hidden;
width: 20%;
}
.content .divs img {
height: 100%;
width: 100%;
}
If you uncomment the height: 100%; from .content then you'll see the equal height divs there with images.
So, my question is:
How the .divss' height is calculated without having parent div height .img -> .content in percentage calculation for inherited div ?
Here's your problem in a nutshell:
Demo: http://jsfiddle.net/a75ekc0e/9/
.content {
height:400px;
position:relative;
}
.content div {
float:left;
background:yellow; border:1px solid blue;
width:20%; height:25%;
margin:1em;
}
That simplified demo shows the content 'working'. The key parts are that:
Your divs have a percentage height.
The 'containing block' of the divs has an explicit height.
Super-important: Note that the position:relative causes .content to be the 'containing' for its children; without this declaration it will be the body that is used for positioning.
…and thus, the divs can calculate their height based on their positioning.
If you remove the height from the .content then this element has no explicit height, and its height is taken from its content. When you do that with the above demo and Run it, you see the divs collapse to have no height at all, because they cannot calculate the percentage of something that will be determined later on.
In your demo they get their height from their varying-height image content, which causes them to vary. The height:25.5% is completely ignored because the parent has no explicit height.
Per the specification of the CSS height property:
The percentage is calculated with respect to the height of the generated box's containing block. If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned, the value computes to 'auto'.
For more details, read the section "Calculating Heights and Margins" in the CSS specification.
This might not be an answer.
Though, struggling a lot, I found the key reason behind this in short is due to different height of images in original size.
Let see the demo with equal height original image size:
demo
But still amazed of behavior of height of images just due to original image sizes and it also varies in different browsers.

Prevent padding from making an element bigger?

I have an element with a 70% width, and it is floating beside another element with 30% width. However, when I add 25px of padding, the element expands and breaks the format.
Is there any way to make padding increase the contents' distance from the element's edge, as opposed to making the element bigger?
.seventy {
float: left;
width: 70%;
background-color: lightsalmon;
}
.thirty {
float: left;
width: 30%;
background-color: lightgreen;
}
.padded {
padding: 25px; /* Forces box onto next line */
}
<div>Works:</div>
<div class="seventy">70% wide</div>
<div class="thirty">30% wide</div>
<br><br>
<div>Broken:</div>
<div class="seventy">70% wide</div>
<div class="thirty padded">30% wide, padded</div>
When you use the border-box model, the padding is included in the box size. See here for details.
.seventy {
float: left;
width: 70%;
background-color: lightsalmon;
}
.thirty {
box-sizing: border-box;
padding: 25px;
float: left;
width: 30%;
background-color: lightgreen;
}
<div class="seventy">70% wide</div>
<div class="thirty">30% wide</div>
I would create another element of the same type (may I guess it's a div?) inside the element and set that one to have a padding/margin of 25px.
For example:
<div id="wrapper">
<div id="width30">
</div>
<div id="width70">
<div id="padding25">
Acctual content here.
</div>
</div>
</div>
</div>