Vertical-align not working as expected - css

As I was trying to get more familiar with vertical-align property I came across a problem. The default value of the property is baseline, which aligns the baseline of the element with the baseline of its parent. I made the h2 element at the bottom of the code display as inline-block to see how it behaves and that's when I got surprised. Shouldn't it show just right above the border of the body same as the blue box shows, instead of being somewhere in the centre of the body? It looks like aligning those boxes(divs) vertically affects where the baseline of the body is, but why? Please, click "Full page" when running the code snippet to see the behaviour.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vertical align</title>
<style>
body {border: 1px solid black; line-height: 1;}
.box {
display: inline-block;
width: 150px;
vertical-align: middle;
}
.tall {
height: 300px;
background-color: lightblue;
}
.short {
height: 100px;
background-color: green;
}
.middle {
height: 200px;
background-color: yellow;
}
.square {
display: inline-block;
width: 5px;
height: 5px;
background-color: red;
vertical-align: middle;
}
h2 {display: inline-block;}
</style>
</head>
<body>
<h1>Vertical Align</h1>
<div class="box tall"></div>
<div class="box short"></div>
<div class="box middle"></div>
<h2>Picture aligned <div class="square"></div> within text</h2>
</body>
</html>
I expected h2 to go down as you can see in the picture below.

I highly recommend reading this vertical-align article to gain in-depth understanding of the property.

The element is aligned this way because baseline aligns it with the baseline of the text inside the parent element.
In your case, the text baseline is pushed down by the large inline-block divs. The h2 aligns with this text. If you want it to align with the bottom of the other inline-elements (as shown in your image), add the style vertical-align: bottom to your h2.
This article explains the different vertical-align values very well:
https://css-tricks.com/what-is-vertical-align/

When you are using inline-block, it is better to handle your elements by positioning them.See my changes in css-style for h2.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vertical align</title>
<style>
body {border: 1px solid black; line-height: 1;}
.box {
display: inline-block;
width: 100px;
vertical-align: middle;
}
.tall {
height: 300px;
background-color: lightblue;
}
.short {
height: 100px;
background-color: green;
}
.middle {
height: 200px;
background-color: yellow;
}
.square {
display: inline-block;
width: 5px;
height: 5px;
background-color: red;
vertical-align: middle;
}
h2 {
display: inline-block;
width:300px;
size:10px;
vertical-align:bottom;
}
</style>
</head>
<body>
<h1>Vertical Align</h1>
<div class="box tall"></div>
<div class="box short"></div>
<div class="box middle"></div>
<h2>Picture aligned <div class="square"></div> within text</h2>
</body>
</html>

Related

Distribute 3 chlidren in a parent

I have a div with three divs in it like this:
#parent
#child-1
#child-2
#child-3
And I want it to look like this:
Child 2 should use up the available space vertically, because child-3 is display:none as default, and only on some event it would show up, so it should push child-2 up. child-3 should be as high as it needs to be as well.
I like to use flexbox, but I think I cannot use it here.
It would be really easy to put them in another div, and just do a flex on that box and flex-direction:column, but I do not have this opportunity, so they will be in the same div as child-1.
So what is the easiest way to accomplish this with pure CSS without touching the HTML structure?
Here's one working example:
#parent {
height: 50em;
}
div[id^=child] {
border: 2px solid black;
box-sizing: border-box;
}
#child1 {
height: 100%;
min-height: 32em;
background: red;
width: 30%;
float: left;
margin: 0;
}
#child2 {
height: 60%;
background: green;
width: calc(70% - .4em);
margin-left: calc(30% + .4em);
margin-bottom: .4em;
}
#child3 {
height: calc(40% - .4em);
min-height: 10em;
background: yellow;
width: calc(70% - .4em);
margin-left: calc(30% + .4em);
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>The HTML5</title>
</head>
<body>
<div id="parent">
<div id="child1">
</div>
<div id="child2">
</div>
<div id="child3">
</div>
</div>
</body>
</html>

