Vertical Align variable height elements in fixed width container - html

Using display:table;, I am trying to vertically align two inline div's with different heights inside a fixed width container.
display:table; and display:table-cell with vertical-align: middle; is a very simple solution to this that works in certain circumstance - however in this it seems I have missed something.
The result of my fiddle is a correct vertical-align however each element is not holding their responsive widths to fill the entire container space. i.e. 2 elements inside the container equal 50% width.
Here is my code:
HTML
<div class="table container">
<div class="inner-column table-cell">
<div class="table inner-container">
<div id="left" class="table-cell">
content
</div>
</div>
</div>
<div class="inner-column table-cell">
<div class="table inner-container">
<div id="right" class="table-cell">
content
</div>
</div>
</div>
</div>
CSS
body {
width: 100%;
margin: 0 auto;
background: white;
color: white;
text-align: center;
background: white;
}
.table {display: table;}
.table-cell {display: table-cell; vertical-align: middle;}
.container {
width: 600px;
height: 200px;
background: lightgrey;
margin: 0 auto;
white-space: nowrap;
padding: 0
}
.inner-column {
display: inline-block;
white-space: normal;
width: 50%;
height: 100%;
border:1px blue solid;
padding: 0;
margin: 0;
}
.inner-container {
margin: 0 auto;
width: 100%;
}
#left {
background-color: red;
height: 120px;
}
#right {
background-color: purple;
height: 170px;
}
Here is the above in a FIDDLE
Problem List:
Width of the inner-column is slightly bigger than the container
each element container is not vertically aligned to the fixed height of the container.

display:table-cell is not being applied since you wrote this code before display:inline-block.
I have updated fiddle
https://jsfiddle.net/dgzp6h2w/1/

Related

How do I achieve horizontally aligned, gap-less, and centered div elements in container div

I have 3 elements that I would like to align horizontally, without gaps in between, and centered. I've accomplished lining them up horizontally and equally spaced, but want the touching, ie, to not have white space between them but to also take up 100% width of the page. This is generic html but applies to what I've done on my actual page:
CSS:
.content{
width: 100%;
height: 400px;
background-color:white;
text-align: justify;
}
.content .featureitem{
height: 100%;
width: 33%;
display: inline-block;
background-color:bisque;
margin: 0;
}
.content:after{
content: "";
width: 100%;
display: inline-block;
}
HTML:
<div class="content">
<div class="featureitem"></div>
<div class="featureitem"></div>
<div class="featureitem"></div>
</div>
I've tried using display:flex, but that leaves a gap on the right hand side. I want to achieve a row of 3 divs, that span 100% of the width with no gaps in between.
You can achieve this by removing the display: inline-block and adding float: left. Also you should consider calculating your width, since 3*33% != 100%:
.content .featureitem{
height: 100%;
width: calc(100%/3);
//display: inline-block;
float: left;
background-color:bisque;
margin: 0;
}
Fiddle
If you'd like to stick with display: inline-block; for layout, there are a number of ways to fight the space between inline block elements. There a number of good solutions in the CSS Tricks article. I typically use the negative margin option (it hasn't come back to bite me in a major way yet):
nav a {
display: inline-block;
margin-right: -4px;
}
or
nav a {
display: inline-block;
margin-right: -2px;
margin-left: -2px;
}
If you're open to another layout, you can use flexbox, or even center a float-based layout with a parent <div>, if that makes sense.
if you use inline-block elements and have indentation in the HTML code, there will be a white space in between each of them.(just like the one you leave in between words)
you may avoid any gap in html or use display : flex or table layout.
You can use HTML comment <!-- comment -->to erase the gap
.content{
width: 100%;
height: 400px;
background-color:white;
text-align: justify;
}
.content .featureitem{
height: 100%;
width: 33.33%;
display: inline-block;
background-color:bisque;
margin: 0;
}
.content:after{
content: "";
width: 100%;
display: inline-block;
}
<div class="content">
<div class="featureitem"></div><!--
--><div class="featureitem"></div><!--
--><div class="featureitem"></div>
</div>
or table/table-cell display
.content {
width: 100%;
height: 400px;
background-color: white;
text-align: justify;
display: table;
}
.content .featureitem {
height: 100%;
width: 33.33%;
display: table-cell;
background-color: bisque;
margin: 0;
}
<div class="content">
<div class="featureitem"></div>
<div class="featureitem"></div>
<div class="featureitem"></div>
</div>
or display:flex and flex:1
.content {
width: 100%;
height: 400px;
background-color: white;
text-align: justify;
display: flex;
}
.content .featureitem {
height: 100%;
flex: 1;
background-color: bisque;
}
.content:after {
content: "";
width: 100%;
display: inline-block;
}
<div class="content">
<div class="featureitem"></div>
<div class="featureitem"></div>
<div class="featureitem"></div>
</div>

