divs with display: table-column have size=0 - css

I am trying to create something similar to this:
I tried with the following code, but I see nothing:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
* {
margin: 0;
}
#table {
width: 100%;
height: 100%;
display: table;
}
#left {
width: 30%;
height: 100%;
display: table-column;
}
#right {
width: 70%;
height: 100%;
display: table-column;
}
#left_1, #left_2, #left_3, #right_1 {
display: table-cell;
text-align: center;
vertical-align: middle;
}
#left_1 {
background-color: green;
height: 40%;
}
#left_2 {
background-color: red;
height: 30%;
}
#left_3 {
background-color: lightgray;
height: 30%;
}
#right_1 {
background-color: black;
color: white;
height: 100%;
}
</style>
</head>
<body>
<div id="table">
<div id="left">
<div id="left_1">left_1</div>
<div id="left_2">left_2</div>
<div id="left_3">left_3</div>
</div>
<div id="right">
<div id="right_1">right_1</div>
</div>
</div>
</body>
</html>
I was able to successfully use table-row, but I can't get table-column to work. What am I doing wrong?

You can get it with flexbox.
The needed changes in CSS
#table {
display: flex;
}
#left, #right {
flex: 1;
display: flex;
flex-direction: column;
}
#left_1, #left_2, #left_3, #right_1 {
display: flex;
align-items: center;
justify-content: center;
}
updated jsfiddle demo: https://jsfiddle.net/1mew6hqj/2/
Check this guide for flexbox to learn how it works.

+1 to Michael Coker, but here is another possibility.
* {
margin: 0;
}
body,
html {
height: 100%;
}
#table {
width: 100%;
max-height: 250px;
height: 100%;
display: block;
position: relative;
}
#left {
width: 30%;
height: 100%;
display: table;
float: left;
}
#right {
width: 70%;
height: 100%;
display: table;
float: left;
}
.row { display: table-row; }
#left_1,
#left_2,
#left_3,
#right_1 {
width: 100%;
display: table-cell;
text-align: center;
vertical-align: middle;
}
#left_1 {
background-color: green;
height: 40%;
}
#left_2 {
background-color: red;
height: 30%;
}
#left_3 {
background-color: lightgray;
height: 30%;
}
#right_1 {
background-color: black;
color: white;
height: 100%;
}
<div id="table">
<div id="left">
<div class="row">
<div id="left_1">left_1</div>
</div>
<div class="row">
<div id="left_2">left_2</div>
</div>
<div class="row">
<div id="left_3">left_3</div>
</div>
</div>
<div id="right">
<div class="row">
<div id="right_1">right_1</div>
</div>
</div>
</div>
Note: I hope this isn't for a responsive site...

Related

absolute is not available for the grandchildren of flex elements?

How do I get the .top_box to be fixed in the head of the .content?
With the current code, the .top_box always scrolls along with the .content.
.wrapper {
height: 160px;
display: flex;
flex-direction: column;
}
.title_container {
background: pink;
}
.content {
height: 0;
flex: auto;
position: relative;
overflow-y: auto;
overflow-x: hidden;
background-color: bisque;
}
.top_box {
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 16px;
background: royalblue;
}
.scroll_fill {
height: 500px;
}
<div class="wrapper">
<div class="title_container">anyString</div>
<div class="content">
<div class="top_box"></div>
<div class="scroll_fill"></div>
</div>
</div>
You can just change the order of the HTML-Elements in the code and write .top before .item. If you do that, you can also remove most of the CSS because it’s unnecessary.
Here‘s a full example:
.box1 {
height: 600px;
display: flex;
flex-direction: column;
}
.box2 {
background: pink;
}
.box3 {
background-color: red;
}
.top {
width: 300px;
height: 5px;
background: blue;
}
.item {
height: 1000px;
}
<div class="box1">
<div class="box2">anyString</div>
<div class="box3">
<div class="top"></div>
<div class="item"></div>
</div>
</div>
Also a few other things: I wouldnt recommend just using divs and naming them like box1, box2, box3, .... Instead, give them names wich describe their use and meaning like wrapper, top_container, bottom_container, top_item, content, ...:
CSS Naming Conventions.
You can also use specific tags with semantic meanings: Sematic HTML5 Elements
Hope that helps
.wrapper {
height: 160px;
display: flex;
flex-direction: column;
}
.title_container {
background: pink;
}
.content {
height: 0;
flex: auto;
position: relative;
overflow: hidden;
background-color: bisque;
}
.contentInner {
height: 100%;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
}
.top_box {
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 16px;
background: royalblue;
}
.scroll_fill {
height: 500px;
}
<div class="wrapper">
<div class="title_container">anyString</div>
<div class="content">
<div class="top_box"></div>
<div class="contentInner">
<div class="scroll_fill"></div>
</div>
</div>
</div>