Div nest structure

I have met a problem that i don't know where is wrong. my code is here:
<html>
<head>
<style type="text/css">
#top{
width:100%;
height: 78%;
background-color: #ccc;
}
#left{
width: 45%;
height: 100%;
display: inline-block;
background-color: green;
}
#right{
width:50%;
height: 100%;
display: inline-block;
background-color: pink;}
</style>
</head>
<body>
<div id="top">
<div id="left">
<div id="inside">asd</div>
</div>
<div id="right"></div>
</div>
</body>
</html>
if I add nothing to the "inside" div, then the layout would be alright , just like this:
but if i add any tag or even a few words in the "inside" dev .the layout would get wrong.
I'm new to HTML,so I don't know the problem,who can tell me why this happens? I've been driven crazy!!!help~~~~:(
You can use float (see the other answers), but you don't have to if you don't want to.
#left, #right { vertical-align:top; }
will get you what you want.
Aside: You should add <!DOCTYPE html> to the top of your page. In which case, you'll also need to add
html, body { height: 100% }
to your CSS.
try this:
#right{
width:50%;
height: 100%;
display: inline-block;
background-color: pink;
float:right;}
demo
You can resolve the issue by adding a float attribute in css.
Find the updated html template below
<html>
<head>
<style type="text/css">
#top{
width:100%;
height: 78%;
background-color: #ccc;
}
#left{
width: 45%;
height: 100%;
float: left;
background-color: green;
}
#right{
width: 50%;
height: 100%;
float: left;
background-color: pink;}
</style>
</head>
<body>
<div id="top">
<div id="left">
<div id="inside">test new</div>
</div>
<div id="right">test</div>
</div>
</body>
</html>
I would recommand to you twitter bootstrap for the layout of your div.
Using their css sheet.
<div id=top class=row-fluid>
<div id=right class=span6><div>
<div id=left class=span6><div>
</div>
The placement of block is way easier than with inline-block. All you need to get what you show in example is to add the background color. And float can easily become hard to handle.
there is also way to gain it by giving float to an element
#left {
width: 45%;
height: 100%;
/* display: inline-block; */
background-color: green;
float: left;
}
You're having a problem with block and inline. When the text appears, the browser puts the inside div into block display which ruins the inline styling. I'm not sure if there's a neat way around that using inline-block - you'll have to use float, I reckon.
Here's the float solution applied to your markup:
<html>
<head>
<style type="text/css">
#top {
width:100%;
height: 78%;
background-color: #ccc;
}
#left {
background:green;
float:left;
height:100%;
width:45%;
}
#right {
background:pink;
height:100%;
margin-left:45%;
width:50%;
}
</style>
</head>
<body>
<div id="top">
<div id="left">
<div id="inside">asdf</div>
</div>
<div id="right"></div>
</div>
</body>
</html>
Further, be careful of CSS height. It's a headache waiting to happen.

Empty span causes weird margin / padding

