How to style five rows with alternating fixed/variable width? - html

Example:
<div class="container">
<div>variable</div>
<div>fixed</div>
<div>variable with min-width</div>
<div>fixed</div>
<div>variable</div>
</div>
I want the whole thing to be as wide as the viewport.
I know how to do that for three columns, but I am completely lost with the five column version. I do not even have a concept of how that could work. The usual three column style involves absolute positioning of the fixed columns, but that would not work since the outermost columns are of variable width. I am lost.
Any ideas?
This is what I tried:
HTML:
<div class="container">
<div class="left">var</div>
<div class="inner_container">
<div class="inner_left">fix</div>
<div class="middle">var</div>
<div class="inner_right">fix</div>
</div>
<div class="right">var</div>
</div>
CSS:
.container {
position:relative;
}
.container div {
background: yellow;
}
.container .left,
.container .right {
background: orange;
width: 15%;
}
.inner_container {
position:relative;
}
.inner_container div {
margin:0 50px;
background:lightgreen;
}
.inner_container .inner_left,
.inner_container .inner_right {
background:lightblue;
position:absolute;
top:0;
width:50px;
}
.inner_container .inner_left {
left:-50px;
}
.inner_container .inner_right {
right:-50px;
}
The "inner_container" is basically the usual three column solution. If I set the inner_container to "left: 15%" the whole inner container is moved to the right, but still on its own "line".

flexbox can do that.
* {
box-sizing: border-box;
}
.container div {
height: 75px;
border:1px solid grey;
}
.container {
display: flex;
}
.variable {
background: lightgreen;
flex: 1 0 auto
}
.fixed {
background: lightblue;
flex: 0 0 150px;
}
.min-width {
flex-basis:250px;
min-width:250px;
background: pink;
}
<div class="container">
<div class="variable">variable</div>
<div class="fixed">fixed</div>
<div class="variable min-width">variable with min-width</div>
<div class="fixed">fixed</div>
<div class="variable">variable</div>
</div>
Codepen Demo

Related

Absolute-positioned div within a div that takes all remaining space

I'm trying to make a layout that seems simple. Despite looking at lots of examples, I can't crack it.
SideBar| .......MapContainer......
SideBar| ..........Map............
SideBar| .......MapContainer......
Both SideBar and MapContainer should be 100% height.
The tricky bit: Map must have a defined height and width, because the mapbox-gl-js library uses its dimensions to populate it. (Rather than adding content which then sizes it).
MapContainer exists because there will be other absolutely positioned overlay elements within it.
I'm trying to avoid having the sidebar width coded into the definition of MapContainer so I can hide/show the sidebar in JS, and have the MapContainer automatically fill the space.
This gets really, really close:
* {
box-sizing: border-box;
}
.sidebar, .mapcontainer, .container {
height: 200px;
}
.container {
width:100%;
border:1px solid;
display: flex
}
.sidebar {
width:200px;
background:lightblue;
}
.mapcontainer {
width:auto;
background:lightgreen;
position:relative;
flex-grow: 1;
}
.map {
width: 100%;
height: 100%;
position:absolute;
border: 20px dashed grey;
}
<div class="container">
<div class="sidebar"></div>
<div class="mapcontainer">
<div class="map">
</div>
</div>
</div>
But as soon as I change the "height: 200px" to "height: 100%", it collapses to nothing. What do I need to do?
Use viewport units vh instead in the .sidebar, .mapcontainer, .container rule
* {
box-sizing: border-box;
}
html, body {
margin: 0;
}
.sidebar, .mapcontainer, .container {
height: 100vh;
}
.container {
border: 1px solid;
display: flex
}
.sidebar {
width: 200px;
background:lightblue;
}
.mapcontainer {
background:lightgreen;
position:relative;
flex-grow: 1;
}
.map {
width: 100%;
height: 100%;
position:absolute;
border: 20px dashed grey;
}
<div class="container">
<div class="sidebar"></div>
<div class="mapcontainer">
<div class="map">
</div>
</div>
</div>
I just need to add height: 100%; to html and body:
* {
box-sizing: border-box;
}
html, body {
height: 100%;
margin: 0;
}
.sidebar, .mapcontainer, .container {
height: 100%;
}
.container {
width:100%;
border:1px solid;
display: flex
}
.sidebar {
width:200px;
background:lightblue;
}
.mapcontainer {
width:auto;
background:lightgreen;
position:relative;
flex-grow: 1;
}
.map {
width: 100%;
height: 100%;
position:absolute;
border: 20px dashed grey;
}
<div class="container">
<div class="sidebar"></div>
<div class="mapcontainer">
<div class="map">
</div>
</div>
</div>

