Change order of floated divs with CSS - html

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

Related

CSS - Make multiple divs in columns wrap back around

Say I have three divs - Red Green and Blue with the following basic markup and styles: https://jsfiddle.net/ar8sn1o6/
<div class="red">Red</div>
<div class="green">Green</div>
<div class="blue">Blue</div>
.red, .green, .blue {
display: inline-block;
float: left;
margin: 1%;
width: 48%;
}
.red {
background: red;
height: 50px;
}
.green {
background: green;
height: 100px;
}
.blue {
background: blue;
height: 50px;
}
But I want to be displayed in two column on desktop and one column on mobile like this. Whilst it is reasonably straight forward to have a Red -> Blue -> Green mobile layout, I need to instead have a Red -> Green -> Blue layout
Is this possible without duplicating any HTML?
It is possible using media queries
Check out this article to find out more: https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries
Syntax
Media queries consist of an optional media type and can, as of the
CSS3 specification, contain zero or more expressions, expressed as
media features, which resolve to either true or false. The result of
the query is true if the media type specified in the media query
matches the type of device the document is being displayed on and all
expressions in the media query are true.
See snippet below. Resize it to see it working!
.red, .green, .blue {
display: inline-block;
float: left;
margin: 1%;
width: 48%;
}
.red {
background: red;
height: 50px;
}
.green {
background: green;
height: 100px;
}
.blue {
background: blue;
height: 50px;
}
#media (max-width: 400px) {
.red, .green, .blue {
display: block;
width: 100%;
}
}
<div class="red">Red</div>
<div class="green">Green</div>
<div class="blue">Blue</div>
UPDATE
What you're trying to achieve is not possible with CSS only.
Ill try to explain why not.
When you style elements with float: left or display: inline-block. They have an parent element which has the height of the highest child. So every new block thats inserted on a new row will allign at the bottom of the highest previous child.
So aligning them as you want is not possible. However, you can wrap an div around it. And then just add float: left; or display: inline-block. See this example: https://jsfiddle.net/ar8sn1o6/2/
NOTE:
When using float, the parent element will lose its height. You can fix this by adding overflow: hidden to the parent element.
Or use clearfix. See: https://css-tricks.com/snippets/css/clear-fix/
You could use Media queries to specify certain CSS when the viewport of the device is smaller than a certain/specified size.
For example:
#media screen and (max-width: 480px) {
container {
width: 100%;
}
.blue {
background-color: blue;
width: 90%;
height: 50px;
}
}
This would mean that if the width of the device was smaller than 480px, these styles would take effect. I think if you put them all in a container and they all had a width of say 90%, they would align one by one below each other in the mobile view.
Hope that helps
Put a container and add media-query
.red, .green, .blue {
display: inline-block;
margin: 1%;
}
.red {
background: red;
height: 50px;
width:100%;
}
.green {
background: green;
height: 100px;
}
.blue {
background: blue;
height: 50px;
width:100%;
}
.container, .green{
float:left;
width: 48%;
}
#media only screen
and (max-width: 480px) {
.container, .green{
width: 100%;
}
}
<div class="container">
<div class="red">Red</div>
<div class="blue">Blue</div>
</div>
<div class="green">Green</div>

responsive web design media query width not changing

