Floating block collapse - html

I make grid system and i have encountered "strage" behaviour of block
for example
HTML:
<div class="l_row">
<div class="l_cell"></div>
<div class="l_cell"></div>
<div class="l_cell"></div>
<div class="l_cell"></div>
</div>
CSS:
.l_row {
min-width: 0px;
width: 100%;
max-width: 100%;
margin: 2rem auto;
}
.l_row:before, .l_row:after {
content: " ";
display: table;
}
.l_row:after {
clear: both;
}
.l_cell {
float: left;
padding-right: 15px;
width: 25%;
}
.l_row .l_cell:last-child {
padding-right: 0px;
}
And if .l_cell have some content at least one symbol 1, a, - works well, but if .l_cell is empty it collapses to width:0 and ignoring width in css

Your layout can be fixed with a few minor adjustments.
(1) If you add padding to .l_cell, this will increase the box width and the four .l_cell blocks with width 25% will not fit on a single line. You can fix this by using box-sizing: border-box which will force .l-cell to keep the over width to 25% while also including the 20px right padding.
(2) The "zero collapse width" effect is due to the nature of the floats. Since you did not specify a height or minimum height, any float without content will have zero height but with 25% width. If you have a sequence of floats as in your example, the left edges of the floats will be positioned to the left as far as possible until they hit the right edge of a previous float. If a float has zero height, it has no right edge, to it appears to have zero width. If you add a min-height value, all the floats will position themselves as you expect.
.l_row {
min-width: 0px;
width: 100%;
max-width: 100%;
margin: 2rem auto;
}
.l_row:before, .l_row:after {
content: " ";
display: table;
}
.l_row:after {
clear: both;
}
.l_cell {
box-sizing: border-box;
float: left;
padding-right: 20px;
width: 25%;
min-height: 20px;
}
.l_cell:nth-child(odd) {
background-color: beige;
}
.l_cell:nth-child(even) {
background-color: lightblue;
}
.l_row .l_cell:last-child {
padding-right: 0px;
}
<div class="l_row">
<div class="l_cell">x1</div>
<div class="l_cell"></div>
<div class="l_cell">x3</div>
<div class="l_cell"></div>
</div>

use &nbsp inside it to achieve what you are looking for.
For instance,
<div class="l_cell"> </div>
This considers the div as a block with content.
Hope this helps.

Finded...
https://css-tricks.com/make-sure-columns-dont-collapse-horizontally/
.col {
border-top: 1px solid white;
border-bottom: 1px solid white;
padding-top: 1rem;
padding-bottom: 1rem;
min-height: 1px;
}

Related

Fixed height of div regardless of elements inside

For reporting purposes I want a div report-canvas with a fixed height in mm:
.report-canvas {
height: 335mm;
min-height: 335mm;
max-height: 335mm;
}
A page has this structure:
<div class="a4">
<div class="header"></div>
<div class="report-canvas"></div>
<div class="footer"></div>
</div>
This works fine when .report-canvas doesn't have any child elements. But when I start to add h2's, table's and other div's, then the footer is pushed down outside of the page and the report-canvas is too big. How can I force report-canvas to always have the same size regardless of child elements?
This is the CSS of the other elements:
.a4 {
page-break-before:always;
clear: both;
margin: 0 auto;
border: 1px solid #888888;
width: 250mm;
height: 365mm;
}
.header {
padding-bottom: 10px;
height: 35px;
}
.footer {
padding-top: 10px;
height: 25px;
}
You can either use overflow: hidden or overflow: scroll on report-canvas

How to position a div with equal margins for left, right, and top