When I place a fixed size display-block <span> element inside a <div> it causes a weird margin or padding (I don't know) at the bottom of the <div>. When there is text inside the <span> element, everything is fine. What's the reason for this? How can I fix it? I tested on Firfox and Chrome.
Weird space http://picster.at/img/0/9/6/0968c75ddf29ad07cb71eee2cff472a9.png
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
<!--
.outer {
background: grey;
padding: 4px;
}
.inner {
display: inline-block;
background: cyan;
height: 40px;
width: 40px;
}
-->
</style>
</head>
<body>
<div class="outer">
<span class="inner">Foo</span>
</div>
<br>
<div class="outer">
<span class="inner"></span>
</div>
</body>
</html>
Update:
Floating would be an alternative to display-block elements. Perfectly valid, however I would like to understand what's wrong with display-block in this example. Also, it doesn't look like a white-space problem to me, as this would only affect margin to the left/right (correct me if I'm wrong).
It is because you are using inline-block;, this is the best example of how inline-block is different from floats
Demo
.outer {
background: grey;
padding: 4px;
overflow: hidden;
}
.inner {
float: left;
background: cyan;
height: 40px;
width: 40px;
}
inline-block leaves whitespace of 4px margin.
More Info
This hack works great for me.
Demo
.inner:after{
content: '\00a0';
}
inline-block is messing it up
If your intention of setting it as inline-block was to set a row of .inner's, set change the inner to block, and float left.
Then use a div with clear: both to fix the issue that normally the floating causes.
Here's your code modified:
<head>
<style type="text/css">
<!--
.outer {
background: grey;
padding: 4px;
}
.inner {
display: block;
background: cyan;
height: 40px;
width: 40px;
float: left;
margin-right: 4px;
}
.clear{
clear:both;
}
-->
</style>
</head>
<body>
<div class="outer">
<span class="inner">Foo</span>
<div class="clear"></div>
</div>
<br>
<div class="outer">
<span class="inner"></span>
<span class="inner"></span>
<div class="clear"></div>
</div>
</body>
</html>
It can be solved by setting the "line-height" of the outer element to 0. This solves pretty much every case.
Don't forget to make sure the inner element doesn't inherit that though, to do this you can just set it to "line-height:initial".
.outer {
background: grey;
padding: 4px;
line-height:0;
}
.inner {
display: inline-block;
background: cyan;
height: 40px;
width: 40px;
line-height:initial;
}

How to make a div stretch its height between two other divs and center its content

I want to make a one Column Layout with 3 section
Section 1: Header
Section 2: A Content Section that stretchs from beneth the header to the beginning of the footer, which has it's content centered vertically and horizontally within itsel
Section 3: Footer that always resides at the bottom of the browser window.
The Problem:
I can't get the content div to strech to the beginning of the footer/bottom div. If I enter height:100% it automatically stretches till the end of the whole page.
Also would like to center the content inside this middle div vertically and horizontally - though I have not yet attempted to do so.
Also don't understand why the background of the header text is not in color. even though the subheader divs are encapsulated by the header div which has background-color defined.
thanks!
http://jsbin.com/ixipug/1/edit
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
html {
height: 100%;
}
body {
height: 100%;
margin-left: 20px;
margin-top:0px;
margin-bottom: 0px;
}
#containerHeaderContent {
min-height:100%;
height: auto;
height: 100%;
margin: 0 auto -1.5em;
}
.push {
height: 1em;
}
.header {
background-color: aqua;
padding-top:20px;
}
.subheader-left {
float:left;
font-family: serif;
font-size: 20px;
text-align: left;
}
.subheader-right{
float: right;
font-family: sans-serif;
font-size: 12px;
padding-right: 20px;}
.middleSection {
padding-top: 10px;
clear:both;
width:100%;
height auto;
background-color: #e8e7e7;
}
.bottom{
background-color: red;
position: absolut;
height: 1em;
font-size: small;
}
.bottom-left {
float: left;
font: sans-serif;
left: 20px;
}
.bottom-right {
float: right;
right: 15px;
font-style: italic;
color: #8e8e8e;
font-size: 11px;
}
</style>
<title>XYZ</title>
</head>
<body>
<div id="containerHeaderContent">
<div class="header">
<div class="subheader-left">XYZ</div>
<div class="subheader-right">LOREM</div>
</div>
<div class="middleSection">Content Vertical and Horizontally Centered inside DIV</div>
<div class="push"></div>
</div>
<div class="bottom">
<div class="bottom-left">
<span class="about">
<span class="bold">XYZ</span> is a project by XZY. |
<span="address">Website Information</span> — info#info.com
</span>
</div>
<div class="bottom-right">
<span class="openinghours">Open by Appointment</span><span class=""> sponsored by XYZ</span>
</div>
</div>
</body>
</html><!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
</body>
</html>
2018 update
use flexbox or css grid. Here is a flexbox example. Css grid could be even simpler, but support is pretty low still:
body, html { padding: 0; margin: 0; }
header { background: #faa; }
article { background: #afa; }
footer { background: #aaf; }
.page {
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
}
article {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
}
<div class="page">
<header>header content</header>
<article>main content</article>
<footer>footer content</footer>
</div>
No need to use tables! Some simple css will do nicely.
DEMO: http://jsbin.com/azivip/2/edit
Html Markup:
<body>
<div id="content">
<div id="header">
This is the header
</div>
<div id="inner">
This is the body
</div>
<div id="footer">
this is the footer
</div>
</div>
</body>
CSS:
body{
height:100%;
padding:0px;
margin:0px;
}
#content{
position:relative;
bottom:0px;
width:100%;
height:100%;
}
#header{
position:relative;
bottom:0px;
width:100%;
height:100px; /* Edit for height of header*/
background:#f00;
}
#inner{
width:100%;
text-align:center;
position: absolute;
top: 50%;
display: table-cell;
vertical-align: middle;
}
#footer{
position:absolute;
bottom:0px;
width:100%;
height:100px; /* Edit for height of footer */
background:#0f0;
}
In order for #inner to stay centered vertically even with multi-line content, you'll need to use Javascript/jQuery. Below is an example script that "pulls up" #inner just the right amount to be centered.
var mrgntop = -Math.floor($("#inner").height() / 2);
$("#inner").css({"margin-top":mrgntop});
<table> is what you need to use in this case. The HTML will look like this, basically:
<table class = "wrapper">
<tr><td class = "header">I'm the header.</td></tr>
<tr><td valign = "middle" class = "content">Some content. Some content. More content. More content. Content is great. Content is a great thing to talk about when trying to insert random content to elaborate behavior. Content.</td></tr>
<tr><td class = "footer">I'm the footer.</td></tr>
</table>
Example CSS:
html, body, .wrapper {
height: 100%;
}
.header {
height: 100px; /*This value can be anything*/
}
.content {
text-align: center;
}
.footer {
height: 100px;
}
Demo: jsFiddle.
Note how the content is centered both vertically and horizontally.
Hope that helped!