How to center group of divs inside div?

I am a bit newbie with CSS and i am pretty obfuscated trying to center a group of divs inside a div. What i want:
divs 2,3 and 4 should be centered inside div1.
My approach:
.div1 {
display: inline-block;
margin: 0 auto;
text-align: center;
}
.restofdivs {
width: 470px;
margin: 20px;
min-height: 1px;
float:center
}
the result is: the 3 divs (2,3 and 4) one on top of another...
Regards,
This can easily be done with table display:
.table-display {
display: table;
width: 100%;
}
.cell-display {
display: table-cell;
}
.div1, .div2, .div3, .div4 {
padding: 40px;
}
.div1 {
background: #ABC;
}
.div2 {
background: #DEF;
}
.div3 {
background: #CAD;
}
.div4 {
background: #FAD;
}
<div class="div1">
<div class="table-display">
<div class="cell-display div2"></div>
<div class="cell-display">
<div class="div3"></div>
<div class="div4"></div>
</div>
</div>
</div>
Maybe set a width on .div1 and remove inline-block from .div1
.div1 {
width: 960px;
margin: 0 auto;
text-align: center;
}
.restofdivs {
width: 470px;
margin: 20px;
min-height: 1px;
}
The most common way to center a block element if you know it's width is to define the width and use "margin: 0 auto". This tells the browser to give a top and bottom margin of 0, and to automatically determine equal margins on the left and right.
Using floats, you can create the layout you described as follows:
http://jsfiddle.net/ynt4suee/
Markup:
<div>
<div id="one" class="border clearfix">one
<div id="wrapper">
<div id="two" class="border">two</div>
<div class="subcontainer">
<div id="three" class="border">three</div>
<div id="four" class="border">four</div>
</div>
</div>
</div>
CSS:
div.border{
border: 1px solid red;
}
div#wrapper{
width: 400px;
margin: 0 auto;
}
div#two{
width: 250px;
float: left;
}
div.subcontainer{
float: right;
width: 130px;
}
.clearfix:after {
content: " "; /* Older browser do not support empty content */
visibility: hidden;
display: block;
height: 0;
clear: both;
}
Here's another approach, using inline-block elements for the inner divs instead:
http://jsfiddle.net/xojqq4v5/
Markup:
<div id="one" class="border">
div 1
<div id="wrapper">
<div id="two" class="border">div 2</div>
<div id="subcontainer">
<div id="three" class="border">div 3</div>
<div id="four" class="border">div 4</div>
</div>
</div>
</div>
CSS:
div.border{
border: 1px solid red;
margin-bottom: 5px;
}
div#wrapper{
width: 450px;
margin: 0 auto;
}
div#two, div#subcontainer{
display: inline-block;
vertical-align: top;
}
div#two{
width: 300px;
}
div#three, div#four{
width: 140px;
}
Still, so long as you know the total width of the inner divs, you can center the wrapper using "margin: 0 auto", which has the advantage of not centering text on all child elements unless otherwise specified.
The difference here is that to lay out the inner divs in columns, div 2 and the container div containing divs 3 and 4 are defined as inline-block elements.

inline-blocks with width that amounts to 100% don't fit in one line