I would like to achieve a layout that looks like this:
I am interested in a css/html only solution, so no javascript required.
The widths of both divs are dynamic, so I cannot use any static margins.
The spacing between the sides of the divs, and the top, should be the same.
I tried using margin: auto auto 0 auto on the inner div, as you can see in this jsfiddle, but it only works for left and right.
Note, the following attempt doesn't answer the question fully, since the width of the child cannot be dynamic.
The idea is to use a percentage width + percentage margin-top values on the child. It's a responsive layout, see the comments in the code, and try it out on different window sizes.
JSFiddle: http://jsfiddle.net/jkoycs6e/
body {
margin: 0;
}
.outer {
height: 100vh; /*for demo only*/
background: teal;
overflow: auto;
}
.inner {
width: 80%;
background: gold;
margin: auto;
margin-top: 10%; /* 100%-80%/2 */
}
<div class="outer">
<div class="inner">
hello<br/>hello<br/>hello
</div>
</div>
This is not possible. At least not without using javascript. There is no css-only solution.
If you put align="center" in your div you'll get to the middle of the screen every time but it's not going to be supported in HTML5 so I recommend the 50:50 approach.
div
{
text-align:center;
margin-top:50%;
margin-bottom:50%;
}
Hope that helps. ^^
Set the outer parent's overflow to auto and give your margin-top a relative value. Something like this:
.outer {
background: blue;
overflow: auto;
}
.inner {
background:yellow;
width: 100px;
height: 100px;
margin: 1em auto 0 auto;
}
<div class="outer">
<div class="inner">
</div>
</div>
This seems to work:
.outer {
height: 500px;
width: 300px;
background: blue;
position: relative;
}
.inner {
width: 80%;
height: 200px;
background:green;
position: absolute;
margin-left: 10%;
margin-right: 10%;
margin-top: 10%;
margin-bottom: 0;
}
You can change the percentages marked for the margins as per your intended value for k.
Here's the fiddle
EDIT: Note that the width of inner has to be set in terms of percentages for this to work. Also note that when a margin is specified in terms of percentage, the margin's value is computed as a percentage of the width of the container. Even for the vertical margins, the percentage is applied on the width (and NOT the height) of the container.
Here's an SO post that's helpful in understanding how to position elements with respect to their container.
This answer doesn't actually make use of the margin property, nor does it have only two div.
body {
font-size: 26px;
text-align: center;
font-family: monospace;
}
#container {
display: inline-block;
position: relative;
width: 100%;
}
#dummy {
margin-top: 20%;
}
#element {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: silver
/* show me! */
}
#wrapper {
display: table;
width: 100%;
}
#row {
display: table-header-group;
}
#left {
display: table-cell;
background-color: chartreuse;
width: 20%;
}
#incenter {
display: table-cell;
background-color: aqua;
}
#right {
display: table-cell;
background-color: chartreuse;
width: 20%;
}
<div>
<div id="container">
<div id="dummy"></div>
<div id="element">
k (20%)
</div>
</div>
<div id="wrapper">
<div id="row">
<div id="left">width = k (20%)</div>
<div id="incenter">incenter</div>
<div id="right">width = k (20%)</div>
</div>
</div>
</div>
Another example with measurements in pixels is here.
For explanation refer:
https://stackoverflow.com/a/12121309/2534513
https://stackoverflow.com/a/6615994/2534513
I have actually combined techniques mentioned in above two answers to make this one.
Using JavaScript would have been a lot easier.

Make 3 column divs responsive. Help me spot what I'm doing wrong?

