Move one element before another with css/html - html

Is it possible to "move" one full width element that is below another one so that it appears to be above by only using CSS/HTML? (and not changing the markup order)
<div id="first">first</div>
<div id="second">second</div>
#first {…}
#second {…}
Desirable result:
second
first

You can use CSS Flexible Boxes for this. Specifically the order property.
In this example I've added width and background-color to help visualize. Please note that browser support for CSS flexible boxes is limited to modern browsers such as IE 10+, Chrome 21+, Firefox 20+ and may not work well in mobile browsers (especially older ones).
.container {
display: flex;
flex-direction: column;
}
#first {
order: 2;
width: 10em;
margin-top: 1em;
background-color: orange;
}
#second {
order: 1;
width: 10em;
background-color: yellow;
}
<div class='container'>
<div id=first>
first
</div>
<div id=second>
second
</div>
</div>

Only if you know exact height of second element:
#first {
margin-top: 20px;
}
#second {
top: 0;
position: absolute;
}
http://jsfiddle.net/9zmcnedy/

Js Fiddle
something like this
#first { position:relative; top:18px}
#second {position:relative; bottom:18px}

There is a work-around by using position: absolute but this has a drawback that the parent element will not stretch the height as the child container's (first element) height increase. (To fix that you should use javascript)
CSS
.container {
border: 1px solid green;
display: inline-block;
position: relative;
}
#first {
position: absolute;
top: 100%;
}
Working Fiddle

Related

How do i make this layout in css, divs are collapsing

JsFiddle: http://jsfiddle.net/techsin/csfvb91u/
(just realized normal div is collapsing ALSO to size of content, is min height completely useless?)
I need two divs, one left, and on right. Left one is 100px wide and stays that way. While, right div expands infinitely and doesn't shrink beyond 400px. Both Divs should be the height of parent. And parent has no exact height but minimum height of 800. So if content of one of these 2 divs were to push the height of div and extend it. Then The height of parent should increase and thus also the height of other div.
I tried using floats. I managed to some extent. However left side which was on float left, its height kept collapsing and didn't follow height:100% rule. It only worked if parent had definite width.
I tried using inline block but then right div won't expand to fillin the available space..
Why in the world css doesn't have fit-content, fill-available, choose what % refers to, choose what to position against, use vector or use pngs to shape div, inset textshadow, etc.
<div class="cont">
<div class="a"></div>
<div class="b"></div>
</div>
try with display:table and display:table-cell for child you will need to give fixed with for the left div
demo - http://jsfiddle.net/z90fma6e/
html,
body {
height: 100%;
}
* {
margin: 0;
padding: 0;
}
.cont {
display: table;
height: 100%;
}
.left,
.right {
height: 100%;
}
.left {
width: 200px;
background: red;
display: block;
}
.right {
width: 100%;
display: table-cell;
background: green;
}
<div class="cont">
<div class="left">fixed
<br/>height adjusts</div>
<div class="right">expands
<br/>height adjusts</div>
</div>
Sounds like your divs are collapsing. Your going to need a clearfix you can add to divs. There are a few ways to do this; however, this option is best.
.clearfix:after {
content: ".";
visibility: hidden;
display: block;
height: 0;
clear: both;
}
Add this clearfix class and css to your divs so they wont collapse.
You can read more about them at cssTricks
perfect use case for CSS flex layout:
<style>
body {
display: flex;
flex-direction: row;
margin: 0;
padding: 0;
}
div:first-child {
width: 200px;
background: red;
}
div:last-child {
flex: 1;
background: blue;
}
</style>
<div></div>
<div></div>
If you wish to support IE8 or earlier I would suggest you to use positioning:
Here's what I came up with
Fiddle : http://jsfiddle.net/csfvb91u/4/
If the content on the right is going out of the container, you can always use margin-right:200px as the right side container is shifted 200px using left:200px. Hope you get what I'm saying... :)
HTML:
<div class="cont">
<div class="a"></div>
<div class="b"></div>
</div>
CSS:
.a {
position:absolute;
width: 200px;
background-color: green;
height: 100%;
}
.b {
width:100%;
position:absolute;
left:200px;
background-color: blue;
height: 100%;
}
.cont {
position:relative;
border:1px solid #333;
min-height:300px;
overflow:hidden;
}

Change order of floated divs with CSS