I want to have a div at the left side of a container, and a div on the right side of the container in the same line. I try to do so using inline-blocks, and text-align right for the right container.
http://codepen.io/anon/pen/WbbBzE
<div class="container">
<div class="left">
I'm on the left
</div>
<div class="right-container">
<div class="right">
I'm on the right
</div>
</div>
</div>
.container {
font-size: 0;
width: 100%;
}
.container > div {
font-size: 12px;
border: solid 1px black;
display: inline-block;
width: 50%
}
.right-container {
text-align: right;
}
For some reason, even though the parent container has font-size: 0, and the children are both 50%, they drop to the other line. Setting the width to 49% seems to work, but I don't understand why 50% doesn't when it should? Is there a better way to do it?
The width also is affected by the border on the elements. You can add box-sizing:border-box; to those divs to make them sit side by side.
.container {
font-size: 0;
width: 100%;
}
.container > div {
font-size: 12px;
border: solid 1px black;
display: inline-block;
width: 50%;
box-sizing: border-box;
}
.right-container {
text-align: right;
}
<div class="container">
<div class="left">I'm on the left</div>
<div class="right-container">
<div class="right">I'm on the right</div>
</div>
</div>

How do I distribute rows of varying heights evenly when parent height is 100%?

Below I have 3 rows (.child) with different heights.
The height of the parent (#parent) cannot be known in advance and it will actually change if the height of its parent (the parent of #parent) changes.
Is there some CSS combination that I could use that would set the margins between those rows in such a way that the rows are spread out evenly on the vertical ?
Similar to when we have cells with different widths that we want to spread out evenly on the horizontal. This is easy to achieve by using display: table-cell; I believe, even if the width of their parent is unknown.
JSFIDDLE : http://jsfiddle.net/7ty82k3b/5/
CSS :
#parent {
display: table;
position: fixed;
top: 0px;
left: 0px;
height: 100%;
width: 93px;
background-color : red;
}
.child {
position : relative;
float: left;
clear: both;
border: 1px solid blue;
display: table-row;
width: 91px;
}
span.child {text-align:center;}
HTML :
<body>
<div id="parent">
<img class="child" src="http://www.philreinhardt.com/downloads/SuperSqueezePages/Super%20Squeeze%20Page%20Pack/BonusMoreAnimatedArrows/More%20Animated%20Arrows/Arrow%20Right%201/Arrow%20Right%201%20Small/ArrowRightBlueSmall.gif">
<span class="child">Hey!</span>
<img class="child" src="http://www.philreinhardt.com/downloads/SuperSqueezePages/Super%20Squeeze%20Page%20Pack/BonusMoreAnimatedArrows/More%20Animated%20Arrows/Arrow%20Right%201/Arrow%20Right%201%20Small/ArrowRightBlueSmall.gif">
</div>
</body>
Wrap your .child inside some .row so you can display the .row as a table-row and the .child as a table-cell and then vertical-align: middle them. Also, keep in mind that images are crybabies that won't handle very well "exotic" displays, so don't try to display them as table-row or table-cell.
#parent {
display: table;
position: fixed;
top: 0px;
left: 0px;
height: 100%;
width: 93px;
background-color: red;
}
.row {
display: table-row;
}
.child {
position: relative;
border: 1px solid blue;
display: table-cell;
vertical-align: middle;
}
span.child {
text-align: center;
}
<div id="parent">
<div class="row">
<div class="child">
<img src="http://www.philreinhardt.com/downloads/SuperSqueezePages/Super%20Squeeze%20Page%20Pack/BonusMoreAnimatedArrows/More%20Animated%20Arrows/Arrow%20Right%201/Arrow%20Right%201%20Small/ArrowRightBlueSmall.gif">
</div>
</div>
<div class="row"> <span class="child">Hey!</span>
</div>
<div class="row">
<div class="child">
<img src="http://www.philreinhardt.com/downloads/SuperSqueezePages/Super%20Squeeze%20Page%20Pack/BonusMoreAnimatedArrows/More%20Animated%20Arrows/Arrow%20Right%201/Arrow%20Right%201%20Small/ArrowRightBlueSmall.gif">
</div>
</div>
</div>

how to apply vertical-align: middle at div