The div elements inside the row are floated left, as described here:
http://www.w3schools.com/html/html_responsive.asp
and percentage sized.
I tried to apply what was suggested in this link below, in a similar question, but without success:
Responsive CSS / Inline divs
The divs keep an inline relation of 50% - 100% - 50% and their contents overlap.
Can anyone help me spot what I missed?
Thank you.
In my CSS and HTML I have:
footer[role="contentinfo"] div {
box-sizing: border-box;
}
.engage-row:after {
content: "";
display: table;
clear: both;
}
.col-1 {
float: left;
width: 25%;
}
.col-2 {
float: left;
width: 50%;
padding: 10px 20px 0px 20px;
}
.col-3 {
float: left;
width: 25%;
}
.footer-wfix {
clear: both;
}
/* for illustrative purposes */
.engage-row {
border: 1px solid red;
}
.engage-row > div {
border: 1px solid blue;
}
<footer id="colophon" role="contentinfo">
<div class="footer-wrap">
<div class="engage-row">
<div class="col-1">
Column 1
</div>
<div class="col-2">
Column 2
</div>
<div class="col-3">
Column 3
</div>
</div>
<div class="footer-wfix">
Footer Menu and Site-generator
</div>
</div>
</footer><!-- #colophon -->
Edited the code and am adding the below for clarity:
- I edited the footer by adding the "engage-row" and it's containing column divs.
- All divs have inherited box-sizing: border-box.
- Column 1, Column 2 and Column 3 don't readjust positioning when I decrease the screen size (width); instead of becoming on top of each others, they are changing their size (keeping percentages but becoming smaller), making the containing text and images overlap (text from column 2 goes in front of the image in column 1). I hope I am using the correct terms for clarity.
- How can I make them readjust the positioning as the screen size changes?
- PrintScreen: 3column divs in footer
(This is an awesome site. Thank you)
You need to take into account the padding in the .col-2 declaration. When you have three columns adding up to a total of "100 % width" and then add padding, the result so to speak is "more than 100 % width", causing the overlapping behavior you observe.
One way around it is to declare the paddings in percent as well. If you don't like the resulting "elastic margins", you need to figure out a equation that works. Or check out Bootstrap or something similar (I mean you can either use it as is, or decipher their responsive solutions).
You need to add the css3 property box-sizing: border-box; This will wrap your padding into your div, so the width will be 50% only.
Please share your feedback if its helpful for your problem.
.col-2{
float: left;
width: 50%;
padding:10px 20px 0px 20px;box-sizing: border-box;
}
you mention 25% 50% 25% and a border of div so overlapped,
in this case use box-sizing: border-box;
.engage-row:after {
content: "";
display: table;
clear: both;
}
.col-1 {
float: left;
width: 25%;
}
.col-2 {
float: left;
width: 50%;
padding: 10px 20px 0px 20px;
}
.col-3 {
float: left;
width: 25%;
}
.footer-wfix {
clear: both;
}
/* for illustrative purposes */
.engage-row {
border: 1px solid red;
}
.engage-row > div {
border: 1px solid blue;
box-sizing: border-box;/*added one*/
}
This is what I needed (I couldn't be clear until I researched enough):
The left and right divs include images and I didn't want those to change size as I decrease the screen resolution. I wanted to input that adjustment in the middle div which contains only text and a subscription form.
The question/answer that drove me there:
How to make element fill remaining width, when sibling has variable width?
My testing fiddle - http://jsfiddle.net/0gvxxpjj/
<!-- In html--->
<div class="row">
<div class="col-1">
<img src="">
</div>
<div class="col-3">
<img src="">
</div>
<div class="col-2">
<h3>Header</h3>
<p>This is a paragraph that, along with the header, needs to wrap as the screen is resized</p>
</div>
</div>
<!-- html ends here-->
/* CSS starts here */
.col-1 {
float: left;
width: 100px;
}
.col-3 {
float: right;
width: 100px;
}
.col-2{
padding: 10px 20px 0px 20px;
overflow: hidden;
}
.row {
border: 1px solid black;
display: inline-block;
}
.col-1, .col-3 {
border: 1px solid blue;
}
.col-2 {
border: 1px dashed red;
}
Hope it becomes useful to someone else.
As I understand it, you want to have the divs be in a 25% - 50% - 25% layout and after the browser shrinks beyond a certain size, they become 100% width and stack on top of each other.
This is done via media queries. What, essentially, happens is that you set some CSS rules inside a media query which adds to any previous CSS rules only when a certain condition has been met (in this case browser width). A rough example can be seen below.
These are the relevant parts:
This sets how the divs will look by default - full width.
.col-1,
.col-2,
.col-3 {
float: left;
width: 100%;
}
This sets the widths of the divs to 25-50-25 once the browser width is larger than 768px.
#media all and (min-width:768px) {
.col-1, .col-3 {
width: 25%;
}
.col-2 {
width: 50%;
}
}
You can extend this example to the layout you desire.
footer[role="contentinfo"] div {
box-sizing: border-box;
}
.engage-row:after {
content: "";
display: table;
clear: both;
}
.col-1,
.col-2,
.col-3 {
float: left;
width: 100%;
}
.col-2 {
padding: 10px 20px 0px 20px;
}
.footer-wfix {
clear: both;
}
/* for illustrative purposes */
.engage-row {
border: 1px solid red;
}
.engage-row > div {
border: 1px solid blue;
}
#media all and (min-width:768px) {
.col-1, .col-3 {
width: 25%;
}
.col-2 {
width: 50%;
}
}
<footer id="colophon" role="contentinfo">
<div class="footer-wrap">
<div class="engage-row">
<div class="col-1">
Column 1
</div>
<div class="col-2">
Column 2
</div>
<div class="col-3">
Column 3
</div>
</div>
<div class="footer-wfix">
Footer Menu and Site-generator
</div>
</div>
</footer><!-- #colophon -->

Auto re-size in Div not working

