vertically align for floated element - css

fiddle
I've the following markup:
<div id="all">
<div id="one">one</div>
<div id="two">two</div>
<div id="main">main para goes here</div>
</div>
and the following css:
#all{
height: 300px;
background: red;
}
#one{
float: left;
}
#two{
float: right;
}
#main{
margin: 0 auto;
width: 250px;
}
I wanted to align vertically but no success even after using pseudo technique. Vertical alignment should work at least ie8.
Please note: I can't change the markup. It means I can't avoid using float.
So, is there any way to make it success?

Well, using CSS floats gives no chance to align the floated element vertically in their container (regardless of using CSS flexible box method).
Hence I'd go with inline-blocks so that I can align them by vertical-align: middle declaration.
So far so good, but the #two element must be positioned at the right side of the container without using CSS floats. Hence we have to specify width of the columns to reorder the columns via relative positioning:
To get this approach to work on IE8, we have to use percentage units for the width columns. Saying that we'll end up with:
EXAMPLE HERE
#all {
height: 300px;
width: 100%;
font-size: 0; /* To remove the white-space between inline-block columns */
}
#all:before {
content: "";
display: inline-block;
vertical-align: middle;
height: 100%;
}
#one, #two, #main {
display: inline-block;
vertical-align: middle;
position: relative;
font-size: 16px; /* Reset the font-size to the default value */
}
#one, #two { width: 30%; }
#two { left: 40%; text-align: right; } /* Push the column to the right by 40% */
#main{ right: 30%; width: 40%; } /* Pull the column to the left by 30% */
This will work on IE8+ (not remember the requirements of IE6/7). However for IE9+ we can use calc() expression to specify the width of columns like so:
Example Here
#one, #two {
width: calc((100% - 250px) / 2);
}
#two{
left: 250px;
text-align: right;
}
#main{
right: calc((100% - 250px) / 2);
width: 250px;
background-color: orange;
}

Demo
Using flex-box
css
#all{
height: 300px;
background: red;
display: flex;
align-items:center
}
#one{
float: left;
order: 1;
}
#two{
float: right;
order: 3;
}
#main{
margin: 0 auto;
width: 250px;
order: 2;
}

Using a bit of jquery and css you can easily center the elements that you want:
CSS
div{
outline:solid gray 1px;
}
#all{
height: 300px;
}
#one{
float: left;
position:relative;
}
#two{
float: right;
position:relative;
}
#main{
margin: 0 auto;
width: 250px;
position:relative;
}
JS
function center(element){
var all = $("#all");
if(element.height()<all.height()){
element.css(
"top",
((all.height()/2)-(element.height()/2))+"px"
);
}
}
center($("#one"));
center($("#two"));
center($("#main"));
FIDDLE
http://jsfiddle.net/ovkgzmdv/5/

Related

Responsive layout managing percentages

I'm trying to make my own responsive layout using percentages. I managed to calculate the columns that I wanted to use but I can't work out how to put like a margin (gutter) in between columns. If you check the codepen code there is no spacing in between the contents.
Codepen
.container{
width: 90%;
max-width: 1140px;
margin: 0 auto;
/*background: #333;*/
}
.container .columns{
float: left;
background: #ccc;
margin: 0 0 1em ;
padding-right: 1em;
padding-left: 1em;
border-left-width:12px;
}
.row{
float: left;
clear: both;
width: 100%;
}
.container .columns.col-1 { width: 8.33333333333%; }
.container .columns.col-2 { width: 16.6666666667%; }
.container .columns.col-3 { width: 25%; }
.container .columns.col-4 { width: 33.3333333333%; }
.container .columns.col-5 { width: 41.6666666667%; }
.container .columns.col-6 { width: 50%; }
.container .columns.col-7 { width: 58.3333333333%; }
.container .columns.col-8 { width: 66.6666666667%; }
.container .columns.col-9 { width: 75%; }
.container .columns.col-10{ width: 83.3333333333%; }
.container .columns.col-11{ width: 91.6666666667%; }
.container .columns.col-12{ width: 100%; }
I would personally shy away from Calc as it's still not fully supported but up to you — http://caniuse.com/#feat=calc
I would recommend wrapping all of your content in another set of elements that way you can use padding for spacing and margin for alignment. Check out the demo.
<div class="columns col-6"><div>6</div></div>
DEMO
Instead of giving padding give margin
.container .columns{
float: left;
background: #ccc;
margin: 0 0 1em ;
margin-right: 1em;
margin-left: 1em;
border-left-width:12px;
}
Use calc() method to calculate margin from width.For example for .col-3 the CSS would be
.container .columns.col-3 {
width: calc(25% - 5px);
margin-right:5px;
}
make sure you use calc() in right way like this
calc([first value][space][operator][space][second value])
If you see your columns width, You have divided 100% of the viewport width equally.
For example:
.container .columns.col-6 {
width: 50%;
}
So in that case, you won't have any space between two blocks.
So while mentioning the width for the columns, you need to consider margin as well.
so you can use either of the following two approaches:
.container .columns.col-6 {
width: calc(50% - 10px); // 10px represents the margin / space
margin-right:10px;
}
or
.container .columns.col-6 {
width: 46%;
margin-right: 1%;
}
The first approach is better.