How do I keep the divs side by side in the container?

I want to create container that has two elements with colors given in the picture. The two are different divs and must stay side by side. How do I do it?
Here is my code:
<html>
<head>
<title>Testing</title>
<style>
.container{
width: 50%;
height: 50%;
}
.sidenav{
width: 25%;
height: 100%;
background-color: black;
}
.bgrnd{
width: 75%;
height: 100%;
background-color: blue;
float: left;
}
</style>
</head>
<body>
<div class="container">
<div class="sidenav">
</div>
<div class="bgrnd">
</div>
</div>
</body>
</html>
You didn't set a height on the body of the document so setting a percentage on the divs won't do anything until you do. You also needed to float the sidenav div.
.container {
width: 50%;
height: 50%;
}
.sidenav {
width: 25%;
height: 100%;
background-color: black;
float: left
}
.bgrnd {
width: 75%;
height: 100%;
background-color: blue;
float: left;
}
html,
body {
height: 100%;
}
<div class="container">
<div class="sidenav">
</div>
<div class="bgrnd">
</div>
</div>
Your code Updated!
body, html{
padding:0px;
margin:0px;
height:100%;
}
.container{
width: 50%;
height: 50%;
}
.sidenav{
width: 25%;
height: 100%;
background-color: black;
float: left;
}
.bgrnd{
width: 75%;
height: 100%;
background-color: blue;
float: left;
}
<div class="container">
<div class="sidenav"></div>
<div class="bgrnd"></div>
</div>
How about this:
<div class="container">
<div class="sidenav">
test
</div>
<div class="bgrnd">
test
</div>
</div>
CSS:
.container {
width: 50%;
height: 50%;
}
.sidenav {
width: 25%;
height: 100%;
background-color: black;
color: #fff;
float: left;
}
.bgrnd {
width: 75%;
height: 100%;
background-color: blue;
color: #fff;
float: right;
}
You can set .sidenav and .bgrnd to position: absolute; and position them accordingly from there. Also, you've set .container to: width: 50%; and height: 50%; which I presume you don't want.
.container {
height: 100%;
width: 100%;
}
.sidenav {
width: 25%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background-color: black;
}
.bgrnd {
width: 75%;
height: 100%;
position: absolute;
top: 0;
left: 25%;
background-color: blue;
}
<!DOCTYPE html>
<html>
<head>
<title>Testing</title>
</head>
<body>
<div class="container">
<div class="sidenav"></div>
<div class="bgrnd"></div>
</div>
</body>
</html>
How about using css-flex.
#main {
width: 100%;
border: 1px solid #c3c3c3;
display: -webkit-flex; /* Safari */
-webkit-flex-direction: row-reverse; /* Safari 6.1+ */
display: flex;
flex-direction: row-reverse;
}
.div1 {
width: 25%;
height: 50px;
}
.div2 {
width: 75%;
height: 50px;
}
<div id="main">
<div class="div1" style="background-color:coral;">A</div>
<div class="div2" style="background-color:lightblue;">B</div>
</div>

Element to take remaining height of viewport

