Vertical divider line in a scrollable flexbox div element - css

I have a vertically central adaptable scrollable flexbox element, which itself should have two columns (I solved this with two child-divs). The central flexbox should have a frame and a central divider line.
I can't get the central divider line to run all the way to the bottom of the scrollable flexbox. I tried it with a third child div element but the line only appears for the vertical extent of the flexbox.
How can I make two columns in a scrollable flexbox with a frame and central divider line running all the way to the bottom?
Thank you for your help.
Here is the example:
https://jsfiddle.net/soliman/0d0tn22x/2/
<body>
<div class="wrapper">
<div class="header">
<h1>Header</h1>
</div>
<div class="content">
<div class="leftContent"> Column 1
With a lot of lines.
</div>
<div class="divider"></div>
<div class="rightContent"> Column 2
With fewer lines
</div>
</div>
<div class="footer">
Footer
</div>
</div>
</body>
CSS:
html,
body {
height: 100%;
margin: 0;
padding: 0;
background: black;
color: red;
}
.wrapper {
display: flex;
/* use the flex model */
height: 100%;
flex-direction: column;
}
.header {
margin: 1em 1em 0 1em;
}
.content {
flex: 1 1 auto;
display: flex;
overflow-y: auto;
position: relative;
min-height: 100px;
margin: 0 1em 0 1em;
border: 6px double red;
}
.content > div {
width: 50%;
padding: 3%;
}
.content > div:first-child {
margin-right: 10px;
}
.footer {
margin: 0 1em 1em 1em;
}
.divider {
position: absolute;
left: 50%;
top: 0%;
bottom: 0%;
border-left: 6px double red;
}

Try this mixed flexbox and CSS table layout. You can set the content area as a table, and the three columns as table cells, so they always be equal height.
There is one issue with the approach is - it only works properly if the content is taller than the container, otherwise the vertical line will stop in the middle. See the other approach at the bottom.
jsFiddle
html,
body {
height: 100%;
margin: 0;
}
.wrapper {
height: 100%;
display: flex;
flex-direction: column;
}
.content {
flex: 1;
overflow-y: auto;
min-height: 100px;
border: 1px solid;
}
.wrapContent {
display: table;
width: 100%;
}
.wrapContent > div {
display: table-cell;
}
.leftContent,
.rightContent {
width: 50%;
}
.divider {
border-left: 1px solid;
}
<div class="wrapper">
<div class="header">
<h1>Header</h1>
</div>
<div class="content">
<div class="wrapContent">
<div class="leftContent">
<div style="height:500px;">Left</div>
</div>
<div class="divider"></div>
<div class="rightContent">
<div style="height:auto;">Right</div>
</div>
</div>
</div>
<div class="footer">
<p>Footer</p>
</div>
</div>
Another way would be using background image for the vertical line, set that to the center of the content container, with repeat-y, the image can be just a square dot. It works well even if the content is shorter than the container.
jsFiddle
html,
body {
height: 100%;
margin: 0;
}
.wrapper {
height: 100%;
display: flex;
flex-direction: column;
}
.content {
flex: 1;
display: flex;
overflow-y: auto;
min-height: 100px;
border: 1px solid;
background: url("http://i.imgur.com/oyQ4xsL.png") center top repeat-y;
background-size: 1px;
}
.leftContent,
.rightContent {
width: 50%;
}
<div class="wrapper">
<div class="header">
<h1>Header</h1>
</div>
<div class="content">
<div class="leftContent">
<div style="height:500px;">left</div>
</div>
<div class="rightContent">
<div style="height:auto;">right</div>
</div>
</div>
<div class="footer">
<p>Footer</p>
</div>
</div>

Related

How can I slide in a div inside of the container when :hover, and squished specific divs and not others?

I have div container with 3 div inside. div 3 is hidden out of the container, on the right side, div 1 is supposed to be in the left of the container (but its width should be as big as possible), and div 2 on the right.
When the container is :hover, I want div 3 to slide in from the right side, push div 2 to the left, and squish div 1 (while div 2 and 3 widths remain stable).
<div class="container">
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
</div>
I've tried playing with flex-shrink, flex-basis, with no success. I've tried to put div1 and div2 in a separate div, like this:
<div class="container">
<div class="div4">
<div class="div1">
<h3>A title here</h3>
<p>a description here</p>
</div>
<div class="div2">
<p>text<p>
</div>
</div>
<div class="div3"></div>
</div>
And the CSS:
.container {
height: 68px;
overflow: hidden;
display: flex;
flex-direction: row;
align-items: stretch;
border: 1px solid #000000;
}
.div4 {
display: flex;
flex-direction: row;
width: 100%;
}
.div1 {
width: 100%;
min-width: 0px;
background: yellow;
flex-shrink: -1;
}
.div1 h3, .div1 p {
margin: 0px;
overflow: hidden;
text-overflow: ellipsis;
}
.div2 {
background: red;
min-width: 68px;
}
.div3 {
height: 68px;
min-width: 60px;
background: #99E2D0;
position: relative;
right: -60px;
}
.container:hover > .div3 {
right: 0px;
}
My main issue here is that I'm moving div3 out of the container width right: -60px;, but div4 doesn't stretch to the full width of the container.
Here is the codepen:
https://codepen.io/MaximeZind/pen/KKeeeEb