JSFIDDLE
I want to change the order of floated divs at a certain pixel size.
At default state they both have 50% width and they are next to each other.
Below 600px screen size (or w/e does not matter) I want the second div(red one) float above first div(yellow one).
How is this possible with CSS only solution?
HTML
<div class="yellow"></div>
<div class="red"></div>
CSS
.yellow {
background: yellow;
width: 50%;
height: 300px;
float:left;
}
.red {
background: red;
width: 50%;
height: 300px;
float:left;
}
#media screen and (max-width:600px) {
.yellow {
background: yellow;
width: 100%;
height: 300px;
float:left;
}
.red {
background: red;
width: 100%;
height: 300px;
float:left;
}
}
The solution I want is:
RED DIV
YELLOW DIV
but now it is:
YELLOW DIV
RED DIV
I know that you're asking how to accomplish this utilising floats, but as far as I know using pure CSS this is impossible (at least without using nasty positioning, which you've said you don't want to do).
As far as I know the only nice way to accomplish this with pure HTML/CSS is to utilise the new flexbox spec (a good starting point would probably be this css tricks article).
When you use flexbox you can use the order property on items to dictate which order items appear in (duh)
You can see an example of this in action here, the HTML code is similar to what you have, with an added wrapper element (I also fixed the DOCTYPE declaration):
<!DOCTYPE html>
<div class="wrapper">
<div class="yellow">
</div>
<div class="red">
</div>
</div>
The CSS is a little different:
.wrapper {
display: flex;
flex-flow: row wrap;
}
.yellow {
background: yellow;
width: 20%;
height: 300px;
}
.red {
background: red;
width: 20%;
height: 300px;
}
#media screen and (max-width:600px) {
.yellow {
order: 2;
width: 100%;
}
.red {
order: 1;
width: 100%;
}
}
I've also cleaned it up a little, you had duplicate code in your media query which didn't really need to be there.
The only downside to this is that it currently only works on around 80% of browsers as of writing:
http://caniuse.com/#search=flexbox
Depending on your target market that might be OK, you could use graceful degradation so that it appears correctly in all ways except the ordering on devices that don't support flexbox fully.
I guess you're also only really targeting mobile devices with reordering things, support there is good so it might work well for you.
Try to change your
HTML to this -
<div class="container">
<div class="yellow"></div>
<div class="red"></div>
</div>
and your #media query CSS to this -
#media screen and (max-width:600px) {
.container{
display:flex;
flex-direction: column-reverse;
}
.yellow {
background: yellow;
width: 100%;
height: 300px;
}
.red {
background: red;
width: 100%;
height: 300px;
} }
Here is a simple solution using negative margins and floats.
For the CSS, use the following:
#media screen and (max-width:600px) {
.yellow {
background: yellow;
width: 100%;
height: 300px;
float:left;
margin-top: 300px;
}
.red {
background: red;
width: 100%;
height: 300px;
float:left;
margin-left: -100%;
}
}
Your HTML remains the same as you posted.
Add a top margin to .yellow using margin-top: 300px (equal to the height of the
red div).
For the red div, add a negative left margin of 100%.
This will force the red div to position itself over the yellow div, but since you
have the yellow div a top margin, the yellow div pops out under the red div.
The trick is similar to that used for the Holy Grail 3-column layout design.
See demo: http://jsfiddle.net/audetwebdesign/jux84wzk/
So far, there are no mobile first answers, which is fewer lines of css, and other benefits. This does touch the html, so it's not the OP's question, for a CSS only approach it's the Flexbox answer from two other peeps, which I have voted up.
DEMO: http://jsfiddle.net/mhrf6d4n/
HTML, put in source order of the smallest viewport first:
<div class="red"></div>
<div class="yellow"></div>
CSS (put the shared, global to all viewports outside of media queries, combine shared selectors, then after put the min-width and put your floats in there)
.yellow, .red {
background: yellow;
height: 300px;
}
.red {
background: red;
}
#media screen and (min-width:600px) {
.yellow, .red {
float:left;
width:50%;
}
}

IE - using 100% height within table-row

