Vertically aligning floating divs in modern browsers (2014) - html

I'd like to ask this question again as its previous incarnation was half a decade ago. We need not consider anything pre-IE9 for the purposes of this discussion:
I am trying to float two divs with different font-sizes. I can't find a way to align the text on the same baseline. Here is what I have been trying:
<div id="header">
<div id="left" style="float:left; font-size:40px;">BIG</div>
<div id="right" style="float:left;">SMALL</div>
</div>
I am struggling with this currently and the best solution I've found is magic offsets from inspection, and that's hardly robust. Inline-block has its own issues I'd prefer to avoid.
Edit:
http://jsfiddle.net/crw4r/10/
As you can see, floats align at the top, not at the baseline.

You could use display: table-cell instead of floats?
#header {
display: table;
width: 100%;
}
#header div {
display: table-cell;
}
#left {
font-size: 40px;
}
#right {
text-align: right;
}
Demo

Set the line-height to be the same on both.
http://jsfiddle.net/crw4r/6/
eg.
line-height: 42px;
or if this is not what you want...
you could use absolute positioning.
http://jsfiddle.net/crw4r/7/
or, you could set the line height on both and add margin to the top of the smaller one, so the sum of the line-height and top margin are the same on both text.
http://jsfiddle.net/crw4r/13/

With display: inline-block, the divs are automatically aligned on the baseline. To compensate for the float, you can use text-align
#left {
display: inline-block;
width: 50%;
font-size: 40px;
text-align: left;
}
#right {
display: inline-block;
width: 50%;
text-align: right;
}
See JSFiddle
If you need to account for white space, use width: 49% for one of the divs
JSFiddle

<div id="container">
<div class="left"><span>Big</span></div>
<div class="right"><span>Small</span></div>
</div>
#container{
width:100%;
margin:0px auto;
}
#container div{
position:relative;
height: 42px;
width: 100px;
}
#container div span{
position:absolute;
bottom:0;
right:0;
}
.left{
float:left !important; font-size:40px;
}
.right{
float:right !important;
}

Try below css and html
CSS
.header {
overflow: hidden;
width: 200px;
display:table;
}
.header > div{
display:table-row;
}
.header > div > div{
display:table-cell;
vertical-align:baseline;
width:50%;
}
.big {
text-decoration: underline;
font-size: 40px;
}
.small {
text-decoration: underline;
font-size: 12px;
}
HTML
<div class="header">
<div>
<div class="big">BIG</div>
<div class="small">SMALL</div>
</div>
</div>

Related

Conflict between making a div a clickable link and vertical centering

To make the rounded boxes (see http://jsfiddle.net/L36nq/) clickable/hoverable, I need to use
a {
display: block;
}
Yet to keep the images (the two squares) centered, I need to use
#left {
display:table;
...
}
#right {
display:table;
...
}
How do I make the full rounded boxes clickable/hoverable while keeping the images centered?
HTML
<div id="left">
<div id="cell">
<a href="http://google.com/">
<img src="box.svg" width="75%" height="75%" />
</a>
</div>
</div>
<div id="right">
<div id="cell">
<a href="http://bing.com/">
<img src="box.svg" width="75%" height="75%" />
</a>
</div>
</div>
CSS
#left {
display:table; position:absolute;
top:25%; left:25%; width:24%; height:50%;
vertical-align:middle; text-align:center; margin: auto; border-radius:30px;
background-color: #D88;
}
#right {
display:table; position:absolute;
top:25%; left:51%; width:24%; height:50%;
vertical-align:middle; text-align:center; margin: auto; border-radius:30px;
background-color: #88D;
}
#cell {display:table-cell; vertical-align:middle;}
a {
display: block;
}
body { background-color: #9D9; }
a {
display: block;
min-width: 100%;
min-height: 100%;
position:absolute;
top:0;
}
Your anchor tag is not inheriting and height or width so it's essentially 0x0 px. The above css worked for me in fiddle: http://jsfiddle.net/MkfAe/
Something like this might work for you. http://jsfiddle.net/ZNXvT/1/
I'm taking your #cell elements and keeping them as block-level elements, and setting a height: 100%; on them. I also set height: 100%; on your anchor element.
#cell {
height: 100%;
}
a {
display: block;
height: 100%;
}
Now onto the magic. You can add an element inside the a (I called mine .valign-height) and set that as height: 100%;, and also add a vertical-align: middle;.
a .valign-height {
display: inline-block;
height: 100%;
vertical-align: middle;
width: 0;
}
Then with the image (or svg) itself, I set that to vertical-align: middle;.
a img {
vertical-align: middle;
}
An element is not able to be vertically-aligned by itself, as vertical-align aligns to its siblings. If we have a hidden element that will spoof the vertical-align for you, it will center your content always. This way, you can keep the anchor filling the space, and keep your img element vertically centered.

Position div within a list item in the middle

I have a div in a list item which is floated right. The div positions it self at the top right corner of the list item. Is it possible to position it in the middle-right without the use of padding or margins?
---------------
DIV
---------------
Needs to be:
---------------
DIV
---------------
I made a bunch of assumptions and didn't bother check this first.
li {
height: 32px;
}
li div {
width: 100%;
line-height: 32px;
text-align: center;
}
You could use the table cell method.
<div class="wrap one">
<div class="inner-wrap">
<div class="inner">Test</div>
</div>
</div>
With the CSS defining a parent as a table, then table-cell with vertical align:
.wrap .inner {
background: white;
float: right;
}
.wrap.one {
display: table;
width: 100%;
}
.wrap.one .inner-wrap {
display: table-cell;
vertical-align: middle;
}
Demo: http://jsfiddle.net/vFqSC/
If you want the div to take up the full space you could position the div this way:
li div {
float: right;
height: 100%;
}
or if you don't want it to take up the full space
li div {
position: absolute;
right: 0px;
top: 50%;
height:80%;
margin-top:-40%; // Half of height
}
If you have a hard coded list height and div height:
li { height: 50px; }
li div {
position: absolute;
right: 0px;
height:30px;
top: 10px;
}
There are many ways to do this, you should provide more information on how you want it to behave and look
Yes, you can, but margin or padding is the preferred method, but you could use relative positioning and assess a amount along on vertical axis. fiddle: http://jsfiddle.net/De4CV/1/
div {
width:200px;
height:200px;
background:#333;
}
div p {
font:1em normal Futura, sans-serif;
color:#f5f5f5;
text-align:right;
position:relative;
top:90px;
}
<div class="div">
<p>Hello there!</p>
</div>