DIV width: auto is 0 pixel

I'm new in CSS and have not not found the solution for this basic problem. I have 3 divs in one line. The center div must have fixed width and it's position also fixed px from the center. I need auto width for the left and right div to fill the space at the left/right side. Here is my try but the left and right divs are zero width. Thanks for the help!
.fullwidth{
width:100%
height:20px;
}
.left{
background-color:green;
float:left;
height:20px;
width: auto;
}
.center{
background-color:red;
position:absolute;
right:50%;
margin-right:100px;
height:20px;
width:100px;
}
.right{
background:blue;
float:right;
height:20px;
width: auto;
}
<div class="fullwidth">
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</div>
What you're looking for is known as the flexible box model design, it is fairly new so there are some vendor prefix requirements although I have emitted them for simplicity. You may have noticed that there is poor support for Internet Explorer so if that's a concern you may need to look for alternatives. Regardless take a look of it in use:
.fullwidth {
width: 100%;
height: 20px;
display: flex;
}
.left {background-color: green;}
.center {
background-color: red;
width: 100px;
}
.right {background: blue;}
.left,.right {flex: 1;}
<div class="fullwidth">
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</div>
flexbox can do that.
Codepen Demo - Click "View Compiled" for all vendor prefixes
* {
box-sizing: border-box;
}
.fullwidth {
height: 20px;
display: flex;
}
.fullwidth .left,
.fullwidth .right {
flex: 1 0 auto;
}
.left {
background-color: green;
}
.center {
background-color: red;
flex: 0 0 100px;
margin-left: -100px;
}
.right {
background: blue;
}
.line {
/* center point reference for demo only */
position: absolute;
height: 50px;
left: 50%;
width: 1px;
border-right: 1px solid green;
}
<div class="fullwidth">
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</div>
<div class="line"></div>
You could use CSS calc function
.fullwidth {
width: 100%;
height: 20px;
}
.fullwidth div {
float: left
}
.left {
background-color: green;
height: 20px;
width: calc(50% - 50px);
}
.center {
background-color: red;
height: 20px;
width: 100px;
}
.right {
background: blue;
height: 20px;
width: calc(50% - 50px);
}
<div class="fullwidth">
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</div>

Three column layout with an auto-width center column