I'm using css tables where the last table row has height 100% - to fill up the remaining height.
FIDDLE
This works for me cross-browser (Including IE).
However, if I then add in the last table-row some divs with fixed height (this is dynamic content - I don't know how many of them there are) where the last div has height:100% - in order to fill up the last table-row. - like this:
FIDDLE -
this now doesn't work in IE (Even IE10)
What must I do to make this work in IE ?
(Edit: As correctly pointer out in the comments: It doesn't work in any browser - although in Chrome and firefox it looks like it works - the height:100% on the last div of the third row wasn't filling up the remaining height but rather taking up the complete height of row3...
So I attempted using table rows for row 3:- FIDDLE... Now this works in other browsers, but still doesn't work in IE!)
Markup
<div class="table">
<div class="row row1">row1</div>
<div class="row row2">row2</div>
<div class="row row3">
<div class="row3a">row3a</div>
<div class="row3b">row3b</div>
<div class="row3c">row3c</div> <!-- in IE this doesn't fill the last row -->
</div>
</div>
CSS
.table
{
display: table;
width: 600px;
height: 300px;
}
.row
{
display: table-row;
}
.row1
{
height: 50px;
background: pink;
}
.row2
{
height: 100px;
background: orange;
}
.row3
{
height: 100%;
background: yellow;
}
.row3a
{
height: 30px;
background: purple;
}
.row3b
{
height: 60px;
background: aqua;
}
.row3c
{
height: 100%;
background: brown;
}
Pure CSS, Cross-Browser Solution, Without using CSS Table Layout.
I actually recomend you to USE the CSS table layout if you can. (I don't know why you don't want it in your rows, its perfectly fine.)
OR the flexbox layout, although it's not properly implemented yet in all browsers..
--I just read in the comments that it didn't worked for you in IE, well: my solution does.. even with IE8.
Working Fiddle
HTML: I'm using the extra wrapper I mentioned in the comment.
<div class="table">
<div class="row1">row1</div>
<div class="row2">row2</div>
<div class="row3">
<div class="Wrapper">
<div class="row3a">row3a</div>
<div class="row3b">row3b</div>
<div class="row3c">row3c</div>
</div>
</div>
</div>
CSS: (most of it if for the backgrounds)
.table
{
width: 600px;
height: 900px;
}
.row1
{
height: 50px;
background: pink;
}
.row2
{
height: 100px;
background: orange;
}
.row3
{
background: yellow;
position: relative;
}
.row3a
{
height: 30px;
background: purple;
}
.row3b
{
height: 60px;
background: aqua;
}
.row3c
{
background: brown;
}
.Wrapper
{
position: absolute;
width: 100%;
height: 100%;
}
.table:before, .Wrapper:before
{
content: '';
height: 100%;
float: left;
}
.row3:after, .row3c:after
{
content: '';
display: block;
clear: left;
}
IE gives you the perfect result you wanted. You are rendering it as table-row. You don't need to set specific height to the last row for it to fill the remaining space.
You are actually doing it wrong by setting height to 100%;
Here 100% means the actual height of row3 and chrome renders it as you have written.
i.e row3c overflows its parent row3.
since you specified pixel heights for the remaining rows it won't fill. You need to specify
percentage heights for all ( row3a -> height: 20%, row3b -> height: 30%, row3c -> height: 50%)
it will work
You are giving height to table as 300px, Here is fiddle http://jsfiddle.net/yKPq3/11/ and assuming you want table to be filled 300px, you need to change .row3 to height:150px and .row3c to height:60px

Create three divs such that the top and bottom ones have fixed height, and the middle one has dynamic height?

I want to create three, stacked divs. The top and the bottom ones will be of fixed height, whereas the one in the middle will have a dynamic height that expands to fill the remaining space:
I've tried numerous things, such as setting the height to auto. I do have a solution, but it involves JavaScript (i.e., calculating the remaining height) but I was wondering if there was a pure CSS solution.
There's a CSS solution, but it won't work in older browsers. You need to use the calc "function" that is new to CSS, combined with height: 100%. If you've never used height: 100% before, you know that every parent element of the one you want to be 100% tall must also be set to height:100%. calc can take a percentage value and subtract pixels from it, so you just need to set it to be 100% minus however tall the top and bottom divs are.
Supported by: IE9+, Firefox 4+, Chrome 19+, Safari 6+
http://caniuse.com/calc
HTML
<div id='top'></div>
<div id='mid'></div>
<div id='bot'></div>
CSS
html, body
{
height: 100%;
}
#top, #bot
{
height: 50px;
background: red;
}
#mid
{
height: calc(100% - 100px);
}
FIDDLE: http://jsfiddle.net/jakelauer/9cYUB/
One solution is to do it with position absolute.
The downside of this approach is that if the total height of surrounding is smaller then the sum of the fixed heights the container will not be visible anymore.
Another thing to be noted is that this is probably a bad solution if you want to target mobile devices. It always depends on the exact situation if this solution is suitable.
If i remember right you will only have problems with IE 6 (on desktop) which does not support the top bottom combination for the position absolute.
HTML
<div class="header"></div>
<div class="container"></div>
<div class="footer"></div>
CSS
.header, .container, .footer{
position: absolute;
outline: 1px solid black;
}
.header {
left: 0px;
top: 0px;
right : 0px;
height: 50px;
}
.container {
left: 0px;
top: 50px;
right : 0px;
bottom: 50px;
}
.footer {
left: 0px;
bottom: 0px;
right : 0px;
height: 50px;
}
JSFiddle
You can do it with a HTML table if you need older browser support, or if you need to support IE8+ or higher you could use the CSS table layout.
Here's a jsFiddle using CSS table layout.
HTML
<div>
<div>
<div>Fixed Height</div>
</div>
<div>
<div>
<div>Variable Height</div>
</div>
</div>
<div>
<div>Fixed Height</div>
</div>
</div>
CSS
html, body {
height:100%;
width: 100%;
margin: 0px;
padding: 0px;
text-align: center;
font-size: 20pt;
font-family: Verdana;
}
body > div {
display:table;
width: 100%;
height:100%;
}
body > div > div {
display: table-row;
}
body > div > div > div {
display: table-cell;
vertical-align: middle;
}
body > div > div:nth-child(odd) {
background: grey;
color: #FFF;
height: 100px;
}
body > div > div:nth-child(even) {
height:100%;
width:100%;
}
body > div > div:nth-child(even) >div {
height:100%;
width:100%;
overflow:hidden;
}
If i understand you request you need to use wrap div: http://www.cssstickyfooter.com/using-sticky-footer-code.html

How to center a div vertically?

I have a div that I want to center horizontally and vertically.
For the horizontal issue everything is great, but I have a problem with the vertical alignment.
I tried this:
#parent {
display: table;
}
#child {
display: table-row;
vertical-align: middle;
}
but this doesn't work.
If you only have to support browsers that support transform (or its vendor prefixed versions), use this one weird old trick to vertically align elements.
#child {
position: relative;
top: 50%;
transform: translateY(-50%);
}
If you have to support older browsers, you can use a combination of these, but they can be a pain due to the differences in rendering block vs table.
#parent {
display: table;
}
#child {
display: table-cell;
vertical-align: middle;
}
If your height is fixed and you need to support those really old, pesky browsers...
#parent {
position: relative;
}
#child {
height: 100px;
position: absolute;
top: 50%;
margin-top: -50px;
}
If your height is not fixed, there is a workaround.
See it on jsFiddle.
Having the parent property as, display:table and child property as display: table-cell and vertical-align: middle worked for me.
You can use flexbox to center horizontally or vertically your child div inside a parent div:
This should be your html:
<div id="parent">
<div id="child">
info
</div>
</div>
And this is the css with flexbox:
#parent{
display: flex;
align-items: center;
justify-content: center;
position: relative;
width: 100%;
height: 100vh;
background: lightgray;
}
#child{
position: relative;
background: black;
padding: 2rem;
color: white;
box-shadow: 5px 5px 20px rgba(0,0,0,.4);
border-radius: 5px;
}
Here is de codepen: https://codepen.io/bongardabo/pen/YzZQgaJ
First off, treating non-table markup as tables (with display:table and friends) isn't cross-browser. I don't know which browsers you need to support but certainly IE6 won't do this. But, if your targeted browser do all support display:table I can give you some tips.
The vertical centering approach you're looking for (using table layout) depends on having a TD with vertical-align:middle, then inside of that a single block element will vertically center. So I think what you want is:
#parent { display:table-cell; vertical-align:middle; }
#child { /* nothing necessary, assuming it's a DIV it's already display:block */ }
It's ok to use table-cell with no surrounding table-row and table, the browser infers the needed table wrapping elements for you.
here is another way when you don't know the inner div size or whatever, you may use % here and there to fix the "centering" ....
the idea is that your top value is half the height of your child element as to create the centering illusion
Here's the code:
<div id="parent">
<div id="child">
hello
</div>
</div>
and for the styling:
#parent {
position: relative;
height: 300px;
width:200px;
background-color:green;
}
#child {
height: 50%;
width: 50%;
position:relative;
top:25%;
left:25%;
background-color:red;
}
Here you can see it in action
http://jsfiddle.net/Wabxv/