I'm looking for a way to create a CSS layout where the left column is fluid and the right column is fixed using the exact markup below. I don't think it is possible. Am I wrong?
<div class="wrapper">
<div class="left">Fluid Column</div>
<div class="right">Fixed Column</div>
</div>
Yep. Try this:
<div id="wrapper">
<div id="left">
<div id="content">
...
</div>
</div>
<div id="right">
...
</div>
</div>
CSS:
#wrapper { width: 900px; }
#left { float: left; width: 100%; margin: 0 -100px 0 0 ; }
#content { margin: 0 100px 0 0; }
#right { float: right; width: 100px; }
Note: Remove wrapper if you want the width to be 100%.
It's probably not a viable solution at this point in time but if you are not adverse to using bleeding-edge CSS you could also use the CSS3 flex box module. Using vendor specific prefixes, it is currently supported in Firefox, and Webkit based browsers such as Safari and Google Chrome.
<!doctype html>
<style>
.wrapper {
display: -moz-box;
display: -webkit-box;
display: flexbox;
-moz-box-orient: horizontal;
-webkit-box-orient: horizontal;
flex-direction: lr; /* box-orient has been renamed in the most recent version of the draft */
width: 100%;
}
.right {
width:150px;
background-color: #eee;
}
.left {
-moz-box-flex: 1;
-webkit-box-flex: 1;
flex-box: 1; /* box-flex has been renamed flex-box */
}
</style>
<div class="wrapper">
<div class="left">Fluid Column</div>
<div class="right">Fixed Column</div>
</div>
For the sake of semantics, you might want to rename .left and .right to something like .content and .sidebar
Give this a shot:
* { padding:0px; margin:0px; }
.wrapper {
position:absolute;
width:100%;
height:100%;
}
.left {
position:absolute;
top:0; bottom:0;
left:0; right:150px;
background-color:#999999;
}
.right {
position:absolute;
top:0; bottom:0;
right:0;
width:150px;
background-color:#AAAAAA;
}
Related
say I have...
<div id="A"></div>
<div id="B"></div>
How can the end-user view div B on top of div A on their browser?
I'm trying to do this with CSS without editing the html.
You can use flex-box and order to acheive what you want
body {
display: flex;
flex-wrap:wrap;
}
#A {
width: 100%;
height:50px;
background: red;
color:white;
order: 2;
}
#B {
width: 100%;
height:50px;
background: black;
color:white;
order: 1;
}
<div id="A">A</div>
<div id="B">B</div>
You need to add display:flex; and flex-direction:column-reverse; to the parent of your two divs.
body{
display:flex;
flex-direction:column-reverse;
}
Or you can choose div's order manually with order property:
body {
display: flex;
}
#A {
order: 2;
}
#B {
order: 1;
}
Use CSS3 flex to change the positioning of flex elements and this can be done using order property,
The CSS order property specifies the order used to lay out flex items
in their flex container.
#box{
display:flex;
width:100%;
flex-direction:column;
}
.A{
order:2;
background:#111;
color:#fff;
}
.B{
order:1;
background:#111;
color:#fff;
}
<div id="box">
<div class="A">A</div>
<div class="B">B</div>
</div>
A way to do this in CSS:
The container must have display:flex attribute
Then :
#A{
order:2;
}
#B{
order:1;
}
You can also achieve this with jQuery
$('#B:parent').each(function () {
$(this).insertBefore($(this).prev('#A'));
});
It feels unclean to do it this way but here you go (no container element needed)
#A {
display: table-footer-group;
}
#B {
display: table-header-group;
}
<div id="A">A</div>
<div id="B">B</div>
I have a responsive website with a two-column layout in large browser windows. The two-column layout is currently implemented using float. On smaller screens I'd like to have just one column. The content of the other column should be displayed between the two elements of the main column, like shown here:
<div class="two-columns">
<div class="main-column">
<div class="red-element"></div>
<div class="yellow-element"></div>
</div>
<div class="sidebar-column">
<div class="green-element"></div>
</div>
</div>
I tried using a flex-box-based approach, basically the one described in this question, but flex-basis still seems to be unsupported in Safari when flex-direction is column. Proper Safari support is a must as Safari is the main browser of my visitors.
Is there a way this can be achieved using CSS only without having to place the green element twice in my markup?
Here's a general solution using one flex container:
<div class="container">
<div class="box"> ... </div><!-- red box -->
<div class="box"> ... </div><!-- green box -->
<div class="box"> ... </div><!-- yellow box -->
</div>
Starting with small screens (for no particular reason), stack them in a column:
.container {
display: flex;
flex-direction: column;
}
.box {
height: 100px;
width: 100%;
}
Re-arrange the layout for wider screens:
#media (min-width: 800px) {
.container {
flex-direction: row;
flex-wrap: wrap;
}
.box {
flex-basis: 45%;
}
}
On screens wider than 800px, the container lines the items in a row and enables wrapping. Each box is given a large enough width (flex-basis) for only two to fit on a line.
Full demo:
* {
box-sizing: border-box;
}
.container {
display: flex;
flex-direction: column;
padding: 5px 0;
background-color: #f5f5f5;
border: 1px solid #aaa;
}
.box1 { background-color: red; }
.box2 { background-color: lightgreen; }
.box3 { background-color: yellow; }
.box {
height: 100px; /* `flex-basis: 100px` would also work */
width: calc(100% - 20px);
margin: 5px 10px;
border: 1px solid #ccc;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.2em;
}
#media (min-width: 800px) {
.container {
flex-direction: row;
flex-wrap: wrap;
}
.box {
flex-basis: 45%;
}
}
<div class="container">
<div class="box box1"><span>1</span></div>
<div class="box box2"><span>2</span></div>
<div class="box box3"><span>3</span></div>
</div>
jsFiddle
From your question:
...but flex-basis still seems to be unsupported in Safari when flex-direction is column
I'm not sure this is correct (caniuse.com).
However, you can always use width or height properties instead of flex-basis (more details: What are the differences between flex-basis and width?).
Using Bootstrap,
<div class="row">
<div class="col-md-8">
<div class="red-element"></div>
</div>
<div class="col-md-4">
<div class="green-element"></div>
</div>
<div class="col-md-8">
<div class="yellow-element"></div>
</div>
<div class="clearfix"></div>
</div>
This uses float methods and works on all browsers.
you should using #media via margin-top.on specific screen width (via #media), change margin-top of the green-element to -200%. and change margin-top of yellow-element to 100%.they change their position very nice :)
please see this link:
http://jsbin.com/xozeviseka/edit?html,output
You need to change some html structure so then you can do this.
*,*:after,*:before {
box-sizing:border-box;
}
.two-columns {
position:relative;
background:#EFEFEF;
border:1px solid #000;
}
.red-element,
.green-element,
.yellow-element {
margin-bottom:30px;
}
.red-element {
height:70px;
background:#FF0004;
}
.green-element {
height:70px;
background:#7ED321;
}
.yellow-element {
height:100px;
background:#F8E71C;
}
#media (min-width:767px) {
.main-column {
width:70%;
padding:10px;
}
.sidebar-column {
position:absolute;
right:0;
top:0;
width:30%;
padding:10px;
}
}
<div class="two-columns">
<div class="main-column">
<div class="red-element"></div>
<div class="sidebar-column">
<div class="green-element"></div>
</div>
<div class="yellow-element"></div>
</div>
</div>
Or if you don't want to change html structure you have to take another element that only show in mobile for example
*,*:after,*:before {
box-sizing:border-box;
}
.two-columns {
background: #EFEFEF;
border: 1px solid #000;
overflow: hidden;
}
.red-element,
.green-element,
.yellow-element {
margin-bottom:30px;
}
.red-element {
height:70px;
background:#FF0004;
}
.green-element {
height:70px;
background:#7ED321;
}
.yellow-element {
height:100px;
background:#F8E71C;
}
.hideMobile{
display:none;
}
#media (min-width:767px) {
.main-column {
width: 70%;
float: left;
padding: 10px;
}
.sidebar-column {
float: right;
width: 30%;
padding: 10px;
}
.showMobile {
display:none;
}
.hideMobile {
display:block;
}
}
<div class="two-columns">
<div class="main-column">
<div class="red-element"></div>
<div class="green-element showMobile"></div><!--only for mobile-->
<div class="yellow-element"></div>
</div>
<div class="sidebar-column hideMobile"><!--hide in mobile-->
<div class="green-element"></div>
</div>
</div>
I'm having some trouble getting my image to take up no more than 100% of the available width of the parent container. I'm only noticing the issue in Firefox 36 (not IE or Chrome). So is it a firefox bug or am I missing something here?
Note: The image should never be larger than it's original size.
Chrome:
Firefox:
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.container {
width:300px;
}
.flexbox {
display:flex;
}
.flexbox .column {
flex:1;
background-color: red;
}
.flexbox .middleColumn {
flex:3;
}
.flexbox .middleColumn img {
width:auto;
height:auto;
max-width:100%;
max-height:100%;
align-self: center;
display: block;
}
</style>
</head>
<body>
<div class="container">
<div class="flexbox">
<div class="column">This is the left column!</div>
<div class="middleColumn">
<img src="http://placehold.it/400/333333">
</div>
<div class="column">This is the right column!</div>
</div>
</div>
</body>
</html>
You need to add min-width:0 on .middleColumn, if you want to allow it to shrink below its min-content width (the intrinsic width of its <img>-child).
Otherwise, it gets the new default min-width:auto, which on a flex item will basically make it refuse to shrink below its shrinkwrapped size.
(Chrome hasn't implemented min-width:auto yet. I'm told IE has, in their next-gen rendering engine, so I'd expect that version should behave like Firefox here -- as will Chrome, once they implement this feature.)
Snippet with that fixed:
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.container {
width:300px;
}
.flexbox {
display:flex;
}
.flexbox .column {
flex:1;
background-color: red;
}
.flexbox .middleColumn {
flex:3;
min-width:0;
}
.flexbox .middleColumn img {
width:auto;
height:auto;
max-width:100%;
max-height:100%;
align-self: center;
display: block;
}
</style>
</head>
<body>
<div class="container">
<div class="flexbox">
<div class="column">This is the left column!</div>
<div class="middleColumn">
<img src="http://placehold.it/400/333333">
</div>
<div class="column">This is the right column!</div>
</div>
</div>
</body>
</html>
I have to admit that I'm not sure why, but for some reason in Firefox it looks like you have to give the image a width/height (i.e. something other than "auto"). Our old friend 100% seems to do the trick:
.flexbox .middleColumn img {
width: 100%;
height: 100%;
display: block;
}
Here's a fiddle showing the working solution. Note that I changed the side columns to flex:2 to make the result a bit more apparent.
I seem to get this working with the following:
.flexbox {
display:flex;
}
.flexbox .column {
flex:1 1 0;
overflow:hidden;
background-color: red;
}
.flexbox .middleColumn {
flex-grow:3;
flex-shrink:3;
}
.flexbox .middleColumn img {
max-width:100%;
}
setting flex:1 1 0; on all columns sets them to equally grow and do so from the even and miniscule basis of 0px.
You then overide the grow and shrink on .middleColumn
max-width:100%; is needed as per usual
the magic seems to be overflow:hidden; on the item getting flexed.
the other stuff on the image is not needed.
In my experience, the approach is slightly different, maybe strange, but it works. Basically, I fix the max width to the real image width, so it won't pixelate, and use percentage width instead of max-width. If you have, say an <ul> (flex) container, the cells will be:
li{
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
width: 50%; // for example..
img{
display: block;
max-width: [your real img width in px] // instead of 100%;
width:100%; // instead of max-width
}
}
What I'm trying to achieve is to have items one below another in same starting line but to be centered in div. This is my fiddle: https://jsfiddle.net/7vdbLcL9/
<div class="container">
<div id="wrapper">
<div id="inner1">Zmaja od Bosne 5</div>
<div id="inner2">71 000 Sarajevo</div>
<div id="inner3">Bosnia and Herzegovina</div>
</div>
</div>
And the CSS:
.container{
width:40%;
border:1px solid black;
}
#wrapper{
margin-left:auto;
margin-right:auto;
height:auto;
width:auto;
text-align:center
}
I want to get this :
----------------------------------
Zmaja od Bosne 5
71 000 Sarajevo
Bosnia and Herzegovina
----------------------------------
You mean like this? https://jsfiddle.net/7vdbLcL9/1/
Your .container gets text-align:center,
and the #wrapper gets display:inline-block (so that it will be only as wide as needed, and can be centered via text-align of the parent) and text-align:left to counter the effect of center on the parent element.
Just use a flexbox:
.container {
display: flex;
flex-direction: column;
align-items: center;
width:40%;
border:1px solid black;
}
#wrapper { }
DEMO
Flexbox benefits:
minimal code; very efficient
centering, both vertically and horizontally, is simple and easy
equal height columns are simple and easy
multiple options for aligning flex items
it's responsive
it's the future of CSS layouts
Note that flexbox is supported by all major browsers, except IE 8 & 9. Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes. For a quick way to add all the prefixes you need, post your CSS in the left panel here: Autoprefixer.
.container{
width:40%;
border:1px solid black;
display:flex;
}
#wrapper{
margin-left:auto;
margin-right:auto;
height:auto;
width:auto;
text-align:center
display:flex;
}
Are you looking for something like this?
#wrapper {
display: block;
text-align: center;
line-height: 0;
font-size: 0;
margin-bottom: 20px;
}
#wrapper div {
display: inline-block;
width: auto;
}
#wrapper2 {
display: table;
}
#wrapper2 div {
display: table-cell;
width: 1%;
}
div div {
width: 200px; line-height: 100px; background: lightseagreen; font-size: 12px;
border: 1px solid yellow;
text-align: center;
padding: 0 1em;
}
<div id="wrapper">
<div id="inner1">Zmaja od Bosne 5</div>
<div id="inner2">71 000 Sarajevo</div>
<div id="inner3">Bosnia and Herzegovina</div>
</div>
<div id="wrapper2">
<div id="inner1">Zmaja od Bosne 5</div>
<div id="inner2">71 000 Sarajevo</div>
<div id="inner3">Bosnia and Herzegovina</div>
</div>
I'm trying to understand how to make my layout responsive. I have the following code:
<style>
.wrapper{width:1000px;}
.left{float:left; width:100%;max-width:641px;display:inline;}
.right{float:left;width:359px;display:inline;}
</style>
<div class="wrapper">
<div class="left"></div>
<div class="right"></div>
</div>
Now this is OK while the window width is over 1000px. When I shrink the window, the div.right is pushed to the new line instead of giving me the resposive shrinking of div.left. Please point me to the right direction. Thanx!
You sound like you want something flex-box can solve easily. http://codepen.io/tkrugg/pen/pmhrE
If you support only recent browsers, you should give it a try.
.wrapper{
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
max-width:1000px;
}
.left{
flex-grow:1;
}
.right{
flex-basis:359px;
}
add this Style to your html. this will work fine.
Demo
.wrapper{
display:table;
max-width:1000px;
width:100%;
}
.left{
display:table-cell;
max-width:641px;
}
.right{
display:table-cell;
width:349px;
}
That's because you're doing it wrong. What you should do instead is to use display: table; CSS property. That's how fluid grids work. So your code becomes this:
<style>
.wrapper { max-width: 1000px; margin: 0 auto; }
.row { display: table; width: 100%; height: auto; }
.left { /* 641px / 1000px = 0.641 * 100 = 64.1% */
width: 64.1%; display: table-cell; vertical-align: top; }
.right { /* 359px / 1000px = 0.359 * 100 = 35.9% */
width: 35.9%; display: table-cell; vertical-align: top; }
</style>
<div class="wrapper">
<div class="row">
<div class="left"></div>
<div class="right"></div>
</div>
</div>
You would have to create a breakpoint for mobile, and stack your divs on top of each other simply by setting display: block; and width: 100%;.
your code has some errors.only left div can see. if my answer doesn't help please put your whole code so people can see the error easily.
how ever your requirement can be achieved adding.
position: absolute;
to the right div like below.
.right{float:left;width:359px;display:inline;position: absolute;}
hope this helps.