I have a responsive website design I'm working on and I need to figure out how to make three divs collapse based on a media query. Here's what I'm trying to do: Screen size 1000px or larger: Three divs centered on the page with this format. Screen size less than 1000px: Three divs still centered but in this format. The issue I'm running into is figuring out how to make div1 wrap to the next line. The only way I know to make this happen is to write some jQuery script to change the order of the div elements in the actual html, but I'd rather not. Any suggestions?
With no code and no link to the page (preferred) there is no way for us to suggest changes to code we can't see. It will likely need some position properties in the alternate CSS. Using jquery for some this basic should not be necessary unless the page structure is already really screwed up.
I can't link to the page because it's being developed on a local computer. Here's the code I have: <div id="rotators"> <div id="rotatorLeft"> <img class="RotatorImage" src="/images/Showcase.png"> </div> <div id="CenterRotator"> <img class="RotatorImage" src="/images/MainRotator.png"> </div> <div id="rotatorRight"> <img class="RotatorImage" src="/images/DYK.png"> </div> </div> and CSS: #rotators { width: 100%; margin: 10px auto; height: 390px; max-width:1320px; } #rotatorLeft { width: 25%; float: left; } #CenterRotator { width: 50%; float: left; } #rotatorRight { width: 25%; float: left; } .RotatorImage { width: 100%; }
Well that structure is never going to work to re-position the way you want it. the three boxes need to be independent, so you need to get rid of the "rotator" wrapper. Then you can specify #center-rotator first in the listing order with margin-auto and positioning for the the other 2, then the media query just needs to specify new position for the two smaller boxes. But without a real page to work with and nothing but some out of context code fragments to go from, that is just a high level guess.
I'd be curious to see if anyone can do this with pure CSS. I tried for 20 minutes, I can't figure it out. I tried changing positioning stuff, z-index, all kinds of stuff. I think even if there is a way to do it without manipulating the dom with JS, its going to be hacky as hell. <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" media="screen,projection,tv" href="style.css"> <title>Blah Blah</title> </head> <body> <div class="widthWrapper"> <div id="one"> <p>Div 1</p> </div> <div id="two"> <p>Div 2</p> </div> <div id="three"> <p>Div Three</p> </div> </div> </body> </html> Code (markup): * { margin: 0; padding: 0; } .widthWrapper { max-width: 1000px; width: 90%; margin: 0 auto; } #one { background: yellow; } #two { background: blue; } #three { background: green; } @media only screen and (max-width: 999px) { #one { } #two { } #three { } } Code (markup):
Even if you solve it with some kind of hack; why waste time on bad code. The problem is not CSS; it is markup, that as it stands, is not going to be responsive without a bunch of unnecessary scripting. The three boxes are bound to a common parent get rid of the binding, and use a media query to set positioning and it is pretty much a no-brainer. Trying to make a badly thought out piece of markup do tricks is a waste of time because even if you figure it out, it has no practical use in a serious website.
I think i have come up with a solution, but it requires the height of DIV2 to be fixed, as you have to push the two other divs down by the height of the first box in pixels. It might not be ideal in your circumstance, but it might be helpful for other use cases... Anyways, here is a live example: http://test.helgesverre.com/3divs/ And here is a fancy GIF: http://i.gyazo.com/aafed45b2922c7d2dc140b9489c74c88.gif The Markup: <html> <head> <title>3 Box Floating</title> <link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="responsive.css"> </head> <body> <div class="box1">DIV 1</div> <div class="box2">DIV 2</div> <div class="box3">DIV 3</div> </body> </html> HTML: Style.css: /* Reset some default padding and margin */ html, body { margin: 0; padding: 0; } /* This is just for esthetics, you don't need this */ .box1, .box2, .box3 { height: 100px; color: white; font-size: 22px; font-weight: bold; text-align: center; line-height: 100px; } /* Float all the divs to the left and assign a width of 25% */ .box1 { background-color: orange; width: 25%; float: left; } /* Float all the divs to the left and assign a width of 50% * setting the height of the "middle box" to a fixed value is * essential with this solution */ .box2 { height: 100px; background-color: gray; width: 50%; float: left; } /* Float all the divs to the left and assign a width of 25% */ .box3 { background-color: blue; width: 25%; float: left; } Code (CSS): Responsive.css: @media(max-width: 1000px) { /* Set this box as position relative, * give it 50% width and float it to the LEFT * then, offset the "top" with the HEIGHT of BOX2. */ .box1 { position: relative; top: 100px; width: 50%; float: left; } /* Set this box as position absolute, * give it a width of 100% and a float of none. */ .box2 { width: 100%; float: none; position: absolute; } /* Set this box as position relative, * give it 50% width and float it to the RIGHT * then, offset the "top" with the HEIGHT of BOX2. */ .box3 { position: relative; top: 100px; width: 50%; float: right; } } Code (CSS):
1) I advise AGAINST percentage sidebar widths. It WILL bite you in the ass if media queries fail to run. 2) You shouldn't be thinking in pixels, you should be thinking in EM's. That way your layout is elastic. 3) No, you do not need any scripttardery like the idiotic halfwit bullshit known as jQuery for this. 4) A "content first" negative margin float layout for the wide version could easily be turned into what you are saying. I would have a third wrapper so that if you want them to be a single column alongside the content (an intermediate width before dropping them down) you could do that too. Thankfully this is ACTUALLY DIV's job -- applying style WITHOUT saying what that style is. (and why HTML 5 is a bunch of idioitic bull) <div class="columnOffset"><div id="content"> <h2>Content Area</h2> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non laoreet eros. Maecenas volutpat quam porta felis ullamcorper, at auctor purus dignissim. Nullam facilisis dolor justo, vitae euismod tellus vestibulum vel. Praesent in risus vel mi euismod molestie. Mauris at magna sem. Maecenas neque ex, tempor quis semper quis, mattis quis lacus. Praesent lacus neque, tempor id mattis suscipit, mattis sed velit. Ut elementum nibh turpis, sit amet sodales sem eleifend auctor. Suspendisse facilisis pellentesque ligula, non tempus turpis varius et. Duis felis magna, porttitor at massa eget, vestibulum lobortis velit. Suspendisse metus ante, blandit eu sollicitudin ac, luctus quis felis. Cras fermentum auctor egestas. Fusce dignissim fringilla convallis. </p> <!-- #content, .columnOffset --></div></div> <div id="extras"> <div class="firstSection"> <h2>First Sidebar</h2> <p> Ut elementum nibh turpis, sit amet sodales sem eleifend auctor. Suspendisse facilisis pellentesque ligula, non tempus turpis varius et. Duis felis magna, porttitor at massa eget, vestibulum lobortis velit. </p> <!-- .firstSection --></div> <div class="secondSection"> <h2>Second Sidebar</h2> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non laoreet eros. Maecenas volutpat quam porta felis ullamcorper, at auctor purus dignissim. Nullam facilisis dolor justo, vitae euismod tellus vestibulum vel. </p> <!-- .secondSection --></div> <!-- #extras --></div> Code (markup): .columnOffset { width:100%; float:left; } #content { margin:0 16em; /* side margin == sidebar width plus any desired padding */ } #extras .firstSection, #extras .secondSection { position:relative; float:left; width:16em; } #extras .firstSection { margin-right:-16em; left:100%; } #extras .secondSection { margin-left:-16em; } @media (min-width:56em) { .columnWrapper { float:none; } #content { margin:0; } #extras .firstSection { width:50%; margin:0; } #extras .secondSection { float:none; overflow:hidden; /* prevent de-indent */ margin:0; } } @media (min-width:32em) { #extras .firstSection { width:auto; float:none; } } Code (markup): Or at least that's how I'd go about it. ... and for **** sake, absolute positioning is NOT the answer unless you want a busted ass broken layout without a footer. No offense helge, but that's the DUMBEST way of building a columnar layout I've ever seen... particularly with the fixed-height nonsense.
... and here's a working demo of that, that does far more since I also added the two column version. http://www.cutcodedown.com/for_others/Jahzin/template.html as with all my examples the directory: http://www.cutcodedown.com/for_others/Jahzin/ ...is wide open for easy access to the gooey bits and pieces. Dynamic height on all elements, nothing removed from flow on any of the layouts so none of the headaches if you go changing your content. It is generally easier on wider widths to stick with elastic sidebars instead of percentages, having the center be fluid between them. Percentage widths are generally a headache and a half with issues like perfect-width float drop -- that's why the version that has the two side-by-side half width only floats one of them, using an overflow to let the other remain fully fluid without de-indenting past it's kin. SOMEDAY soon we'll be able to use something called "flex-box" which will remove a lot of the complications and extra wrapping elements, but that's still very much in flux both on the specification and on implementation -- particularly since IE9 doesn't have support.
Interesting solution, looks clean. I don't know why, I always feel like I'm doing something wrong if I need negative margins. Deathshadow you should consider renaming all those folders to reflect what the demos are. Seems like theres a lot of helpful stuff in there, but no way tell what each is until you go inside. Found this gem in there. I feel like I've came quite a ways since then!
They are WAY too useful when building dynamic floating layouts to simply reject them out of hand. The ability to force one element to overlap another using them -- quite often without even resorting to floats is VERY powerful, particularly when you don't want to remove elements from flow. You just have to keep in mind that negative margins just reduces the element's size "in flow" -- I often like to think of it as if there are two separate 'boxes' browsers keep track of. There's the "Flow box" which is what the browser uses to determine how other elements react to it's position, and the "Render Box" which is how it's drawn. Relative positioning for example moves the render box (where it's drawn) without changing the position of flow box (where other elements in flow think it is)... likewise margins simply change the size of the flow box. Mind you, much like the layman's explanation of inflation being "when universe expanded at a rate that was faster than the speed of light", though that oversimplifies and it ain't quite right, but for purposes here it will have to do, 'cause I ain't got the time to explain it to you. The "perfect float" used in my example is, well... a great example. You have a 100% width float, so there's 0px to fit anything next to it. Using a negative margin on a float after it equal to the width of that element makes it 0px wide in flow, resulting that element now fitting, so it pops up into place next to that 100% width float. ... and of course you can simply turn that behavior off for the media queries, or change which elements are doing it as need be -- hence three column, two column, content top with two columns below and single column all from one HTML codebase and JUST using media queries to do it. Also nice that you can do it "content first" in the source order, since usually people browsing without screen media CSS are more after your content/largest column than they are the extra crap you put to the sides.