I've searched it at online and found some solution. But, nothing works at my project. At most of the solution, I've found:
<div class="a">
<div class="b">
Unknown stuff to be centered.
</div>
</div>
.a {
display: table;
width: 100%;
}
.b {
display: table-cell;
text-align: center;
vertical-align: middle;
}
By applying this technique, I've tried to build something like this: http://jsfiddle.net/L2GZx/1/
The text of left column only needed to be aligned middle vertically. But, it's not working with that technique:
<div class="row">
<div class="left">
<p>Sample Text</p>
</div>
<div class="right">
<p>Text</p>
<p>Input Element</p>
<p>Table</p>
<p>Image</p>
</div>
</div>
<div class="row">
<div class="left">
<p>Sample Text Sample Text Sample Text Sample Text Sample Text </p>
</div>
<div class="right">
<p>Text</p>
<p>Input Element</p>
<p>Table</p>
<p>Image</p>
</div>
</div>
<div class="row">
<div class="left">
<p>Sample Text</p>
</div>
<div class="right">
<p>Text</p>
<p>Input Element</p>
<p>Table</p>
<p>Image</p>
</div>
</div>
CSS:
.row {
width: 100%;
background: #ccc;
border-bottom: 1px solid #999;
display: table;
}
.left {
float: left;
width: 40%;
padding: 20px;
display: table-cell;
vertical-align: middle;
}
.right {
float: right;
background: #fff;
width: 40%;
padding: 20px;
}
How can I make the text of left-column aligned middle vertically? Note: I can't use any fixed height as content of each row will be different
Remove the floats. Floated elements can not also be displayed as table-cells. See updated Fiddle.
.row {
width: 100%;
background: #ccc;
border-bottom: 1px solid #999;
display: table;
}
.left {
width: 40%;
padding: 20px;
display: table-cell;
vertical-align: middle;
}
.right {
display: table-cell;
background: #fff;
width: 40%;
padding: 20px;
}
.left {
width: 40%;
padding: 20px;
display: table-cell;
vertical-align: middle;
}
removing" float:left " from .left style solves that issue, but using table and div together is not that good.Working Example
An alternative that I prefer in a situation like this is:
To not use display: table-cell, but rather use display:
inline-block.
To then use vertical-align: middle on the element.
Sample (revised) markup / css:
<div class="row">
<div class="left">
<p>Sample Text</p>
</div>
<div class="right">
<p>Text</p>
<p>Input Element</p>
<p>Table</p>
<p>Image</p>
</div>
</div>
CSS:
.row {
width: 100%;
background: #ccc;
border-bottom: 1px solid #999;
}
.row > div {
display: inline-block;
/* below 2 lines are IE7 hack to make inline-block work */
zoom: 1;
*display: inline;
/* below is consolidated css for both left / right divs */
width: 40%;
padding: 20px;
}
.left {
vertical-align: middle; /* or top or bottom */
}
.right {
background: #fff;
vertical-align: top; /* or middle or bottom */
}
All you have to do is to add a line-height to the left column and it will be automatically aligned (without vertical-align so you can remove it).
Here it is:
.left {
float: left;
width: 40%;
padding: 20px;
display: table-cell;
line-height:150px;
}
And here is your updated FIDDLE
Using your first example, try something like this. I'll explain how it works in the CSS.
<div class="a">
<div class="b">
Unknown stuff to be centered.
</div>
</div>
.a {
width: 100%;
position: relative; /* We want our parent div to be the basis of our absolute positioned child div */
/* You can set your height here to whatever you want */
}
.b {
position: absolute;
width: 100%; /* Set to be the full width, so that our text is aligned centered */
text-align: center;
top: 50%; /* Positions the top of the div at 50% of the parent height */
left: 0; /* Assures that the child div will be left-most aligned */
margin-top: -.5em; /* Moves the top of our div up by half of the set font size */
height: 1em; /* Sets our height to the height of the desired font */
}
Here is the JSFiddle link to see a live example: http://jsfiddle.net/L2GZx/20/
This is one of the best solutions to absolutely center text inside of a webpage. It does have it's limitations however seeing how it won't react to other elements inside the same parent and it also has to have a set height. So multiline text will have it's shortcomings with this method.
I hope this helps!