I have 2 divs side by side. I don't know the height of them upfront, it changed according to the content. Is there a way to make sure they will always be the same height, even when one of them stretches, only with CSS?
I made a fiddle to show. I want the red and blue divs to be the same height...
http://jsfiddle.net/7RVh4/
this is the css:
#wrapper {
width: 300px;
}
#left {
width:50px;
background: blue;
float:left;
height: 100%; /* sadly, this doesn't work... */
}
#right {
width:250px;
background: red;
float:left;
}
You could try instead of using float, use display: table-cell. You might find some older browsers don't understand this rule however. See below:
#wrapper {
display: table; // See FelipeAls comment below
width: 300px;
}
#left {
display: table-cell;
width: 50px;
background: blue;
}
#right {
display: table-cell;
width: 250px;
background: red;
}
Antony answer works ok, but you need all the divs to have the same parent and to have a wrapper, I have a solution that use javascript but works with any kind of element, they just need to have the same selector.
function setEqualHeight(selector, triggerContinusly) {
var elements = $(selector)
elements.css("height", "auto")
var max = Number.NEGATIVE_INFINITY;
$.each(elements, function(index, item) {
if ($(item).height() > max) {
max = $(item).height()
}
})
$(selector).css("height", max + "px")
if (!!triggerContinusly) {
$(document).on("input", selector, function() {
setEqualHeight(selector, false)
})
$(window).resize(function() {
setEqualHeight(selector, false)
})
}
}
setEqualHeight(".sameh", true)
http://jsfiddle.net/83WbS/2/
I would recommend reading this article that explains how to do what you are trying to do. I would put a fiddle up that shows, but its pretty extensive and pure css. http://matthewjamestaylor.com/blog/equal-height-columns-cross-browser-css-no-hacks
There is a much simpler solution I want to point to. Using large padding-bottom: 500em and negative margin-bottom:-500em of the same amount on columns while the wrapper has simply overflow:hidden to cut the columns to the right size.
Found here:
HTML/CSS: Making two floating divs the same height
As indicated by Hexodus you can padding-bottom and margin-bottom, but a better solution would be to use flexbox or grid.
You can check this codepen if you want. I included a footer area because that is something I needed and it required a little bit more of hack.
.section {
width: 500px;
margin: auto;
overflow: hidden;
padding: 0;
}
div {
padding: 1rem;
}
.header {
background: lightblue;
}
.sidebar {
background: lightgreen;
width: calc(25% - 1rem);
}
.sidebar-left {
float: left;
padding-bottom: 500rem;
margin-bottom: -500rem;
}
.main {
background: pink;
width: calc(50% - 4rem);
float: left;
padding-bottom: 500rem;
margin-bottom: -500rem;
}
.sidebar-right {
float: right;
padding-bottom: 500rem;
margin-bottom: -500rem;
}
.footer {
background: black;
color: white;
float: left;
clear: both;
margin-top: 1rem;
width: calc(100% - 2rem);
}
<div class="section">
<div class="header">
This is the header
</div>
<div class="sidebar sidebar-left">
This sidebar could have a menu or something like that. It may not have the same length as the other
</div>
<div class="main">
This is the main area. It should have the same length as the sidebars
</div>
<div class="sidebar sidebar-right">
This is the other sidebar, it could have some ads
</div>
<div class="footer">
Footer area
</div>
</div>
You can do this without using tables, by using this CSS trick.
Example - http://jsfiddle.net/LMGsv/
HTML
<div id="wrapper">
<div id="columns">
<div id="left">text</div>
<div id="right">text<br/>another line<br /></div>
</div>
</div>
CSS
#wrapper {
float:left;
width: 300px;
}
#columns {
float:left;
width:300px;
background:blue;
}
#left {
float:left;
width:50px;
background: blue;
}
#right {
width:250px;
background: red;
float:left
}
Related
I have a responsive site that contains some elements that have the float: left css. For smaller screens, I want to move the second element beneath the first one.
HTML:
<div>A</div>
<div>B</div>
<div>C</div>
CSS:
div {
float: left;
}
Picture: Above the red line is the current layout, below it the desired layout for smaller screens. The size or alignment of the divs does not need to change.
Can I achieve this effect without wrapping divs A and B in a new div?
UPDATED: You can use clear:left on the div B then use translate-Y to let the C div on top;
body {
width: 100%;
height: 100%;
background-color: honeydew;
}
div {
display: inline-block;
padding: 36px;
}
#a {
float: left;
background-color: tomato;
}
#b {
float: left;
clear:left;
background-color: gold;
}
#c {
float: left;
background-color: skyblue;
-webkit-transform: translateY(-100%);
-ms-transform: translateY(-100%);
transform: translateY(-100%);
}
<div id=a>1.</div>
<div id=b>2.</div>
<div id=c>3.</div>
I'm not sure if you'd be interested in some jQuery, but let me provide a bit rough example, something like structural programming and could be surely cleaned up, but this allows you to add some classes and rearrange elements dynamically, without touching the HTML code at all.
<div class="first">A</div>
<div class="second">B</div>
<div class="third">C</div>
CSS:
.first {
float: left;
width: 100%;
}
.second {
float: left;
width: 100%;
}
.third {
float: left;
width: 100%;
}
#left-row {
width: 50%;
float: left;
}
.need-wrapper-right {
width: 50%;
float: right;
}
jQuery
jQuery(document).ready(function($) {
if ($(window).width() < 800) {
$(".second").detach().insertAfter(".first");
$(".first").addClass("need-wrapper-left");
$(".second").addClass("need-wrapper-left");
$(".third").addClass("need-wrapper-right");
$(".need-wrapper-left").wrapAll("<div id='left-row'>");
$(".second").detach().insertAfter(".first");
$(".third").insertAfter($("#left-row"));
}
});
Check the demo on Codepen (the code is set to rearrange elements below 800px). You can check the jQuery documentation about .detach(), addClass() and other functions.
EDIT: Also, you should use media queries so these CSS classes would apply only on lower resolutions.
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.
I want a layout with three boxes (two optional) like this:
[side box 1] [ main content
[side box 2] . main content ]
or
[ main content spans 100% if side boxes aren't provided ]
I want the main content box to span the entire height and width available in #load (minus margins) except if the side boxes are there, then I want it to only span up until those boxes (and their right margin).
My CSS:
#load {
margin: 10px;
height: 100%;
min-width: 1080px;
}
#primary,#secondaryOne,#secondaryTwo {
border-radius: 8px;
background: #f5f5f5;
border: 1px solid #ccc;
}
#primary {
float: right;
height: inherit;
width: 75%;
height:500px;
background:red;
}
#secondaryOne,#secondaryTwo {
min-width: 250px;
max-width: 300px;
height: 220px;
margin-right: 10px;
width: 20%;
clear:left;
float:left;
}
#secondaryTwo {
margin-top: 10px;
}
Simple HTML
<div id='load'>
<div id='primary'></div>
<div id='secondaryOne'></div>
<div id='secondaryTwo'></div>
</div>
JSFiddle
Problems
*SOLVED*Making #primary span the entire width if the sideboxes are missing.
*SOLVED*Is there a way to line the two sideboxes (#secondaryOne,#secondaryTwo) on the left side of #primary without nesting them in a separate div? If I use float: left on them, they line side by side, if I don't float them, the #primary generates below them, not beside them.
Solutions
Problem #1 was solved by joeytje50 using the secondary + primary tags and placing the secondary side boxes before the primary in HTML.
Problem #2 was solved in more than one way. The way I chose so that the secondary tags were placed together and before the primary was by NoobEditor using clear: left and a negative margin-top.
The solution can be found at: http://jsfiddle.net/v4cvv/67/
The main part of the solution is:
#primary {
width: 100%;
}
#secondaryOne + #primary, #secondaryTwo + #primary {
margin-top: -221px;
width: 75%;
}
Alternate Solution
One problem I found with the above solution, is it requires the two boxes and them to be the same height. A solution around this is by grouping the boxes in their own div. This solution is:
HTML
<div id='load'>
<div id="sideboxes">
<div id="boxOne" class="box"></div>
<div id="boxTwo" class="box"></div>
<div id="boxThree" class="box"></div>
</div>
<div id="primary" class="box"></div>
</div>
CSS
.box {
border-radius: 8px;
background: #f5f5f5;
border: 1px solid #fff;
}
#primary {
float: right;
display:block;
height: 97%;
width: 100%;
}
#sideboxes + #primary {
width: 75%;
}
#sideboxes {
float: left;
height: 97%;
width: 23%;
margin-right: 10px;
}
#sideboxes .box {
float: left;
height: 220px;
margin-bottom: 10px;
width: 100%;
}
The alternate solution no longer requires clear and can be extended for other uses. You may now also have 1, 2, 3, or however many boxes you want in the sideboxes div.
Thanks all for their help.
To answer your question about the primary box being 100% width when the secondary boxes are not there, you could do the following:
#primary {width:100%;}
.secondary + #primary {width:75%;}
If you put that CSS code at the bottom of your stylesheet, and then put the primary div tag after your first secondary div tag, then it'll by default be 100% wide, unless there's an element that has class="secondary". This won't change anything about the position the div is rendered, but it will fix your problem.
Alternatively, if your secondary divs are possibly hidden instead of not being there, you could do this:
#primary, .secondary.hidden + #primary {width:100%;}
.secondary + #primary {width:75%;}
That is, assuming you hide the secondary tabs via a class such as .hidden.
Here is a working version that becomes 100% width when the secondaries are removed, but still is 75% width when there is a .secondary element before it.
Keeping your HTML markup smae, here is the solution for your problem : demo
CSS
html.body {
height:100%;
}
#load {
margin: 10px;
height: 100%;
width:100%;
}
#primary, #secondaryOne, #secondaryTwo {
border-radius: 8px;
background: #f5f5f5;
border: 1px solid #ccc;
}
#primary {
float: right;
display:block;
height: 100%;
max-width:100%;;
width: 68%;
margin-top:-70%; /* this is the key */
}
#secondaryOne, #secondaryTwo {
width:30%;
height: 220px;
margin-right: 10px;
}
#secondaryTwo {
margin-top: 10px;
}
Problem #1
To get your #primary div to adapt it's width, you can use jquery to verify the presence of the .secondary divs and to set the an other width to the #primary div.
With .secondary demo
without .secondary demo
JQUERY:
if ($('.secondary').length){
$('#primary').css('width', '75%');
}
Problem #2
You can use clear:left; and by changing the order of the divs in your html markup you will have your 2 divs stacked on the left and your content div on the right.
FIDDLE
HTML:
<div id='load'>
<div id='primary'></div>
<div id='secondaryOne' class="secondary"></div>
<div id='secondaryTwo' class="secondary"></div>
</div>
CSS :
.secondary{
clear:left;
float:left;
}
Try
#primary {
min-width:75%;
max-width:100%;
}
http://jsfiddle.net/Paramasivan/v4cvv/65/
How can i construct above arrangement without using js ?
Thanks in advance !
#div3 {
display: inline-block;
}
#div1 {
min-width: 150px;
float: left;
}
#div2 {
max-width: 100%;
float: left;
}
http://jsfiddle.net/XCDsu/4/ - how can i fit the second div to content ? The first one has to be 150px not percent
all of those techniques in the other answers have a common problem.
they are assuming that the width of the first column is 150px, but actually you need min-width to be 150px. so what happens when the first column need to grow?
take a look at my solution. pure CSS, without using calc (so its also supported in older browsers like IE8)
Working Fiddle
HTML: nothing new here..
<div id="Container">
<div id="Column1">content</div>
<div id="Column2">content of second div is very very large</div>
</div>
CSS:
#Container
{
width: 80%; /*Change to WTE you want*/
display: table;
border: 1px solid black;
margin: 0 auto;
}
#Container > div
{
display: table-cell;
}
#Column1
{
background-color: red;
min-width: 150px; /*From your CSS*/
}
#Column2
{
background-color: green;
}
You could use the holy grail technique:
http://alistapart.com/article/holygrail
#div3 {
display: block;
background: blue;
padding-left: 150px;
}
#div1 {
width: 150px;
float: left;
margin-left: -150px;
}
#div2 {
width: 100%;
float: left;
}
What this does is create a 150px wide padding on the left of #div3, but it pulls #div1 into it with the negative margin.
This way the "100%" that #div2 uses is actually (100% - 150px) of #div3
If the width of #div1 is fixed at 150px and #div3 is dynamic, then you can use :
#div2 {
width : calc(100% - 150px);
}
And if #div1 is also dynamic, then you need to use JS.
I have a problem with some divs. In short here is what I need: 2 divs with a certain width (same width) - one with float left and one with right, and a third div that takes all the remaining space. The divs are using display : inline-block to have them on same line.
I have tried this :
<div class="wrapper">
<div class="control leftControl"></div>
<div class="display"></div>
<div class="control rightControl"></div>
</div>
And here is my css:
.wrapper {
width: 100%;
height: 100%;
min-width: 960px;
background-color: #E8E8E8;
}
.control {
width: 10%;
height: 100%;
display: inline-block;
background-color: #ADADAD;
}
.leftControl {
float: left;
}
.rightControl {
float: right;
}
.display {
width: 80%;
height: 100%;
display: inline-block;
}
The problem is that using % on some resolution causes the last div (controlRight) to be moved on a new line.I can understand why and found that if i use 79% on display the divs display almost correctly (1% left unsued.)
It is clear to me that this is not a correct solution.
Any help is appreciated.
You can put all your elements float:left and your 100% will always fit: fiddle
HTML
<div class="control"></div>
<div class="display"></div>
<div class="control"></div>
CSS
.control {
width: 10%;
height: 200px;
background-color: green;
float:left;
}
.display {
width: 80%;
height: 200px;
background-color:blue;
float:left;
}
Putting everything on float left will simply push divs one by one on the right.