I'm trying to create 3 columns layout, where structure should be main, left column, right column. The main column is auto-width to fill rest of page.
Unfortunately I cannot change the HTML, which is currently like this:
<div class="wrap">
<div class="main"></div>
<div class="left"></div>
<div class="right"></div>
</div>
Yes: That means I cannot change the order of divs.
I've found some solutions, one of these is by using display: table-cell, but there is issue when using float. Second solutions is layout by using flexbox, it is pretty good solution, but I cannot use it because of IE9 where this CSS style isn't supported.
Just to restate the aim: My need is to have left and right with fixed width, and main will fill rest of free space.
<---250px--><----------------auto-width-------------><---200px--->
<---Left-----><------------------main------------------><---right----->
Have anyone any solutions for this in pure CSS without any JavaScript?
Here you go. A simple CSS solution. Remember you should always clear your floats.
HTML
<div class="left"></div>
<div class="right"></div>
<div class="main"></div>
<div class="clear"></div>
CSS
.main, .left, .right {
min-height: 250px;
}
.left {
float: left;
background-color: green;
width: 50px;
}
.right {
float: right;
background-color: blue;
width: 50px;
}
.clear {
clear: both;
}
.main {
background-color: gray;
}
JSFiddle: http://jsfiddle.net/18rvc23q/
You could try floating the sidebars to the left and right respectively, and then applying some padding to the .main div to keep it from overlapping them.
<style>
.left {float: left; width: 250px;}
.right {float: right; width: 200px;}
.main {padding: 0 200px 0 250px;}
</style>
<div class="wrap">
<div class="right">right</div>
<div class="left">left</div>
<div class="main">main</div>
</div>
https://jsfiddle.net/1ofqkLmw/
Note that in this markup I've moved the main div to be the last child of wrap.
Also note that you can just as well use margin instead of padding - if you don't want the border and background to overlap the sidebars, then margin is the way to go.
You could use a mix of left and right margin on .main and then absolute position the .left and .right columns.
HTML
<div class="wrap">
<div class="main"></div>
<div class="left"></div>
<div class="right"></div>
</div>
CSS
.wrap {
position: relative;
}
.main {
border: 1px dashed red;
margin: 0 100px;
min-height: 300px;
}
.left,
.right {
width: 100px;
min-height: 300px;
position: absolute;
top: 0;
}
.left {
left: 0;
background-color: yellow;
}
.right {
right: 0;
background-color: blue;
}
Here's a jsFiddle of it in action: http://jsfiddle.net/1u9gzyh6/
Two ways to do this:
HTML
<div class="wrap">
<div class="left"></div>
<div class="main"></div>
<div class="right"></div>
</div>
The better (but unsupported in IE9-) way
.wrap {
display:flex;
}
.left {
flex-basis:250px;
}
.right {
flex-basis:200px;
}
.main {
flex-grow:1;
}
The somewhat hackier, but supported in IE9 (but not IE8- or certain mobile browsers) way
.wrap {
display:block;
}
.left {
width:250px;
}
.right {
width:200px;
}
.main {
width:calc(100% - 450px);
}
UPDATE: if you wanted to dynamically add / remove columns, just add a few extra classes in your CSS file:
.main.no-left {
width:calc(100% - 200px);
}
.main.no-right {
width:calc(100% - 250px);
}
.main.no-left.no-right {
width:100%;
}
And apply the classes dynamically via JS as needed. Anything else requires a JS solution that actually sets the width as an inline style, or makes use of position:absolute;, which can get real hacky, real fast.
EDITED:
<style>
div {
margin: 0;
padding: 0
}
div.main-wrapper {
overflow: hidden;
width: 700px;
margin: 0 auto;
}
div.left-wrapper {
float: left;
width: 500px;
}
div.left-col {
float: left;
width: 200px; /*change to what value you desire*/
background-color: #5446EB;
height: 400px;
}
div.main-col {
background-color: #DDEB46;
height: 400px;
}
div.right-col {
float: right;
width: 200px; /*change to what value you desire*/
background-color: #EB838D;
height: 400px;
}
</style>
<div class="main-wrapper">
<div class="left-wrapper">
<div class="left-col">
insert content of the left col here
</div>
<div class="main-col">
insert content of the main col here.
</div>
</div>
<div class="right-col">
insert content of the right col here
</div>
</div>
I think this should solve your problem:
.main, .left, .right {
height: 250px;
}
.left {
float: left;
background-color: green;
width: 50px;
position: relative;
margin-left: -300px; // negative width of main
}
.right {
float: left;
background-color: blue;
width: 80px;
margin-left: 50px; // width of left
}
.main {
width: 300px;
background-color: gray;
float: left;
position: relative;
left: 50px; // width of left
}
.wrap:after {
content: "";
clear: both;
}
<div class="wrap">
<div class="main">Main</div>
<div class="left">Left</div>
<div class="right">Right</div>
</div>

3-column layout (fixed-fluid-fixed) with full-screen height