How to set two floated divs to be the 100% height of the page

There are two floated divs of different height inside a wrapper div. I need both of them to be 100% of height of the body i.e. of the same height. Also used clearfix. But height:100% doesnt seem to work. How to do this?
Demo
Html:
<div class="wrapper">
<div class="primary">
<img src="http://demo1.opentaps.org/images/products/small/gis_computer_glen_rolla.png" />
</div>
<div class="secondary">
<img src="http://demo1.opentaps.org/images/products/small/gis_computer_glen_rolla.png" />
</div>
<div class="clearfix">
</div>
</div>
CSS:
body {
min-height: 100vh;
background-color: green;
margin: 0;
}
.wrapper{
background-color: blue;
height: 100%;
}
.primary{
float: left;
width: 80%;
height: 100%;
background-color: yellow;
}
.primary img{
height: 100px;
width: 100px;
}
.secondary{
float: right;
width: 20%;
background-color: red;
height: 100%;
}
.secondary img{
height: 500px;
width: 100px;
}
.clearfix{
clear: both;
}
All you need to do is add a height of 100% to the html and body tags like so:
html, body {
height: 100%;
}
Demo:
http://jsbin.com/EsOfABAL/1/
if you want to use vh units (seen in your code), it does makes it easier, no need to worry about 'heritage' and see your columns being stopped at 100% height of the window.
if you mix the method of faux-column and clear fix , you need to set only once min-height:100vh; on the floatting element.
Your yellow background has to be drawn in the wrapper and the red one in the non-floatting element wich is stretch with the clearfix method.
body {
margin: 0;
}
.wrapper{
background-color: yellow;
overflow:hidden;
}
.primary{
float: left;
width: 80%;
min-height:100vh;
}
.wrapper .primary img{
height: 100px;
/* width:1000px; */
width: 100px;
}
.secondary .overflow{
margin-left:80%;
background-color: red;
}
.overflow:after {
content:'';
height:0;
display:block;
clear:both;
}
.secondary img{
height: 500px;
/*height:100px;*/
width: 100px;
}
uncomment height value for image to check behavior and drawing of your page, scrolling or not .
http://codepen.io/anon/pen/chHtK
Hope this helps you to understand the use of vh (or vw) units , for the faux-column and clearfix methods, it's just a reminder of old methods :)
Enjoy
The html element also needs to be 100% - try this:
html { height: 100%; }
body {
height: 100%;
background-color: green;
margin: 0;
}

How to make side-by-side blocks fill the rest of the container when one is fixed size?

I have two blocks that are side-by-side. One size is fixed, 90px and other one is not, I want the other one to extend itself to the rest of the container since container size is will be changing.
Here is fiddle with commends displaying the problem: http://jsfiddle.net/L6CSG/
HTML
<div class="container">
<span class="left"></span>
<span class="right"></span>
</div>
CSS
.left, .right {
height: 30px;
display: inline-block;
margin: 0px;
float: left;
}
.left {
background: green;
width: 90px;
}
.right {
background: blue;
width: 100%; // How can I make it fit the rest of the container?
}
.container {
width: 400px; // This value is NOT STATIC
}
You can do it by pure CSS, here is working example jsFiddle
Make sure filler element is last in DOM tree
Make sure rest of the elements have position: relative specified and width+height
This is nice trick I learned:
HTML:
<div id="container">
<div class="left"></div>
<div class="rest"></div>
</div>
CSS:
#container {
width:50%;
height: 50px;
background-color: red;
min-width: auto;
}
.left {
position: relative;
float: left;
width: 90px;
height: 100%;
background: blue;
}
.rest {
display: block;
height: 100%;
overflow: hidden;
background: yellow;
}
Solution 1:
Make the width of .right width: calc(100% - 90px);
Solution 2:
http://jsfiddle.net/L6CSG/4/ In case of this solution you should probably use divs instead of span since I changed your spans to block elements.
You have to set float: left only for the left one
see result:
http://jsfiddle.net/L6CSG/2/
also you need display: block and width: auto for the right one
Here is the solution:
HTML:
<div class="container">
<span class="left"></span>
<span class="right"></span>
</div>
CSS:
.left, .right {
height: 30px;
margin: 0px;
display: block;
}
.left {
background: green;
width: 90px;
float: left
}
.right {
background: blue;
width: auto;
}
.container {
width: 400px;
}
JavaScript is needed to calculate the extra space that can be filled, as the container is not a fixed width.
var con = document.querySelector(".container");
var left = document.querySelector(".left");
var right = document.querySelector(".right");
window.addEventListener('resize', function() {
calcSize();
});
function calcSize() {
var diff = con.offsetWidth - left.offsetWidth;
right.style.width = diff + "px";
}
calcSize();
http://jsfiddle.net/L6CSG/7/

