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/
Related
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>
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.
In a webpage i have following markup for my layout
<div class="parent">
<div class="left-content"></div>
<div class="right-content"></div>
</div>
and the styles for the given markup are:
.parent{
display:table;
width:100%;
}
.parent > .left-content{
width:auto;
}
.parent > .right-content{
width:320px;
}
How do I make the "right-content" occupy 320px of available width and the "left-content" div occupy all the remaining width?
Note that: i can not use the following technique to achieve this behaviour as my layout is responsive and i need to move the "right-content" to the bottom of "left-content" at specific resolution.
Markup:
<div class="parent">
<div class="right-content"></div>
<div class="left-content"></div>
</div>
Styles
.parent{
display:block;
width:100%;
}
.parent > .left-content{
width:auto;
}
.parent > .right-content{
width:320px;
float:right;
}
To make things easier I would first change the markup so you have the left content is below your right-content (as desired on smartphone-resolutions).
<div class="left-content"></div>
<div class="right-content"></div>
Next, because your first div is the one that takes up remaining width, the simple solution seems to be display:table-cell (and the parent as display:table). It looks doable with inline-blocks or floats as well, but you may have to resort to something like width: calc(100% - 320px); so I like the table solution a little bit more.
Next you add a simple media query to change back to blocks on lower resolutions.
.parent {
display: table;
width: 100%;
}
.parent > .left-content {
display: table-cell;
width: auto;
/* Added for visualisation */
background: blue;
height: 50px;
}
.parent > .right-content {
display: table-cell;
width: 320px;
/* Added for visualisation */
height: 50px;
background: red;
}
/* Media query */
#media(max-width: 550px) {
.parent > .left-content {
display: block;
}
.parent > .right-content {
display: block;
width: 100%;
}
}
<div class="parent">
<div class="left-content">Left</div>
<div class="right-content">Right</div>
</div>
I would strongly suggest using calc rather than forcing your markup to behave like a table.
http://sassmeister.com/gist/c87585fcff7fae356adb
.left-content,
.right-content {
width: 100%;
}
#media (min-width: 600px) {
.left-content {
float: left;
width: calc(100% - 320px);
}
.right-content {
float: right;
width: 320px;
}
}
I need to collapse divs (left: logo, banner, right: buttons group A, buttons group B)
I want these to collapse in specific way depending on screen size:
Button group B collapse
Banner collapse
If screen resolution is super high I want to have banner+logo on left (red+green), blank space in middle, and two button groups on right (blue+purple)
See image below:
This is what I have tried so far:
https://jsfiddle.net/ey74wud6/
To be honest it was trial and error, and boxes are collapsing in way not good for me.
<style>
/* just example - color, fixed size of box */
.green { background: green; width: 80px; height: 70px; }
.red { background: red; width: 270px; height: 70px; }
.purple { background: purple; width: 70px; height: 70px; }
.blue { background: blue; width: 70px; height: 70px; }
.box { margin: 2px; }
/* proper css experiments */
.left {
float: left;
}
.left .box {
float: left;
}
.right {
float: right;
}
.right .box {
float: left;
}
</style>
<div class="left">
<div class="box green"></div>
</div>
<div class="left">
<div class="box red"></div>
</div>
<div class="right">
<div class="box purple"></div>
</div>
<div class="right">
<div class="box blue"></div>
</div>
I know I can do it with little help of javascript but my question is it possible to solve my problem using pure CSS?
Any help will be appreciated
You can use css media queries for this. Check out the modified example: https://jsfiddle.net/ey74wud6/1/
I've modified your css code a bit, but the most important part is :
#media (max-width: 454px) {
.left {
width : 280px;
}
.right {
width: 80px;
}
}
#media (min-width: 455px) and (max-width: 522px) {
.left {
width : 360px;
}
.right {
width: 80px;
}
}
You can replace the values to fit your needs
What you need is display:flex
You can define flex-shrink/grow and combine it with max- and min-width on flexible Elements.
And you can combine that with mediaqueries
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%;
}
}