I'm trying to achieve a 3-column fixed-fluid-fixed layout. Also, the height of the layout must take up the whole screen so that it looks like 3 solid columns going from top-to-bottom.
Summary:
Left-column: fixed-width
Center-column: resizeable-width
Right-column: fixed-width
- The height for all 3 columns takes up entire screen.
- All 3 columns are always equal length.
My problem is getting the last part to work. I can not get all 3 columns to be equal height.
Here is my HTML/CSS:
<style type="text/css">
.parent {
margin-bottom:20px;
position:relative;
background-color: green;
}
.main {
margin-left:20%;
background:#ddd;
padding: 10px;
height: 100%;
}
.side {
position:absolute;
width:20%;
top:0;
bottom:0;
background-color: green;
}
.left {
left:0;
background-color: red;
}
.right {
right:0;
background-color: blue;
}
</style>
<div class="parent">
<div class="side left">
Sub Content
</div>
<div class="main">
Main Content<br>
<img src="" width="200" height="600">
</div>
<div class="side right">
Sub Content
</div>
</div>
Is this what you need? http://jsfiddle.net/3MfBa/
HTML:
<div class="side left">
Sub Content
</div>
<div class="main">
Main Content<br>
<img src="" width="200" height="600">
</div>
<div class="side right">
Sub Content
</div>
CSS:
.main {
position: absolute;
top:0;
bottom:0;
left:20%;
right:20%;
background:#ddd;
padding: 10px;
overflow: auto;
}
.side {
position:absolute;
width:20%;
top:0;
bottom:0;
background-color: green;
}
.left {
left:0;
background-color: red;
}
.right {
right:0;
background-color: blue;
}
Alternative CSS (http://jsfiddle.net/DgPRZ/):
body { margin:0; padding:0;}
.main {
margin-left:20%;
margin-right:20%;
background:#ddd;
padding: 10px;
}
.side {
position:fixed;
width:20%;
top:0;
bottom:0;
background-color: green;
}
.left {
left:0;
background-color: red;
}
.right {
right:0;
background-color: blue;
}
ALT VERSION 2 (http://jsfiddle.net/B4X4p/2/):
HTML:
<div class="container">
<div class="col side left">
Sub Content
</div>
<div class="col main">
<div class="main-content">
Main Content<br>
</div>
</div>
<div class="col side right">
Sub Content
</div>
</div>
CSS:
html, body { margin:0; padding:0; height:100%;}
.container, .container > div.col {
display: flex;
flex: 1 0 auto;
}
.container {
width:100%;
min-height:100%;
}
.main {
width: 60%;
background:#ddd;
float:left;
}
.main-content {
padding: 10px;
}
.side {
width:20%;
background-color: green;
min-height:100%;
float:left;
}
.left {
background-color: red;
}
.right {
background-color: blue;
}
To maintain column width you've to use either bootstrap or any framework or custom CSS that I've written below. It can be done with jquery as per your scenario.
.left-column,.right-column,.center-column{width:25%;display:inline-block;height:100vh;}
.center-column{width:50% !important;}
This will make side columns 25% and center one 50%; vh stands for viewport height. It will give you full height based on your viewport without any positioning hack.
T0 make only center part resizable. I guess you need jquery.
I recommend using Bootstrap it's easy to use and implement.
With Bootstrap you could have something like this:
<div class="row">
<div class="col-lg-4 col-md-4 col-sm-4></div>
<div class="col-lg-4 col-md-4 col-sm-4></div>
<div class="col-lg-4 col-md-4 col-sm-4></div>
</div>
And this would do the trick. Bootstrap uses a grid layout system and it is responsive. Read more at getbootstrap.com

3 div's middle div take up remaining width

Alright guys, I've been busting my balls over this one.
I've got three divs; left, middle, right. All 100% height. The left and right div have a fixed width of 150px. Now I want the middle div to take up the remaining space.
Example: Here
CSS:
#left {
height:100%;
width:150px;
float:left;
background:red;
z-index:999;
}
#middle {
height:100%;
width:100%;
background:yellow;
margin-left:-150px;
margin-right:-150px;
}
#right {
float:right;
height:100%;
width:150px;
background:red;
z-index:998;
}
Use display: table:
#container {
display: table;
width: 100%;
}
#left, #middle, #right {
display: table-cell;
}
#left, #right {
width: 150px;
}
Where the #container is your parent element like in
<div id="container">
<div id="left"></div>
<div id="middle"></div>
<div id="right"></div>
</div>
Here is a Fiddle.
Okay using flex and based this answer
#parent {
display: flex;
}
#left {
width:150px;
background-color:#ff0000;
}
#middle {
flex: 1 1 auto;
background-color:#00ff00;
}
#right {
width: 150px;
background-color:#0000ff;
}
<div id="parent">
<div id="left">left</div>
<div id="middle">middle</div>
<div id="right">right</div>
</div>
This actually works if the left and right divs has variable width also.
Check this similar answer
HTML
<div class = "container">
<div class = "fixed">
I'm 150px wide! Glee is awesome!
</div>
<div class = "fluid">
I'm fluid! Glee is awesome!
</div>
<div class = "fixed">
I'm 150px wide! Glee is awesome!
</div>
</div>
CSS
html, body {
height: 100%;
font-family: 'Arial', 'Helvetica', Sans-Serif;
}
.container {
display: table;
width: 100%;
height: 100%;
}
.container > div {
display: table-cell;
text-align: center;
}
.fixed {
width: 150px;
background: rgb(34, 177, 77);
color: white;
}
.fluid {
background: rgb(0, 162, 232);
}
DEMO
If you don't want to use table cells and don't want to give your outer boxes a fixed width (instead let their width be determined by their content, you can use the overflow-hidden and float method)
The bad thing about this method is you have to adhere to having overflow hidden on your divs and also you have to arrange your divs in a backwards way (see below)
DEMO
HTML
<div class='container'>
<div class='third-box'>Third</div>
<div class='first-second'>
<div class='first-box'>First</div>
<div class='second-box'>Second</div>
</div>
</div>
CSS
.container {
width: 400px;
}
.first-second {
overflow: hidden;
}
.first-box {
float: left;
background-color: coral;
}
.second-box {
overflow: hidden;
background-color: aquamarine;
}
.third-box {
float: right;
background-color: salmon;
}
I used this to set a flexible width for the items to the side. Used it in a listed item to get a progress bar with 2 buttons on the side.
ul {
display: table;
width: 100%;
}
ul > li {
display: table-cell;
}
ul > li:nth-child(2) {
min-width: 100%;
}