Please consider this style:
.root {
display: flex;
flex-direction: column;
height: 100%;
}
.header {
width: 100%;
background-color: red;
display: flex;
height: 100px;
justify-content: space-between;
.logo-pane {
width: 100px;
height: 100px;
background-color: green;
}
.user-actions {
width: 100px;
height: 100px;
background-color: blue;
}
}
.content {
flex-grow: 1;
background-color: pink;
}
What I want to achieve is that the content element will take the remaining height of the viewport, but it takes only his content height.
HTML:
<div class="root">
<div class="header">
<div class="logo-pane">Logo</div>
<div class="user-actions">User Actions</div>
</div>
<div class="content">
content
</div>
</div>
Codepen
The problem is the surrounding .root. You have to increase the height of the .root to the remaining space. So you have to set the height:100vh; on .root. Try the following solution:
body, html {
margin:0;
padding:0;
}
.root {
display: flex;
flex-direction: column;
height: 100vh;
align-items:stretch;
align-content:stretch;
}
.header {
width: 100%;
background-color: red;
display: flex;
height: 100px;
justify-content: space-between;
}
.logo-pane {
width: 100px;
height: 100px;
background-color: green;
}
.user-actions {
width: 100px;
height: 100px;
background-color: blue;
}
.content {
flex-grow:1;
background-color: pink;
}
<div class="root">
<div class="header">
<div class="logo-pane">Logo</div>
<div class="user-actions">User Actions</div>
</div>
<div class="content">content</div>
</div>
.content {
flex-grow: 1;
background-color: pink;
height: 100vh;
}
Set the :root to 100vh (100% of the viewport height) instead 100%
You can simply add
height: 100% to html, body
add height to 20% for root div
add height to 80% for content div
will solve your problem
html,body {
height: 100%;
}
Here is the jsFiddle
Hope it helps :)
I think your misunderstanding what flex does. Flex is used to align its children, not to fill a viewport. Heres another solution.
https://jsfiddle.net/rob_primacy/1wnpr50s/
<div class="root">
<div class="header">
<div class="logo-pane">Logo</div>
<div class="user-actions">User Actions</div>
</div>
</div>
<div class="content">
content
</div>
and the css
.root {
display: flex;
flex-direction: column;
height: 100%;
position: relative;
}
.header {
width: 100%;
background-color: red;
display: flex;
height: 100px;
justify-content: space-between;
position: relative;
}
.user-actions {
width: 100px;
height: 100px;
background-color: blue;
}
.logo-pane {
width: 100px;
height: 100px;
background-color: green;
}
.content {
background-color: pink;
position: absolute;
height: 100%;
left: 8px;
right: 8px;
}
Use like this
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Untitled 1</title>
<style type="text/css">
body{
margin:0;
}
.root {
display: flex;
flex-direction: column;
height: 100%;
}
.header {
width: 100%;
background-color: red;
display: flex;
height: 100px;
justify-content: space-between;
.logo-pane {
width: 100px;
height: 100px;
background-color: green;
}
.user-actions {
width: 100px;
height: 100px;
background-color: blue;
}
}
.content {
flex-grow: 1;
background-color: pink;
height:100%;
width:100%;
position: fixed;
}
</style>
</head>
<body>
<div class="root">
<div class="header">
<div class="logo-pane">Logo</div>
<div class="user-actions">User Actions</div>
</div>
<div class="content">
content
</div>
</div>
</body>
</html>
Your codepen linked works fine. I do not understand where you get stuck.
You could basicly build your template from 2 containers :example with header and main
html,
body {
height: 100%;/* or just : 100vh; for body only */
margin: 0;
}
body {
display: flex;
flex-direction: column;
/* width and margin:auto is avalaible */
}
header {
/* height: 50px;or do not set any and let grow from its content */
background: gray;
}
main {
flex: 1;/* will fill up all space left */
background: lightblue;
/* overflow:auto; optionnal if you do not want html to scroll and keep header fixed */
}
<header>
whatever <br/> sizes me
</header>
<main>
content
</main>
Make it simple to start with :)

Flexbox - How to create a responsive dynamic flexbox grid