How to show only three items per row?

I want to created a wrapper component in React, which take a children items, and the wrapper should only show three items per row (inputs, checkboxes, whatever).
And also for bigger screens the cells should not stretch, and items have to be grouped tightly. But when the screen shrinks, items have to wrap and change number of columns.
That's how it should be for bigger screens:
I thought css grid perfectly fits, but I can't find the proper way to do so.
Since you don't have any code shared, this is difficult to answer because we have no reference/starting point of where you are at.
Here is a blitz I put together for you showing a few ways to achieve what I think you need.
EDIT: Here is a snippet of the three options I included.
Option 1: Limit the number of children per parent. Then you can add a flexbox to the parent to control wrapping. Repeat this for how ever many you need.
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div> //repeat
Option 2: Flex Basis
<div class="parent2">
<div class="child2">
<div class="grandchild"></div>
</div>
<div class="child2">
<div class="grandchild"></div>
</div>
</div> // Put your data inside the grandchild component and add a flex basis to the child component
Option 3: Flex and Position
<div class="parent3">
<div class="child3">
<h2>1 </h2>
</div>
<div class="child3">
<h2>2</h2>
</div>
<div class="child3">
<h2>3</h2>
</div>
<div class="spacing"></div>
<div class="child3">
<h2>4 </h2>
</div>
<div class="child3">
<h2>5</h2>
</div>
<div class="child3">
<h2>6</h2>
</div>
</div>
Here are all the styles I used
.parent {
display: flex;
font-size: 0;
flex-wrap: wrap;
margin: 10px;
}
.child {
background: blue;
margin: 10px 0 0 10px;
height: 100px;
width: 100px;
}
/* ....................................... */
.parent2 {
display: flex;
font-size: 0;
flex-wrap: wrap;
margin: 10px;
}
.child2 {
flex-basis: 30%;
background: lightblue;
margin: 10px 0 0 10px;
height: 100px;
width: 100px;
}
.grandchild {
border: 3px solid red;
height: 50px;
width: 50px;
}
/* ....................................... */
.parent3 {
width: 100%;
min-height: 100px;
height: auto;
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
}
.child3 {
width: 100px;
height: 100px;
background-color: lightgreen;
margin: 10px;
position: relative;
}
.spacing {
width: 100%;
height: 5%;
}

How to get a div to fill the remainder of the screen height [duplicate]