Vertical align any inline element in any div using margin-auto

I am designing a text field which I want to be appear vertically-middle of a div. I want the black color div to be show vertically center of the blue (id=srch) div.
HTML & CSS:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style type="text/css">
* {
vertical-align:baseline;
font-weight: inherit;
font-family: inherit;
font-style: inherit;
font-size: 100%;
border:0 none;
outline:0;
padding:0;
margin:0;
}
html {
height:100%;
}
#outerwrapper {
width: 90%;
height: 100%;
min-height: 100%;
height: auto !important;
border: solid thin #333;
}
body {
height: 100%;
width: 100%;
}
#header {
height: 80px;
width: 100%;
background-color:#999;
}
input {
border:solid thin #ab1;
}
#srch{
height:50px;
background-color:#00f;
}
#srch div{
margin: auto 0 auto 0;
width: 200px;
background-color: #000;
}
#contentWrapper {
width: 100%;
overflow: auto;
background-color:#0F0
}
</style>
</head>
<body>
<div id="outerwrapper">
<div id="header">Header
<div id="srch">
<div>
<input type="tel" name="aa"/>
</div>
</div>
</div>
<div id="contentWrapper">
Content Wrapper
</div>
</div>
</body>
</html>
My approach: I give the black div top and bottom margin auto but it is not working (also for the horizontal center [left and right margin:auto] it is working). Does margin:auto only work for left and right?
I want to know why this is happening, and I don't want any other solution like:
Display text inline with a vertical-align div.
Display with proper padding or margin.
margin: auto does not work for top and bottom. If margin-top: auto or margin-bottom: auto is specified, their used value is 0. Here's an article about how you can achieve vertical centering.
You need to use some jQuery here to calculate the height of parent container.
Demo - http://jsfiddle.net/tQBVy/

Resources