I want to learn and try Flexbox therefore just to build a grid construct that looks like this:
Possible sizes of boxes: 4x4, 2x1, 1x1 - they are to be dynamic anywhere.
Responsive to all boxes to the same size
Actually i have this :
.tab {
width: 500px;
height: 100px;
display: flex;
flex-flow: column wrap-reverse;
color: green;
}
.col-wrap-4x4 {
width: 200px;
height: 200px;
display: flex;
flex-flow: column wrap;
}
.col-1x1 {
background-color: black;
border: solid 1px green;
}
.col-1x1.one {
width: 50px;
height: 50px;
}
.col-1x1.two {
width: 100px;
height: 50px;
}
.col-1x1.four {
width: 100px;
height: 100px;
}
<div class="tab">
<div class="col-wrap-4x4">
<div class="col-1x1 four">1</div>
<div class="col-1x1 two">2</div>
<div class="col-1x1 one">3</div>
<div class="col-1x1 one">4</div>
</div>
</div>
Everything I've tried so far has not worked.
Does such a thing anyway?
Like this?
Don't forget that ur parent element must be as big as ur child's + border or margin
.tab {
width: 604px;
height: 100px;
flex-flow: column wrap-reverse;
display: block;
color: green;
}
.col-wrap-4x4 {
width: 230px;
height: auto;
display: inline-block;
flex-flow: column wrap;
}
.col-1x1 {
background-color: black;
/*border: solid 1px green;*/
}
.col-1x1.one {
width: 50px;
height: 50px;
}
.col-1x1.two {
width: 110px;
height: 50px;
}
.col-1x1.four {
width: 100px;
height: 110px;
}
.myClass{
display: inline-block;
float: left;
position: relative;
margin : 10px 5px 0;
}
<div class="tab">
<div class="col-wrap-4x4">
<div class="col-1x1 myClass four">1</div>
<div class="col-1x1 myClass two">2</div>
<div class="col-1x1 myClass one">3</div>
<div class="col-1x1 myClass one">4</div>
</div>
</div>
Greetz

Floated Div Tags Wrapping to New Line When Window Resizes

I have two divs that I want to float on the same line. I don't want the right one to wrap until the window gets around 250px wide.
I am setting the initial widths of the divs to percentages and this seems to be causing issues. The right div will wrap to a new line well before it shrinks to a min-width of 100px;
<div id="#container">
<div id="left">
<div id="box"></div>
</div>
<div id="right">
<h1>Hello World</h1>
</div>
</div>
#container {
display: table;
width: 100%;
}
#box {
width: 100px;
height: 100px;
background: gray;
display: inline-block;
max-width: 100%;
}
#left {
float: left;
width: 23.6%;
min-width:150px;
background: gold;
text-align: center;
}
#right {
float: left;
width: 76.4%;
min-width:100px;
background: pink;
}
http://jsfiddle.net/5C6GB/
Removing the width on the right div partially solved the problem.
But it looks like I had to resort to using display:table*
http://jsfiddle.net/5C6GB/3/
<div id="container">
<div class="tr">
<div id="left" class="td">
<div id="box"></div>
</div>
<div id="right" class="td">
<!-- <h1>Hello World</h1> -->
</div>
</div>
</div>
#container {
display: table;
width: 100%;
background: red;
height: 100px;
}
#box {
width: 100px;
height: 100px;
background: gray;
display: inline-block;
max-width: 100%;
}
#left {
width: 25%;
min-width:150px;
background: gold;
text-align: center;
height: 100%;
}
#right {
min-width:100px;
background: pink;
width: 75%;
vertical-align: bottom;
}
.tr {
display: table-row;
width: 100%;
}
.td {
display: table-cell;
}
#media only screen and (max-width: 600px) {
#left, #right {
display:block;
width: 100%;
min-height: 100px;
}
.tr {
display: block;
}
#container {
display: block;
}
}
It's the min-width:150px; in the left div which is causing the right div to wrap to a new line well before it shrinks to a min-width of 100px;
#left {
float: left;
width: 23.6%;
min-width:150px; /*remove or change this to a smaller amount */
background: gold;
text-align: center;
}
FIDDLE

Resources