I have a <div> called "bottom" which holds 2 divs together. The 2 divs inside are "manufacturers" and "main" which are located side by side with each other. What I want is that the <div id="bottom"> must be auto resizable when either the two divisions expands (the <div id="main"> lists down all the available products that is why it also has an auto height). The problem is that when I use a float property or a "display: inline" property in the main and manufacturers divs it overrides the bottom div causing it not to expand.
here's my css code:
#bottom{
padding: 1.5em;
margin: auto;
margin-top: 3.7em;
margin-bottom: 5em;
background-color: white;
width: 67em;
height: auto;
}
#manufacturers{
padding: 1em;
width: 13em;
height: auto;
border: 1px solid #CFCFCF;
font-size: 17px;
float: left;
}
#main{
float: right;
padding: 0.5em;
width: 47em;
height: 10em;
background: blue;
position: relative;
display: inline;
}
In your case element with ID "bottom" collapsed because of elements inside have floats (left or right). You should use clearfix class with #bottom:
.clearfix: before,
.clearfix: after {
display: table;
content: " "
}
.clearfix: after {
clear: both
}
Answer to question about "clearfix"
#main{
display: inline-block;
}
you could try this:
#bottom{
width: 100%;
}
#manufacturers{
width: 50%;
}
#main{
width: 50%;
}
Add above css properties in your existing CSS stylesheet. Apart from it:
Expanding Downward to fit the content is the expected behavior. If you have specified floats somewhere in your style you may need to clear them.
<div style="clear:both"></div>

Is it possible for inline-block element to auto fill the available width?

I have a <div id="content">, which contains <div id="sub-navigation> and <div id="main container">, which themselves are inline-blocks. I would like to be able to make the main container fill the rest of the available page width. Is that possible?
I need columns-strip to expand or shrink based on the number and width of column elements. If the width of the columns-strip exceeds the width of the main container, then a horizontal scroll bar should appear.
* {
margin: 0px;
padding: 0px;
font-size: 10pt;
white-space: normal;
}
#wrapper {
margin: 0px 20px;
background-color: red;
}
#header {
margin: 25px 10px 10px 10px;
height: 50px;
background-color: purple;
color: white;
}
#content {
margin: 10px;
padding: 10px;
font-size: 0pt;
white-space: nowrap;
overflow: hidden;
background-color: white;
}
#sub-navigation {
width: 200px;
height: 150px;
display: inline-block;
vertical-align: top;
background-color: forestgreen;
color: white;
}
#main-container {
padding: 10px;
display: inline-block;
overflow: auto;
background-color: yellow;
}
#columns-strip {
padding: 10px;
font-size: 0pt;
white-space: nowrap;
background-color: mediumturquoise;
}
.posts-column {
margin: 0px;
width: 200px;
height: 200px;
display: inline-block;
vertical-align: top;
overflow: auto;
}
#footer {
margin: 10px 10px 25px 10px;
height: 50px;
background-color: navy;
}
<div id="wrapper">
<div id="header"></div>
<div id="content">
<div id="sub-navigation"></div>
<div id="main-container">
<div id="columns-strip">
<div class="posts-column" style="background-color: lightgray;"></div>
<div class="posts-column" style="background-color: darkgray;"></div>
<div class="posts-column" style="background-color: gray;"></div>
</div>
</div>
</div>
<div id="footer"></div>
</div>
You have to remove the inline-block styles and float the #sub-navigation div. inline-block is not suited for what you are trying to achieve. When you add no display styles, the div element will be the default value which is block, block elements take up all the available space by default. By floating the #sub-navigation element you make it only take up the space required for its contents.
#sub-navigation {
width: 200px;
height: 150px;
float : left;
vertical-align: top;
background-color: forestgreen;
color: white;
}
#main-container {
padding: 10px;
overflow: auto;
background-color: yellow;
}
make sure to add a clear: left element after the #main-container
That's not how inline-blocks are supposed to be used. Best thing to do here is make your navigation box float:left and leave the default display value alone.
If your header, footer and wrapper have specific widths, then yes, you can have your main-container fill the available space. But if you're not specifying widths in your CSS, then you need to determine how big your main-container CAN be based on the rendered width of the containing element (wrapper). The only way to determine that width after the page loads is with javascript. If you want your site to have a dynamic width but still have your content (sub-navigation and main-container) fill the screen, you would either need to use javascript or percentages, and percentages can get ugly when you start looking at varying resolutions of monitors, laptops, etc...
Ever heard of flex box model!!
It is made just for that.
Note in flexbox model all child elements act as flex box model you cant opt out certain things. Which mean if page has navigation and under it content div + side div. You can't make top navigation out of it. Which has implications. So solution is to have all things only that need flex box in one div.