Two inline-block elements, each 50% wide, do not fit side by side in a single row

<!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;
}

Inline-block elements expanding space below

Creating a page layout using inline-block elements (vertically aligned to the top). The only issue, is that inline-block elements below another set of inline block elements will not fold into open space like floated elements do. It's almost as if it obeys row-like rules. Are there any fixes for this?
Layout example in JSFiddle
CSS
* {
font-family:helvetica;
font-size:18px;
}
.container {
margin:0 auto;
width:90vp;
}
.main_content {
background:red;
display:inline-block;
vertical-align:top;
box-sizing:border-box;
width:76.04%;
min-height:200px;
}
.content_details {
background:blue;
display:inline-block;
vertical-align:top;
box-sizing:border-box;
width:22.39%;
margin-left:01.56%;
min-height:250px;
}
.comments {
background:green;
display:inline-block;
vertical-align:top;
box-sizing:border-box;
width:76.04%;
min-height:150px;
}
HTML
<div class="container">
<div class="main_content">
<h1>Main Content</h1>
</div
><div class="content_details">
<h2>Details</h2>
</div
><div class="comments">
<h2>Comments</h2>
</div>
</div>
Please note I can change the mark-up to create only two inline-block elements (creating two columns), however I would like to know if there is a fix for 3 separate inline-block elements (like in the JSFiddle example), that way I wouldn't need to add extra mark-up.
No there isn't.. Not like you are talking about. You'd have to use:
<div id="col1">
<div id="maincontent"></div>
<div id="comments"></div>
</div>
<div id="details"></div>
Then you would have #col1 and #details as inline-block elements.
The whole point of an inline-block is that it is inline (i.e. on a line with other elements) it isn't acting like a table as you suggested, it's acting like a line of text (as it should) that is wider than it's container and breaking to the next line down.
See here: http://jsfiddle.net/GXmM6/ for a working example
Neither floats nor inline-block will do what you want there, unless you wrap each column in its own div. Short of that, there are JavaScript solutions for doing this, such as Masonry. (It involves a lot of positioning, though.)
Did I get it right that you wanted the .content_details to be a sidebar? Then I just changed it from display: inline-block to float: right to place .comments seamlessly beneath your .main-content. See http://jsfiddle.net/koivo/7UqqF/ for working example. Think that even works just with display: block ...
* {
font-family: helvetica;
color: white; /* added */
font-size: 18px;
}
.container {
margin: 0 auto;
width: 90vp;
}
.main_content {
background: red;
display: inline-block;
vertical-align: top;
box-sizing: border-box;
width: 76.04%;
min-height: 200px;
}
.content_details {
background: blue;
/* display: inline-block; */
float: right; /* added */
vertical-align: top;
box-sizing: border-box;
width: 22.39%;
margin-left: 01.56%;
min-height: 250px;
}
.comments {
background: green;
display: inline-block;
vertical-align: top;
box-sizing: border-box;
width: 76.04%;
min-height: 150px;
}

How can I vertically align two floated divs?

I have two divs inside a container div. One need to float left the other float right. They also both need to be vertically centered inside their parent. How can I achieve this?
<div id='parent'>
<div id='left-box' class='child'>Some text</div>
<div id='right-box' class='child'>Details</div>
</div>
If no float is applied to either they vertically align to the middle with this css
.child{ display:inline-block; vertical-align:middle; }
However adding #right-box{ float: right; } causes the children to lose their vertical alignment. What am I doing wrong?
Thanks guys
here is the online demo of the solution you needed
it was made with this html:
<div id='parent'>
<div id='left-box' class='child'>Some text</div>
<div id='right-box' class='child'>Details</div>
</div>
and this css:
#parent {
position: relative;
/* decoration */
width: 500px;
height: 200px;
background-color: #ddd;
}
.child {
position: absolute;
top: 50%;
height: 70px;
/* if text is one-line, line-height equal to height set text to the middle */
line-height: 70px;
/* margin-top is negative 1/2 of height */
margin-top: -35px;
/* decoration */
width: 200px;
text-align: center;
background-color: #dfd;
}​
#left-box { left: 0; }
#right-box { right: 0; }
You can try the display:table and display:table-cell styles.
Check this site out for more details http://www.quirksmode.org/css/display.html
NB: if you want the parent div height to be a percent (like 100%), then it will be relative to the height of it's container. If the container is the body, then you will have to set the body and html's height as well, like to 100%.
Here's an example of what the code might look like:
<div id='parent'>
<div id='left-box'>Some text</div>
<div id='right-box'>Details</div>
</div>​
<style>
body,html{
height:100%;
}
#parent{
border:1px solid red;
display:table;
height:100%;
width:100%;
}
#left-box{
background-color:#eee;
display: table-cell;
vertical-align:middle;
padding:3px;
width:50%;
}
#right-box{
background-color:#dddddd;
display: table-cell;
vertical-align:middle;
padding:3px;
width:50%;
}
​</style>