Element must cover whole page except 20px margin

I need create element, that cover whole page except 20px margin on all sides. I try this and it works in webkit browsers and Firefox, but Internet Explorer (10) and Opera have problem with this :-( . Any idea how to solve this?
HTML
<div id="first">
<div id="second">
Hello world!
</div>
</div>
CSS
head, body
{
width: 100%;
height: 100%;
}
body
{
position: absolute;
margin: 0;
background-color: blue;
display: table;
}
#first
{
display: table-cell;
height: 100%;
width: 100%;
padding: 20px;
}
#second
{
height: 100%;
width: 100%;
background-color: white;
}
I'd suggest:
#first {
display: table-cell;
position: absolute;
top: 20px;
right: 20px;
bottom: 20px;
left: 20px;
}
Which will position the element 20px away from each of the sides. However I'd suggest not using display: table-cell; since that requires a parent element to have display: table-row which itself then requires a parent element with display: table.
Also, it looks like you're trying to emulate table-based layouts, if you could list the overall problem you're trying to solve you may get better/more useful answers.
Try a solution like this:
http://jsfiddle.net/cyHmD/
Never use position:absolute and display:table on body - leave those properties as they are since body is your base from where you build the rest of the site - at most use position:relative on body tag. box-sizing changes how the browser box model is calculated - for example instead of calculating 100% width + 20% padding + 20% border = 140% it calculates as 100% width + 20% padding + 20% border = 100%.
This solution will work from IE7 on including IE7.
head, body {
width: 100%;
height: 100%;
margin:0;
padding:0;
}
body {
background-color: blue;
}
#first
{
position:absolute;
width:100%;
height:100%;
padding:20px;
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box;
}
#second
{
height: 100%;
width: 100%;
background-color: white;
}
How about this? Simply replace required margin with border:
#first
{
display: table-cell;
height: 100%;
width: 100%;
border: 20px solid blue;
background-color: white;
}

How can I get three divs with equal spacing between them using variable width?

I am designing a webpage with a contact form that you can see here.
As you can see the page is designed to be variable width. I would like there to be equal spacing between the images, the form, and the edge of the content area, i.e. there would be four spaces with equal width.
At the moment I have designed it so that the images are centred in a DIV with a width of 20% and the contact form centred in a DIV with a width of 60%. This works OK, but not great, because the spacing between the contact form and the images is greater than the space between the images and the edge of the content area as the width of the browser grows. I would like to find a way of keeping all the spaces equal width.
Here is the relevant CSS:
#box {
width: 100%;
min-width: 800px;
}
#left {
float: left;
width: 20%;
}
#center {
float: left;
height: 100%;
width: 60%;
}
#right {
height: 100%;
margin-left: 80%;
}
.dharma {
width: 185px;
margin: 0px auto 0;
padding-top: 25px;
}
#contact-form {
width: 471px;
margin: 25px auto;
}
and here is the relevant HTML:
<div id="box">
<div id="left">
<div class="dharma"><img src="images/dharma.jpg"></div>
</div>
<div id="center">
<div id="contact-form">
[form HTML]
</div>
</div>
<div id="right">
<div class="dharma"><img src="images/dharma.jpg"></div>
</div>
</div>
Could someone help out with this?
Thanks,
Nick
The problem you are describing is perfect for the CSS3 flexible-box layout which will work in Chrome, Safari, and Firefox. All you need is:
#box {
display: -moz-box;
display: -webkit-box;
display: box;
}
#left, #center, #right {
-moz-box-flex: 1.0;
-webkit-box-flex: 1.0;
box-flex: 1.0;
}
Unfortunately this won't work in IE but I hope this is still helps.
Would simply setting a rule to have all of the boxes have an added margin on them not work?
Something like this:
#box {
width: 100%;
min-width: 800px;
}
#left, #center, #right { /* adds spacing between columns of equal size */
margin: 0 2%;
}
#left {
float: left;
width: 16%; /* reduced by 4% for margins */
}
#center {
float: left;
height: 100%;
width: 56%; */ reduced by 4% for margins */
}
#right {
height: 100%;
margin-left: 80%;
}

Resources