I have 3 section inside an div and div have a max-width: 1024px;. I make the first 1 float to left and the 3rd one float to right. But the 2nd one, I tried to set it in-between 1st and 3rd using margin: 0 auto;, it did not work...
How to align 3 divs (left/center/right) inside another div?
Here is my Jsfiddle example.
Something like [LEFT] [CENTER] [RIGHT]
here is a possible solution using CSS Calc()
The calc() CSS function can be used anywhere a <length>, <frequency>,
<angle>, <time>, <number>, or <integer> is required. With calc(), you
can perform calculations to determine CSS property values.
#wrap {
width: 100%;
max-width: 1024px;
border:1px dotted green;
font-size: 0; /*fix inline block gap*/
/* margin: 0 auto; - if you want the #wrap to be centered uncomment this line*/
}
.yolo {
width: 29.297%; /* 300px/1024px=0.29297 */
/*max-width: 300px; - this line should be commented if you want to fill the parent with the childs .yolo */
height: auto;
display: inline-block;
font-size: 16px /* show font due to font-size 0 in parent*/
}
.yolo:first-of-type {
background: yellow
}
.yolo:nth-of-type(2) {
background: gray;
width: calc(100% - 58.594%) /* width x 2 (29.297% x2) */
}
.yolo:last-of-type {
background: blue;
}
<div id="wrap">
<section class="yolo molo1">Hello</section>
<section class="yolo molo3">Hey</section>
<section class="yolo molo2">Hi</section>
</div>
UPDATE: OP's Comments below
1st:
Thanks, but i wanted to be 3 individual like there is a gap between
them
2nd:
Btw, Does calc() function in css work in every other browser?
Answer:
Snippet with gap between them
#wrap {
width: 100%;
max-width: 1024px;
border:1px dotted green;
font-size: 0; /*fix inline block gap*/
/* margin: 0 auto; - if you want the #wrap to be centered uncomment this line*/
}
.yolo {
width: 29.297%; /* 300px/1024px=0.29297 */
max-width: 300px;
margin-right:6%;
display: inline-block;
font-size: 16px /* show font due to font-size 0 in parent*/
}
.yolo:first-of-type {
background: yellow;
}
.yolo:nth-of-type(2) {
background: gray;
width: calc(100% - 70.594%) /* width: (29.297% x 2)+(6% x 2) */
}
.yolo:last-of-type {
background: blue;
margin-right:0
}
<div id="wrap">
<section class="yolo molo1">Hello</section>
<section class="yolo molo3">Hey</section>
<section class="yolo molo2">Hi</section>
</div>
CSS Calc() function works from IE9 and above.
If you switch the order of your div elements, you can get the result that you want as follows.
Float .molo1 to the left and .molo2 to the right.
Keep .molo3 as non-floated content and set the left/right margins to 35%, which is 70% divided by 2, 70% being the width left over after taking into account the width of the central div.
If needed, set margin: 0 auto to the wrapping element if you need to center it (optional).
#wrap {
width: 100%;
max-width: 1024px;
border: 1px dotted blue;
margin: 0 auto; /* if you want centering */
}
section.yolo {
width: 30%;
max-width: 300px;
}
section.molo1 {
background-color: yellow;
float: left;
}
section.molo2 {
background-color: blue;
float: right;
}
section.molo3 {
background-color: gray;
margin: 0 35%;
}
<div id="wrap">
<section class="yolo molo1">Hello</section>
<section class="yolo molo2">Hi</section>
<section class="yolo molo3">Hey</section>
</div>
Set width:33%; for each and get rid of the float:right.
Here: http://jsfiddle.net/29zatakh/
You can do this easily with Flex Box:Fiddle Sample
#wrap {
width: 100%;
max-width: 1024px;
display:flex;
}
.molo1, .yolo {
width: 30%;
max-width: 300px;
height: auto;
background: yellow;
justify-content:space-between;
margin:2em;
padding:1em;
}
.molo3 {
background: gray;
}
.molo2 {
background: blue;
}
Related
I have two divs next to each/side by side..
The LEFT div has a FLUID width.
The RIGHT div has a static wdth.
When I resize the screen/browser... it work great! (and as intended).
However because of the way it was set up:
(Fiddle example: http://jsfiddle.net/VHcPT/384/)
The RIGHT div in physically first in the mark-up..(and floated RIGHT).
However at say 768px breakpoint.. I need this RIGHT (static) DIV to stack UNDER the LEFT div.. how can I achieve this?
If I physically have the RIGHT div AFTER the LEFT div in the markup.. it would stack as expected.. but I need to have it FIRST so the fluid/static behavior in place works as it should.
So to re-cap, its NOT about getting the two divs next to each other one fluid, one static.. its how to handle that at a responsive/breakpoint.. and get the static (RIGHT) div to stack UNDER the fluid (LEFT) div
Using the fiddle example.. the RED DIV would go UNDER (stack) the GREEN lines/div.. (the green would then be full width).. at a certain breakpoint.
and because code is required now:
HTML:
<div id="contentcontainer">
<div class="rightcontainer">mm</div>
<div class="leftcontainer">
<div class="item_1">
some text
</div>
<div class="item_2">
some text
</div>
</div>
</div>
CSS:
#directorycontainer {
padding:10px 10px;
display:table;
box-sizing: border-box;
width: 100%;
font-size: 0.8em;
font-weight: normal;
}
.directory {
background: green;
margin-right: 10px;
overflow: hidden;
padding-right: 10px;
position: relative;
}
.mapcontainer {
background: red;
display:table;
width:240px;
height:480px;
float:right;
position:relative;
overflow: hidden;
}
.providercontainer{
background-color: #f7f9fb;
border: 1px solid #e1dacd;
display: table;
margin-bottom: 0.625em;
padding: 0;
width: 100%;
}
OK well looks like this works and should be an acceptable answer/solution:
Fiddle:
http://jsfiddle.net/VHcPT/389/
HTML/Markup:
<div id="contentcontainer">
<div class="leftcontainer">
<div class="item_1">
some text
</div>
<div class="item_1">
some text
</div>
</div>
<div class="rightcontainer">mm</div>
</div>
CSS:
* {box-sizing: border-box;}
#contentcontainer {
padding:10px 10px;
display:table;
box-sizing: border-box;
width: 100%;
font-size: 0.8em;
font-weight: normal;
}
.leftcontainer {
background: green;
overflow: hidden;
padding: 5px;
float:left;
width:calc(100% - 240px);
}
.rightcontainer {
background: red;
display:table;
width:240px;
height:480px;
float:left;
position:relative;
overflow: hidden;
}
.item_1{
background-color: #f7f9fb;
border: 1px solid #e1dacd;
display: table;
margin-bottom: 0.625em;
padding: 0;
width: 100%;
}
works with whatever breakpoints you set and the elements will stack correctly.
you may like my FLEXBOX alternative to you problem. It may take a bit of practice, but it will eventually give you much more control.
The FIDDLE
Below the basic CSS structure, no other 'display', 'position' or 'overflow' needed. With this structure you can mix-match any number of fixed and/or fluid columns.
.flex--box { display: flex; flex-flow: row wrap }
.flex--fluid { flex: 1 1 auto }
.flex--fixed { flex: 0 0 auto; min-width: 240px }
/* MOBILE MQ */
#media all and (max-width: 360px) {
.flex--fluid, .flex--fixed {
flex: 1 1 auto;
}
}
Let me know if you have problem with it.
And of course, do give credit if you think it is worth it.
( BTW: I changed the colors to something less retina intensive &D )
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 have the typical 3 column layout and I need it to be fluid (ish). The specs of the projects are: we need the container to go from 1024px to 1440px max (that's easy). And the center column needs to go from 514 (at 1024) to 626 (at 1440), the sidebars on both sides containing the rest of the space.
I don't see an easy way around this, I've played with max-width and min-width but since the proportions are not the same at the 2 breakpoints, I can't use percentage width to make the columns fill the space on higher resolutions.
Here is my code:
<div id="container">
<nav id="sidebar-left">Left</nav>
<section id="page">Center</section>
<div id="sidebar-right">Right</div>
</div>
#container{
min-width:1024px;
max-width: 1440px;
width: 100%;
margin: 0 auto;
overflow: hidden;
position: relative;
min-height: 100%;
}
#sidebar-left{
min-width: 230px;
max-width: 387px;
float: left;
background: red;
height: 300px;
}
#sidebar-right{
min-width: 230px;
max-width: 387px;
float: right;
background: blue;
height: 300px;
}
#page{
min-width: 514px;
margin: 0 20px;
max-width: 626px;
float: left;
background: purple;
height: 300px;
}
And I also made a fiddle:
https://jsfiddle.net/1y59nuxz/
I'd rather have a css only solution, I'm pretty sure is more or less easy to solve using jquery but I'd want to know if this is approachable with using it.
EDIT: I need this to be compatible with IE9+
Ok. You have several solutions to accomplish this task.
One solution is to change order of elements in your html (if possible):
<div id="container">
<nav id="sidebar-left">Left</nav>
<div id="sidebar-right">Right</div>
<section id="page">
<div class="page-inner">Center</div>
</section>
</div>
For "#page" use next css code:
#page {
overflow: hidden;
height: 300px;
}
.page-inner {
height: 100%;
margin: 0 20px;
background: purple;
}
Example code:
#page {
overflow: hidden;
height: 300px;
}
.page-inner {
height: 100%;
margin: 0 20px;
background: purple;
}
#container{
min-width:1024px;
max-width: 1440px;
width: 100%;
margin: 0 auto;
overflow: hidden;
position: relative;
min-height: 100%;
}
#sidebar-left{
min-width: 230px;
max-width: 387px;
float: left;
background: red;
height: 300px;
}
#sidebar-right{
min-width: 230px;
max-width: 387px;
float: right;
background: blue;
height: 300px;
}
<div id="container">
<nav id="sidebar-left">Left</nav>
<div id="sidebar-right">Right</div>
<section id="page">
<div class="page-inner">Center</div>
</section>
</div>
You can also check the fiddle.
Another solution is to apply flexbox. It's an elegant and easy way.
I think this layout can be achieved using some table & table-cell css like so:
basically set the .container to display: table
then set all direct children of the .container to display: table-cell
now these children will shrink/grow accordingly to their parent, however some tweaks have to be made for the #page to stay put at 626px widh and shrink down accordingly
max-width/min-width combo won't work on the #page div, however we can specify a fixed width, according to the max-width desired, in this case 626px, so that this div won't go past 626px width, but will shrink down if the window is resized
finally since we're using display: table-cell on these children divs, any margin prop. will be ignored, however we can mimic a margin using some border-left & right props. OR add another div inside the #page div that will hold the content and have some margin applied to it and the background accordingly.
Check out the demos bellow:
fake margins to the #page here
OR another div that holds the content for #page here
I have modified your code on fiddle
or else check the code below.
Html
<div class="content">
<div class="content__left">left</div>
<div class="content__right">Right</div>
<div class="content__middle">Center</div>
</div>
CSS
html, body, .container {
width: 100%;
height:100%;
min-width:1024px;
max-width: 1440px;
}
.content__left {
width: 20%;
max-width:200px;
float: left;
background: red;
margin-right:20px;
height:300px;
}
.content__middle {
min-width: 514px;
background: purple;
overflow: auto;
height:300px;
}
.content__right {
width: 20%;
max-width:200px;
float: right;
background: blue;
margin-left:20px;
height:300px;
}
Trying to stack 3 DIVs vertically, so that the top DIV is 25% of screen height, middle is 50%, and bottom is 25%, but they seem to extend the screen and I end up having a scrollbar.
body,html {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#top {
width: 100%;
height: 25%;
background: #464646;
}
#middle {
width: 100%;
padding: 15px 0 15px 0;
margin: 0 auto 0 auto;
min-width: 657px;
height: 50%;
text-align: center;
vertical-align:middle;
}
#bottom {
width: 100%;
padding: 15px 0 15px 0;
height: 25%;
background: #988056;
}
<div id="top"></div>
<div id="middle"><img src="logo.png"></div>
<div id="bottom"></div>
As Hashem mentions in a comment above, box-sizing: border-box is considered best practice nowadays. Add the following to your CSS and you should be good to go:
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
Here is a good read-up for you.
That said, if you are working on an existing product and have lots of legacy code that would be broken if you did this, you need to work around the margins and paddings on your site sections, they add height, and that makes it all add up to more than 100%.
And if you are uncomfortable with that as well, look up flex-box layout. Only works in modern browsers though, so don't do it if you need old IE support.
This is due to the padding that you have added to middle and bottom divs.
The width and height styles always specify the width/height of textual area i.e. width/height of the "div's content" and they do NOT include the padding value. The padding is an extra space added apart from the width/height.
Try the following, and it should give you the desired results:
HTML:
<div id="top"></div>
<div id="middle"><img src="logo.png"></div>
<div id="bottom"></div>
CSS:
body,html {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#top {
width: 100%;
height: 25%;
background: #464646;
}
#middle {
width: 100%;
margin: 0 auto 0 auto;
min-width: 657px;
height: 50%;
text-align: center;
vertical-align:middle;
}
#bottom {
width: 100%;
height: 25%;
background: #988056;
}
Working LIVE.
The CSS flexbox layout module is especially made to handle requirements like this.
You can use the flex-grow property:
The flex-grow property is a sub-property of the Flexible Box Layout module.
IT defines the ability for a flex item to grow if necessary. It accepts a unitless value that serves as a proportion. It dictates what amount of the available space inside the flex container the item should take up.
For example, if all items have flex-grow set to 1, every child will set to an equal size inside the container. If you were to give one of the children a value of 2, that child would take up twice as much space as the others.
*{
margin: 0;
padding: 0;
}
html,body {
height: 100%;
}
#container{
-webkit-display:flex;
-moz-display:flex;
-ms-display:flex;
display:flex;
-webkit-flex-direction:column;
-moz-flex-direction:column;
-ms-flex-direction:column;
flex-direction:column;
height:100%;
}
#top {
-webkit-flex:1;
-moz-flex:1;
-ms-flex:1;
flex:1;
background: #464646;
}
#middle {
-webkit-flex:2;
-moz-flex:2;
-ms-flex:2;
flex:2;
background:dodgerblue;
}
#bottom {
-webkit-flex:1;
-moz-flex:1;
-ms-flex:1;
flex:1;
background: #988056;
}
<div id="container">
<div id="top"></div>
<div id="middle"></div>
<div id="bottom"></div>
</div>
In this scenario, since you're concerned about screen height, you might want to investigate the 'vh' css rule.
For instance, if you wanted to stack your top, middle, and bottom evenly, you could do it with pure css:
#top, #bottom, #middle {
height: 32vh;
}
Or, as pertains to the question:
#top { height: 25vh; }
#middle { height: 50vh; }
#bottom { height 24vh; } /*24 vh so you have a little wiggle room*/
Examine here:
body { margin : 0; padding: 0}
div { border: #ccc solid 1px; }
#top { height: 25vh; }
#middle { height: 50vh; }
#bottom { height: 24vh; }
/*24 vh so you have a little wiggle room*/
<div id="top">top</div>
<div id="middle">middle</div>
<div id="bottom">bottom</div>
<!DOCTYPE html>
<html>
<head>
<title>Width issue</title>
<style type="text/css">
body {
margin: 0;
}
#left {
width: 50%;
background: lightblue;
display: inline-block;
}
#right {
width: 50%;
background: orange;
display: inline-block;
}
</style>
</head>
<body>
<div id="left">Left</div>
<div id="right">Right</div>
</body>
</html>
JSFiddle: http://jsfiddle.net/5EcPK/
The above code is trying to place the #left div and the #right div, side by side, in a single row. But as you can see in the above JSFiddle URL, this is not the case.
I am able to resolve the issue reducing the width of one of the divs to 49%. See http://jsfiddle.net/mUKSC/ . But this is not an ideal solution because a small gap appears between the two divs.
Another way I am able to solve the problem is by floating both the divs. See http://jsfiddle.net/VptQm/ . This works fine.
But my original question remains. Why when both the divs are kept as inline-block elements, they do not fit side by side?
Update: as it's 2021, use flexbox or even better - CSS grid layout instead of inline-block.
When using inline-block elements, there will always be an whitespace issue between those elements (that space is about ~ 4px wide).
So, your two divs, which both have 50% width, plus that whitespace(~ 4px) is more than 100% in width, and so it breaks. Example of your problem:
body{
margin: 0; /* removing the default body margin */
}
div{
display: inline-block;
width: 50%;
}
.left{
background-color: aqua;
}
.right{
background-color: gold;
}
<div class="left">foo</div>
<div class="right">bar</div>
There is a few ways to fix that:
1. No space between those elements
body{
margin: 0; /* removing the default body margin */
}
div{
display: inline-block;
width: 50%;
}
.left{
background-color: aqua;
}
.right{
background-color: gold;
}
<div class="left">foo</div><div class="right">bar</div>
2. Using HTML comments
body{
margin: 0; /* removing the default body margin */
}
div{
display: inline-block;
width: 50%;
}
.left{
background-color: aqua;
}
.right{
background-color: gold;
}
<div class="left">foo</div><!--
--><div class="right">bar</div>
3. Set the parents font-size to 0, and then adding some value to inline-block elements
body{
margin: 0; /* removing the default body margin */
}
.parent{
font-size: 0; /* parent value */
}
.parent > div{
display: inline-block;
width: 50%;
font-size: 16px; /* some value */
}
.left{
background-color: aqua;
}
.right{
background-color: gold;
}
<div class="parent">
<div class="left">foo</div>
<div class="right">bar</div>
</div>
4. Using a negative margin between them (not preferable)
body{
margin: 0; /* removing the default body margin */
}
div{
display: inline-block;
width: 50%;
margin-right: -4px; /* negative margin */
}
.left{
background-color: aqua;
}
.right{
background-color: gold;
}
<div class="left">foo</div>
<div class="right">bar</div>
5. Dropping closing angle
body{
margin: 0; /* removing the default body margin */
}
div{
display: inline-block;
width: 50%;
}
.left{
background-color: aqua;
}
.right{
background-color: gold;
}
<div class="left">foo</div
><div class="right">bar</div>
<hr>
<div class="left">foo</div><div class="right">
bar</div>
6. Skipping certain HTML closing tags (thanks #thirtydot for the reference)
body{
margin: 0; /* removing the default body margin */
}
ul{
margin: 0; /* removing the default ul margin */
padding: 0; /* removing the default ul padding */
}
li{
display: inline-block;
width: 50%;
}
.left{
background-color: aqua;
}
.right{
background-color: gold;
}
<ul>
<li class="left">foo
<li class="right">bar
</ul>
References:
Fighting the Space Between Inline Block Elements on CSS Tricks
Remove Whitespace Between Inline-Block Elements by David Walsh
How to remove the space between inline-block elements?
As #MarcosPĆ©rezGude said, the best way is to use rem, and add some default value to font-size on the html tag (like in HTML5Boilerplate). Example:
html{
font-size: 1em;
}
.ib-parent{ /* ib -> inline-block */
font-size: 0;
}
.ib-child{
display: inline-block;
font-size: 1rem;
}
good answer in css3 is:
white-space: nowrap;
in parent node, and :
white-space: normal;
vertical-align: top;
in div (or other) at 50%
exemple : http://jsfiddle.net/YpTMh/19/
EDIT:
there is another way with :
font-size: 0;
for parent node and override it in child node
EDIT 2021 : personaly, I recommand use flexbox now : https://the-echoplex.net/flexyboxes/
It's because the whitespace between your two divs is being interpreted as a space. If you put your <div> tags in line as shown below the problem is corrected:
<div id="left"></div><div id="right"></div>
Because there is a space between the elements. If you remove all whitespace, they will fit.
<div id="left">Left</div><div id="right">Right</div>
Either make them block instead of inline-block. This will render divs ignoring spaces between them.
display:block;
or remove space between tags
<div id='left'></div><div id='right'></div>
or add
margin: -1en;
to one of the divs in order to mitigate space taken by single space rendered.
Please check below code:
body {
margin: 0;
}
#left {
width: 50%;
background: lightblue;
display: inline-block;
float:left;
}
#right {
width: 50%;
background: orange;
display: inline-block;
float:left;
}
<div id="left">Left</div>
<div id="right">Right</div>
It can be done by adding the css display:inline to the div that holds the inline elements.
While removing the white space using margin with a negative value it becomes necessary to add it to this particular element. As adding it to a class will affect places where this class has been used.
So it would be safer to use display:inline;
Flexbox example - this would be used for the parent class holding the two side by side elements.
.parentclass {
display: flex;
justify-content: center;
align-items: center;
}
Taken from Vertically centering a div inside another div
add float: left; to both div tags.
div {
float: left;
}