I am working on making a page responsive, by changing div width according to the size, but except width every property I am able to change, width is not changing at all.
My code for HTML and styling the elements
#main {
width: 100%;
display: flex;
flex-wrap: wrap;
}
#main div {
width: 100%;
}
#media screen and (max-width: 700px) {
#red {
display: none;
}
body {
background-color: yellow;
}
#blue {
width: 75%;
}
<body>
<div id="main">
<div id="red" style="background-color: red;">RED COLOR</div>
<div id="blue" style="background-color: blue;">BLUE COLOR</div>
<div id="green" style="background-color: orange;">GREEN color</div>
</div>
This is the code I tried, but except width every property I am able to change How do I change the width property?
don't use inline styles (that's a bad practice), and this is all about specificity, so you can set just div (for width:100%) or specify your #blue even more, by adding a parent to it, in this case #main.
You can calculate specificity here
#main {
width: 100%;
display: flex;
flex-wrap: wrap;
}
div {
width: 100%;
}
#red {
background: red
}
#blue {
background: blue
}
#green {
background: green
}
#media screen and (max-width: 700px) {
#red {
display: none;
}
body {
background-color: yellow;
}
#blue {
width: 75%;
}
}
<div id="main">
<div id="red">RED COLOR</div>
<div id="blue">BLUE COLOR</div>
<div id="green">GREEN color</div>
</div>
The problem is that your #main div styles are more specific than your #blue styles.
Change your media query styles to
#main #blue{
width: 75%;
}
Add viewport meta tag after starting head tag.
<meta name="viewport" content="width=device-width, initial-scale=1">
A viewport element gives the browser instructions on how to control the page's dimensions and scaling.
This tag is important for responsiveness of webpage.
It controls your webpage width according to screen size.
Read more http://www.w3schools.com/css/css_rwd_viewport.asp
Your #main div has precedence over your #blue div since it is defined outside the media query. If you want to apply width: 75% to only #blue div use max-width, attribute as:
#blue {
max-width: 75%;
}
Working demo
I was just having this problem and nothing helped me. I tried moving the media query to the end of my CSS file, and everything worked.

Scalable placement of fixed position div on large screen

I have a one column layout with several divs stacked vertically. The topmost div however should move into a second column and have a fixed position once the screen is wide enough.
Currently I use something like in this fiddle:
https://jsfiddle.net/L3u3xqdu/1/
html:
<div class="red">
</div>
<div class="blue">
</div>
css:
.red {
background-color: red;
width: 400px;
height: 400px;
}
#media screen and (min-width: 900px) {
.red {
position: fixed;
left: 500px;
}
}
.blue {
background-color: blue;
width: 400px;
height: 2000px;
}
My question is: Is there a more scalable solution that does not require knowing the width of the column to hardcode the position of the fixed div? I have to adapt that offset every time I add something to the one column. I am searching for some CSS magic or maybe a small framework or library that I can use.
My other libraries that I use are: react, stylus, lodash, jquery, normalize.css
https://jsfiddle.net/u09dpgot/
An extra wrapper div:
<div class="colwrap">
<div class="red">
</div>
<div class="blue">
</div>
</div>
flex css (order changes the order of the html elements visually in the browser):
.colwrap {
display:flex;
flex-wrap:wrap;
}
.red,
.blue {
flex:0 0 400px;
}
.red {
background-color: red;
height: 400px;
}
.blue {
background-color: blue;
height: 2000px;
}
#media screen and (min-width: 900px) {
.red {
order:2;
}
.blue {
order:1;
}
}
https://css-tricks.com/snippets/css/a-guide-to-flexbox/

How can I create three responsive divs using display: table and no JS?