This question already has answers here:
Make a div fill the height of the remaining screen space
(41 answers)
Closed 4 years ago.
I've got a div, I need the bottom div to fill the remainder of the screen and show a scroll bar. The bottom div is not showing a scroll bar.
JSFiddle
.page {
position: fixed;
top: 0;
width: 100%;
height: 100%;
margin: 0;
padding: $menu-height 0 0 0;
box-sizing: border-box;
}
.sidebar {
width: 500px;
float: left;
height: 100%;
box-sizing: border-box;
background: #ddd;
border-right: 1px solid red;
}
.top {
height: 200px;
background: #eee;
}
.bottom {
background: #ccc;
overflow-y: auto;
}
.filler-content {
height: 2000px;
}
<div class="page">
<div class="sidebar">
<div class="top">
top
</div>
<div class="bottom">
<div class="filler-content">
bottom
</div>
</div>
</div>
</div>
If I understood your problem correctly, display: flex is your friend.
Add display: flex; flex-direction: column; to your .sidebar and flex: 1; to your .bottom and that should do it. If I misunderstood, just let me know in a comment and I'll try to help otherwise
Demo: http://jsfiddle.net/qy5fL29t/23/
I would use a flexbox solution as it will make it a lot simpler and get rid of the need for using floats (we shouldn't be abusing them in the day of css3)
html,
body {
height: 100%;
margin: 0;
}
.page {
height: 100%;
display: flex; /* this one is so that you don't need to float the sidebar and can insert a main area that will take up the rest of the width */
flex-direction: column;
flex-wrap: wrap;
}
.sidebar {
width: 500px;
height: 100%;
display: flex; /* this is so we can get bottom to take any height top doesn't need */
flex-direction: column;
background: #ddd;
border-right: 1px solid red;
}
.top {
flex-basis:200px;
min-height: 200px; /* these two are to force top to be 200px otherwise flex may recalculate based on available space */
max-height: 200px;
background: #eee;
}
.bottom {
flex-grow: 1; /* this forces bottom to grow to fill the space top doesn't take */
overflow-y: auto;
}
/* test and example below */
.filler-content {
height:1000px;
}
.main {
flex-grow: 1;
background: white;
}
<div class="page">
<div class="sidebar">
<div class="top">
top
</div>
<div class="bottom">
<div class="filler-content">
bottom
</div>
</div>
</div>
<div class="main">
</div>
</div>
Replace your css with this
.sidebar {
width: 500px;
float: left;
height: 100%;
box-sizing: border-box;
background: #ddd;
border-right: 1px solid red;
}
.top {
height: 200px;
background: #eee;
}
.bottom {
background: #ccc;
overflow-y: scroll;
height:200px
}
.filler-content {
height:2000px;
}
<html>
<body>
<div class="page">
<div class="sidebar">
<div class="top">
top
</div>
<div class="bottom">
<div class="filler-content">
bottom
</div>
</div>
</div>
</body>
</div>
</html>
You can use this code for bottom div srollbar.
.bottom {
background: #ccc;
overflow-y: auto;
height:200px;
}

Parent DIV to inherit width (%) from child div

I am currently trying to figure out a way to be able to have a layout that has a bottom-up, content-oriented resizing behavior.
I have the following situation: https://codepen.io/Flash1232/pen/JJYPVQ
What is wrong here is obviously that the wrapper divs do not wrap around the table divs. Now is there any solution for this involving just plain CSS and HTML or do I have to write something in JS like "set wrapper width to the width of its inner div"?
Thanks in advance for any clues!
Man i solved my problem with display:flex on parent element :)
You may want to consider using a flexbox. Please see below. If there is anything that needs to be different, just let me know.
.outer-div {
position: absolute;
background: black;
width: 800px;
left: 0;
top: 0;
bottom: 0;
overflow: auto;
padding: 10px;
}
.area {
overflow: auto;
display: flex;
border: 5px solid red;
background: white;
margin: 10px 40px 10px 10px;
}
.column {
background: green;
border: 5px solid blue;
}
.wrapper {
display: flex;
border: 5px solid yellow;
justify-content: center;
align-items: center;
}
.table {
white-space: nowrap;
}
.violet {
background: violet;
width: 120%;
height: 80px;
}
.red {
background: red;
width: 150%;
height: 80px;
margin-bottom: 20px;
}
.icons {
Background: yellow;
float: right;
height: auto;
width: auto;
}
<div class="outer-div">
<div class="area">
<div class="column">
<div class="wrapper">
<div class="table red">
<span>***Table Content***</span>
</div>
</div>
<div class="wrapper">
<div class="table violet">
<span>***Table Content***</span>
</div>
</div>
</div>
<div class="column">
<div class="wrapper">
<div class="table violet">
<span>***Table Content***</span>
</div>
</div>
</div>
</div>
<div class="icons">
<p>Icon</p>
<p>Icon</p>
<p>Icon</p>
<p>Icon</p>
<p>Icon</p>
<p>Icon</p>
</div>
</div>
You should read the definition of the width attribute.
https://developer.mozilla.org/en/docs/Web/CSS/width
Percentages: refer to the width of the containing block
If you set width to 150%, you explicitly say, that the child should be bigger than the parent. You can not expect, that the parent has the same width like the child, if you force the child to be wider.

Two columns inside container

What I want to do is have a <div> with a container class and a fixed width, holding a <div> with the block class to prevent other content encroaching on any uneven blank space, then two columns (<div>'s) side-by-side inside the block, and to be 50% of the width of the block.
When I create this, I get what appears to be a margin after the first block, which I do not want. I want the block to pack up tight, no margins.
I have an example here of what I have so far, and here if the code:
<html>
<head>
<title>Columns</title>
<style>
div {
margin: 0;
padding: 0;
}
.container {
background: #DDD;
width: 1200px;
margin: 0 auto;
padding: 2% 0;
}
.block {
background: #555;
width: 100%;
display: block;
}
.col {
width: 49%;
display: inline-block;
background: #333;
}
</style>
</head>
<body>
<div class="container">
<div class="block">
<div class="col left">
<h1>Left</h1>
</div>
<div class="col right">
<h1>Right</h1>
</div>
</div>
</div>
</body>
</html>
Your problem is being causes by inline-block, using this makes a space appear inbetween.
Try using float:left to get around this:
See on jsFiddle
.col {
width: 50%;
float: left;
box-sizing: border-box;
background: #333;
}
Note that I added, box-sizing:border-box; this means when you use padding it will be included in the width, not on top of it. Effectively enabling the use of it without an extra inner div.
Remember to include a clear fix afterwards also to "clear" the floats.
CSS
.clear {
clear:both;
}
HTML
<div class="block">
<div class="col left">
<h1>Left</h1>
</div>
<div class="col right">
<h1>Right</h1>
</div>
<div class="clear"></div>
</div>
Try replacing these classes:
.block {
background: none repeat scroll 0 0 #555555;
display: block;
overflow: auto;
width: 100%;
}
.col {
width: 49%;
float: left;
background: #333;
}
.container {
background: #DDD;
width: 900px;
margin: 0 auto;
padding: 30px 30px 30px 30px;
}
.block {
background: #555;
width: 100%;
display: block;
}
.block:after {
content: "";
display: table;
clear: both;
}
.col {
width: 50%;
float: left;
background: #333;
}

Resources