This is a very common scenario, I think.
I'm relatively (no pun intended) new to CSS and am having an issue with float alignment. I have two divs, one which will hold main content to be floated left and the other for navigation, which should be floated right.
Anyway, here is what happens when I don't apply any CSS formatting. This is desired behavior; the page will scroll down as expected:
Desired behavior
Here is what happens when I apply float: left or float: right to the respective elements:
Undesired page overflow
They both overflow past the page. I want it to stretch the page so that it scrolls down if it doesn't fit on one screen area.
A snippet of my HTML:
<body>
<div id="wrapper">
<div id="header"></div>
<div id="content">
<div id="main">
<p>Lorem ipsum [...snip...]</p>
</div>
<div id="secondary">
<p>Lorem ipsum [...snip...]</p>
</div>
</div>
<div id="footer">©</div>
</div>
</body>
And the corresponding CSS:
#content {
padding:10px;
padding-top: 110px;
padding-bottom:60px; /* Height of the footer */
}
#main {
padding: 10px;
float: left;
width:70%;
text-align:left;
}
#secondary {
padding: 10px;
float: right;
width:20%;
}
Why is it doing this, and how can I fix it?
Any floating element will increase the height of container div, so a floating element may have 1000 lines of code yet height of its parent element will remain zero unless there is an block element after the floating element..
I've modified your code a bit
<body>
<div id="wrapper" class="clrfx">
<div id="header"></div>
<div id="content">
<div id="main" class="clrfx">
<p>Lorem ipsum [...snip...]</p>
</div>
<div id="secondary" class="clrfx">
<p>Lorem ipsum [...snip...]</p>
</div>
</div>
<div id="footer">©</div>
</div>
</body>
css:
.clrfx:after {
clear: both;
display: block;
content: "";
}
Rule of thumb is, assign class="clrfx" to any Div which has atleast one child element which is floating. Some people use <div class="clear"></div> but this SHOULD NOT be used as clearing is a part of styling and not of markup.
In worst case if you have to use this then I would advise use
<br class="clear" />
because breaking line is close to clearing
Clear the floats and you should be OK.
For example according to your example:
<body>
<div id="wrapper">
<div id="header"></div>
<div id="content">
<div id="main">
<p>Lorem ipsum [...snip...]</p>
</div>
<div id="secondary">
<p>Lorem ipsum [...snip...]</p>
</div>
<!-- clear -->
<div style="clear:both;"></div>
</div>
<div id="footer">©</div>
</div>
</body>
Update: for older IE browsers, the clearing div might need a height defined to give it a "hasLayout" property or else it will ignore this div.
http://www.satzansatz.de/cssd/onhavinglayout.html
Generally, people make a class definition that has all this info so you only need to type <div class="clear"></div>
Here's an example of robust clearing CSS from http://sonspring.com/journal/clearing-floats
.clear {
clear: both;
display: block;
overflow: hidden;
visibility: hidden;
width: 0;
height: 0;
}
There are alternative methods to clear floats in the parent div and removing the extra, structural <div> tag but I personally don't feel a need to investigate if they are bullet-proof if this solution definitely is.
As you said that you were new to CSS: Floated elements have no height. Therefore #content is defaulting to minimum height, which is the combined height of the paddings.
Adding <div style="clear:both;"></div> after div#secondary will force it to below the floated elements. As this div does have a height, it causes #main to behave as expected. See Yuji's answer for sample code.
Floating elements are removed from the flow, so they are not taken into consideration when their parent element's height is being calculated and their parent element is set to overflow: visible.
You can either place a dummy element beneath the floated elements (forcing the dummy element to the correct place with the clear property), or you can set the parent element to something other than overflow: visible.
To make your wrapper contain all floated elements, simply set;
#wrapper {overflow: hidden;}
Simple, and you're done. No extra markup.
Related
I am working on a grid layout using css flex styling and want a total css solution, if possible, I have the means to fix it with javascript.
When a row exceeds the viewport width, it displays the scrollbar,
but when you scroll, the styling of the row element remains the size of the viewport,
it does not seem to "wrap" all of its children.
see : fiddle
Try scrolling, you will see the yellow row (.sk_row) class does not appear around all its children.
A solution would be fine, but I would like to know why the parent does not visually contain all children. I think I may be missing some key concept about flexboxes...
Duplicate of fiddle code...
<body>
<div id='pg_wrap'>
<div id='frm0'>
<div class='sk_scrl'>
<div class='sk_row'>
<div class='itm_val'>row 1</div>
<div class='itm_val'>1</div>
<div class='itm_val'>2</div>
<div class='itm_val'>3</div>
<div class='itm_val'>4</div>
<div class='itm_val'>5</div>
<div class='itm_val'>6</div>
<div class='itm_val'>7</div>
<div class='itm_val'>8</div>
</div>
<div class='sk_row'>
<div class='itm_val'>row 2</div>
<div class='itm_val'>1</div>
<div class='itm_val'>2</div>
<div class='itm_val'>3</div>
<div class='itm_val'>4</div>
<div class='itm_val'>5</div>
<div class='itm_val'>6</div>
<div class='itm_val'>7</div>
<div class='itm_val'>8</div>
</div>
</div>
</div>
</div>
#frm0{ width:420px;height:200px}
.sk_scrl{ overflow:auto;display:flex;flex-flow:column;align-content:stretch}
.sk_row{
display:flex;
justify-content:flex-start;
align-items:center;
background:#ff0;border:2px #f00 solid;
height:50px}
.itm_val{
display:flex;
border:1px #000 solid;background:#666;
flex:0 0 100px; height:30px; margin:0 5px;
align-items:center;justify-content:center}
Note : this is not the same as question
That op wants to change child behaviour, I want the parent to change.
It's not working the way you want because .sk_row inherits the width, in this case from #frm0:
#frm0 { width: 420px; }
With the class .sk_scrl you can't see it very well, because it's set to:
.sk_scrl { overflow: auto; }
If you use your browsers developer tools (assuming you have any), you'll see that the elements wrapped around your .itm_val divs are all 420 pixel wide. The reason the .itm_val divs are all visible outside of their container, is because they are "overflowing" out of their containing div.
Here's an example for how the width-inheriting-thing works:
<div class="container">
<div class="element"></div>
</div>
If you set the the width of .container to 50%, it will use up half of the available width within the window. If, however, you want .element to take up the full width of the window, you will have to adjust the width like this:
.element {
width: 200%;
}
If it were set to 100%, it would only be as wide as .container.
Here's a fiddle: http://jsfiddle.net/Niffler/n8hmpv13/
I have two div's that I am trying to position side by side but am having trouble. I understand that div's are block elements but I have never had trouble positioning them side-by-side before..
HTML:
<div class="contact">
<div class="team" id="staff-1">
<div id="DIV_2">
<img id="brian" src="../img/brian.png">
</div>
</div>
<div class="team" id="staff-1">
<div id="DIV_2">
<img id="brian" src="../img/brian.png">
</div>
</div>
</div>
I do not want to post all of the CSS because it is rather long for a SO post, but here it is loaded in a jsfiddle: http://jsfiddle.net/rynslmns/5pQJ7/
You can either use floating or inline-block elements:
.team {
float: left;
width: 33%;
}
OR
.team {
display: inline-block;
width: 33%;
}
I would choose "display: inline-block" as you don't have to clear the floating afterwards.
IDs "staff-1", "brian" and "DIV_2" are repeated. DOM id is unique.
You simply need to use css float to get them to be side by side.
.contact {
overflow: hidden;
}
.team {
float:left;
}
Here is your example code:
http://jsfiddle.net/jcfB3/
Note, your IDs were incorrect, you can't have 2 IDs that have the same value, I made them unique. Also, utilizing floats without any other content in a bounding block element has some issues which I fixed in the example code. See http://www.quirksmode.org/css/clearing.html for more info. It is the reason why I added overflow: hidden.
I'm looking to create something like the image shown:
I have managed to get the #wrap centred horizontally, but that's about it...
any help would be much appreciated.
<style>
#wrap
{
Margin-left:auto;
Margin-right:auto;
padding: 10px;
}
#content
{
padding: 10px;
}
</style>
~~~
<body>
<div id="wrap">
<div id="content">
1
</div>
<div id="content">
2
</div>
<div id="content">
3
</div>
</div> <!--end wrap-->
</body>
Since you're working with block elements (https://developer.mozilla.org/en-US/docs/HTML/Block-level_elements) you need the inner elment to have a fixed height so that you can give position: absolute. Additionally, keep in mind that the ID of an element has to be unique. If you want to use an element mulitple times assign a class name, e.g.
<div class="content">1</div>
<div class="content">2</div>
<div class="content">3</div>
So, for the whole matter have a look at http://jsfiddle.net/YFncP/253/
Hope this helps.
I have a site that has the following basic structure. This site should have a background that is white, with an image that apears once, but instead it just inherits the colour from the html{ } declaration in CSS. All elements below the element that should have the background are transparent, and even though the background is being added (checked in Firebug), it seems that this is below the background defined in html{ }.
This has only happened since I removed the declaration overflow: none; from #content-container, where as before that it worked. I need to remove this however, as changes that are occuring to the site require the nav menu to have dropdowns, so the container below has to allow overflow.
Is there a specific CSS reason why this is happening? Or anything else I need to provide for someone to be able to help? Thanks.
<div id="main-container">
<div id="header-container">
<div id="header-top">
{Code}
</div>
<div id="header-middle">
{Code}
</div>
<div id="header-nav">
{Code}
</div>
</div>
<div id="content-container">
<div id="content-left" class="index">
{Code}
</div>
<div id="content-right">
{Code}
</div>
</div>
<div id="footer-container">
{Code}
</div>
</div>
I'm guessing that #content-left and #content-right elements are floated? In which case the overflow: none on the #content-container was causing the element to self-clear. Without this, the element will not have a height because all the elements within it are floated, and therefore the containers' height cannot be calculated.
If you must use overflow: visible, the workaround is to place a div at the end of the containing element with clear: both set on it:
<div id="content-container">
<div id="content-left" class="index">
{Code}
</div>
<div id="content-right">
{Code}
</div>
<div class="clear"></div>
</div>
.clear { clear: both; }
I'm trying to position two panels and just can't get it to work...
I have a container-page wrapping two panels, each with it's own page. I want to position the panels side by side using float.
This is my CSS:
.pages {width: 100%; position: absolute;}
.leftPanel {position: relative; width: 25%; min-width:100px; float: left;}
.rightPanel {position: static;}
and HTML
<div class="page">
<div id="lefty" class="leftPanel">
<div class="page">
<p>helloworld</p>
</div>
</div>
<div id="righty" class="rightPanel">
<div class="page">
<p>HELLO WORLD</p>
</div>
</div>
</div>
I have to use position:relative for the left panel and position:static for the right panel. Strangely this works in JSBin but in my actual page, the right panel with position:static always has 100% width covering the whole screen.
Any hints on what I may be doing wrong?
Thanks!
div elements by default have a width of 100% of their parent. Since you floated the lefty div you took it out of the flow so what is happening is that the lefty div is effectively sitting outside the flow of the elements. Also float causes the div to shrink-wrap to the size of it's children. So if you are wanting to set the righty div to but up against the lefty div then you should do two things: first add float:left; position:relative; to the righty styling. Second you should add a div at the bottom of that to clear your floats.
On another note you should only use a class if you are going to be styling multiple elements the same way, otherwise just style the element off of the ID.
.pages {width: 100%; position: absolute;}
.leftPanel {position: relative; width: 25%; min-width:100px; float: left;}
.rightPanel {position: relative; float: left;}
<div class="page">
<div id="lefty" class="leftPanel">
<div class="page">
<p>helloworld</p>
</div>
</div>
<div id="righty" class="rightPanel">
<div class="page">
<p>HELLO WORLD</p>
</div>
</div>
<div style="clear:left;"></div>
</div>
Try floating both of the panels? As of right now only the left one is floated... try floating both of them to the left and then putting the correct amount of margin between them to line them up like you want them. Or even floating one left and the other right would probably work.
Add this to your CSS,
div.clear-both {clear: both;}
And change your HTML to this:
<div class="page">
<div id="lefty" class="leftPanel">
<div class="page"
<p>helloworld</p>
</div>
</div>
<div id="righty" class="rightPanel">
<div class="page">
<p>HELLO WORLD</p>
</div>
</div>
<div class="clear-both"></div>
</div>