How can I create a responsive arrangement of three divs, such that:
when the viewport is narrow, the three divs appear one atop the other
when the viewport is average, the first div appears full width atop the other two, which are side-by-side and have equal height
when the viewport is wide, the three divs appear side-by-side with equal height
I would like the solution to be broadly supported by browsers.
I've tried a number of media query based strategies, as follows:
To achieve #1, I style each div as display:block
To achieve #2, I style the green and blue divs as display:table-cell and created a container div styled with display:table.
However, if I create another container div for all three elements and style it with display:table, neither of the following approaches work:
Setting all divs to display:table-cell - because the red table cell and the other two are intervened by the smaller container div
Setting the red div and the smaller container divs to display:table-cell - because the smaller container div still needs to be set to display:table for the sake of the green and blue divs inside it.
It's all a bit hard to explain, but I guess you have the idea. Any help would be greatly appreciated.
Thanks!
Edit: I don't want to set the height of any div manually. It should be dictated by its content
What you are trying to achieve is fairly difficult using display: table because of just the issue you ran into: containers are required and the configuration is not that flexible due to the way tables' strict requirements.
I suggest you use flexbox which has fairly good browser coverage now: http://caniuse.com/#feat=flexbox
Here is a good example of how to get equal height rows using flexbox: http://osvaldas.info/flexbox-based-responsive-equal-height-blocks-with-javascript-fallback
I know #fauxserious already posted a very similar answer, but I'll post mine anyways because it's a bit different.
This doesn't use a table, nor the ::before or ::after CSS pseudo-elements.
div#div1 {
background-color: red;
}
div#div2 {
background-color: green;
}
div#div3 {
background-color: blue;
}
div {
box-sizing: border-box;
padding: 20px;
float: left;
margin: 1%;
width: 31%;
}
#media screen and (max-width: 750px) {
div#div1 {
width: 98%;
}
div#div2, div#div3 {
width: 48%;
}
}
#media screen and (max-width: 500px) {
div {
width: 98% !important;
}
}
<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>
(It's best to see the above snippet if you open it in a new tab / window and resize it.)
See working example on JSFiddle.net.
EDIT See updated snippet. If you remove the height property of the divs (and replace it with padding so that you can see it even when it's empty), then the height will be determined by its content.
Edit: sorry I missed the equal height part.
You are trying to make squares so let me code and then explain. I'm going to make this a list to help identify things. Assume the ul has been reset (no margin, padding or style-type).
<ul>
<li>
<div>
</div>
</li>
<li>
<div>
</div>
</li>
<li>
<div>
</div>
</li>
</ul>
Here's the CSS to make everything squares.
li{
position:relative;
width:33%;
padding-top:33%;
}
li > div{
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
height:100%;
width:100%;
}
You'll notice the padding to be equal to the width. Padding percentage no matter where it's used is based on the parent element's width (margin also works this way). Even if you use it on the top or bottom.
Now with that we can get to positioning with CSS
ul:before, ul:after{
content:"";
display:table;
}
ul:after{
clear:both;
}
li{
position:relative;
width:33%;
padding-top:33%;
float:left;
}
#media screen and (max-width:800px){
li{
width:50%;
padding-top:50%;
}
li:first-child{
width:100%;
padding-top:0; /* Not sure what height you'd want here*/
}
}
#media screen and (max-width:400px){
li{
width:100%;
padding-top:100%;
}
}
I was unsure of why you wanted to use display: table;, however I did something a little different but will look like the images you posted above.
HTML:
<div class="container">
<div class="box box1"></div>
<div class="box box2"></div>
<div class="box box3"></div>
</div>
CSS:
.container {
width: 90%;
margin: 0 auto;
}
.box {
width: 32.3333%;
float: left;
height: 200px;
margin: .5%;
}
.box1 {
background-color: #ff4034;
}
.box2 {
background-color: #22ff62;
}
.box3 {
background-color: #24a6ff;
}
#media screen and (max-width: 900px){
.box:first-child {
width: 99%;
}
.box:nth-child(n + 2){
width: 49%;
}
}
#media screen and (max-width: 436px){
.container .box {
width: 99%;
clear: both;
margin-bottom: 10px;
}
}
Result: Your images above
How about using flex?
.parent {
border: 1px solid #555;
display: flex;
flex-flow: row wrap;
}
.dual {
display: flex;
flex-flow: row wrap;
flex: 2 2 550px;
}
.item {
padding: 20px;
margin: 10px;
flex: 1 1 200px;
min-width: 200px;
}
<div class="parent">
<div class="item" style="background-color: red">red</div>
<div class="dual">
<div class="item" style="background-color: green; flex: 1 1 100px">green</div>
<div class="item" style="background-color: blue; flex: 1 1 100px">blue</div>
</div>
</div>
I had to tweak the sizes a little due to padding and margins, like ".dual" being 550px instead of 400px. Also if the combined items are the same size they will show as two rows in the second column sometimes when shrinking so I made them smaller. Make it full page when you run the snippet or check out the fiddle link which is easier to resize has some extra text showing the blue and green boxes keep the same height in layout 2.

Move one element before another with css/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