css flex-box multiple overflow scroll - css

I wonder if it possible to use flex in order to set the width of an overflow-scrolled row to the width of a sibling non overflow-scrolled row.
See this example: https://codepen.io/AgentCisco/pen/mdKeaRQ
css:
body {
background: #aaa;
}
// outer parent to cut a viewing window
#container {
// center in parent
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
width: 400px;
background: #444;
overflow: auto;
}
.flex-scroll-container {
display: flex;
}
.break { display: flex; overflow-x: scroll; }
// inner parent allowed to stretch to fit children
.flex-scroll {
// inside spacing
padding: 30px 20px;
display: flex;
align-items: center;
justify-content: center;
//flex-wrap: nowrap;
}
.box {
width: 75px;
height: 75px;
}
.box:nth-child(3n-2) { background-color: #EF5350; }
.box:nth-child(3n-1) { background-color: #2E7D32; }
.box:nth-child(3n) { background-color: #03A9F4; }
I'd like the third row (containing more boxes than the second one) to be the same width of the second row and keep its own horizontal scroll.
Is it possible to achieve?
Thanks a lot,

Here is my solution:
HTML:
<div id="container">
<div class="flex-scroll-container">
<div class="flex-scroll">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
<div class="flex-scroll-container">
<div class="flex-scroll">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
<div class="">
<div class="break">
<div class="flex-scroll-new">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
</div>
</div>
CSS:
body {
background: #aaa;
}
// outer parent to cut a viewing window
#container {
// center in parent
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
width: 400px;
background: #444;
overflow: auto;
}
.flex-scroll-container {
display: flex;
}
.break {
overflow-x: auto;
}
// inner parent allowed to stretch to fit children
.flex-scroll {
// inside spacing
padding: 30px 20px;
display: flex;
align-items: center;
justify-content: center;
//flex-wrap: nowrap;
}
.box {
width: 75px;
height: 75px;
}
.break .box {
min-width: 75px;
}
.flex-scroll-new {
display: flex;
padding: 30px 20px;
}
.box:nth-child(3n-2) { background-color: #EF5350; }
.box:nth-child(3n-1) { background-color: #2E7D32; }
.box:nth-child(3n) { background-color: #03A9F4; }
JS:
document.querySelector('.break').style.width = (document.querySelector('.flex-scroll-container:nth-child(2) > .flex-scroll').offsetWidth - 20) + 'px';

Related

CSS div in bottom not showing if applied margin

I'm trying to achieve the following:
I was able to replicate the image but only if my div is not floating in the page (without the margin applied and without the position: absolute), otherwise I can't see the green rectangle.
My HTML structure is the following:
<div class="app">
<div class="interface">
<div class="view">
<div class="body">
<div class="top">
Top content
</div>
<div class="middle">
Middle content
</div>
<div class="bottom">
Bottom content
</div>
</div>
</div>
</div>
</div>
In the .interface CSS I have the following:
.interface
{
position: absolute;
top: 15%;
}
With this CSS I'm unable to see the green rectangle. If I remove the position: absolute (and therefore the top: 15% stops applying) I'm able to see the green rectangle.
You can see the issue in this JSFiddle: https://jsfiddle.net/v9euwdz3/
So, how do I manage to have the DIV showing at a certain level (margin from top) and without compromise my HTML structure?
Here is what you're trying to achieve using flex:
.body {
display: flex;
flex-direction: column;
background-color: blue;
justify-content: space-between;
height: 100vh;
}
.navetc {
background-color: white;
height: 15vh;
}
.top {
background-color: green;
height: 60px;
}
.middle {
background-color: yellow;
flex-grow: 1;
}
.bottom {
background-color: red;
height: 50px;
}
<div class="app">
<div class="interface">
<div class="view">
<div class="body">
<div class="navetc">
SPACE
</div>
<div class="top">
Top content
</div>
<div class="middle">
Middle content
</div>
<div class="bottom">
Bottom content
</div>
</div>
</div>
</div>
</div>
You could also use margin-top: 15%; instead of a placeholder div
.body {
display: flex;
flex-direction: column;
background-color: blue;
justify-content: space-between;
height: 100vh;
}
.top {
margin-top: 15vh;
background-color: green;
height: 60px;
}
.middle {
background-color: yellow;
flex-grow: 1;
}
.bottom {
background-color: red;
height: 50px;
}
<div class="app">
<div class="interface">
<div class="view">
<div class="body">
<div class="top">
Top content
</div>
<div class="middle">
Middle content
</div>
<div class="bottom">
Bottom content
</div>
</div>
</div>
</div>
</div>
(I used vh instead of % to get it to show up correctly in this code snippet)
as we know the content that have height which is 100% means is 100% of its parent and while the height of the parent is not defined will cause an error that's what you was stuck with you set the with of body to 100% but was not right you would set it to 100vh to fit the screen if you are on computer and the other mistakes that I found was in your calculation where you used to subtract the measurement which is in parcentages from the one in pixels height: calc(100% - 150px); and the others where simple mistakes
html,
body {
height: 100vh;
}
.app {
position: relative;
height: 100%;
display: flex;
}
.interface {
position: absolute;
height: 100%;
top: 15%;
}
.view {
position: fixed;
height: 100%;
background-color: #ccc;
width: 350px;
}
.body {
position: relative;
height: 100%;
}
.body .top {
height: 15%;
border: 1px solid #000;
}
.body .middle {
height: 60%;
border: 1px solid red;
}
.body .bottom {
height: 20%;
border: 1px solid green;
}
<div class="app">
<div class="interface">
<div class="view">
<div class="body">
<div class="top">
Top content
</div>
<div class="middle">
Middle content
</div>
<div class="bottom">
Bottom content
</div>
</div>
</div>
</div>
</div>
to see the result in the snippet you should observe it in full page and also when you see the result through jsfiddle there at the result section there is bar downward which hide some part of footer

Flexbox space-between but center if one element

I've the following HTML and CSS.
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
</div>
.container-box {
width: 200px;
display: flex;
flex-direction: row;
justify-content: space-between;
background-color: red;
margin:50px;
}
.box {
background-color: #9009A0;
height: 50px;
width: 50px;
}
Which gives this layout:
The first layout for multiple items does what I expect, but how can I change the second to position the element in center as it only has one element?
See this codepen: https://codepen.io/dennismadsen/pen/oNvqjjV
For cases where you have one item in the container, you can use the :only-child pseudo-class.
Add this to your code:
.box:only-child {
margin: 0 auto;
}
.container-box {
width: 200px;
display: flex;
flex-direction: row;
justify-content: space-between;
background-color: red;
margin: 50px;
}
.box {
background-color: #9009A0;
height: 50px;
width: 50px;
}
.box:only-child {
margin: 0 auto;
}
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
</div>
In such cases, flex auto margins will override justify-content because:
§ 8.1. Aligning with auto
margins
Prior to alignment via justify-content and align-self, any
positive free space is distributed to auto margins in that dimension.
More about :only-child:
§ 6.6.5.10. :only-child
pseudo-class
The :only-child pseudo-class represents an element that has no
siblings. Same as :first-child:last-child or
:nth-child(1):nth-last-child(1), but with a lower specificity.
More about flex auto margins:
In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
Also, to spotlight some interesting flex behavior, if you were using space-around instead of space-between, you wouldn't need auto margins.
Flex item should align left, not center, when it wraps
For info, You could also use together :first-child and :last-child if you wanted to mind about very old browsers ;)
.container-box {
width: 200px;
display: flex;
flex-direction: row;
justify-content: space-between;
background-color: red;
margin: 50px;
}
.box {
background-color: #9009A0;
height: 50px;
width: 50px;
}
.container-box .box:first-child:last-child {
margin: 0 auto;
}
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
</div>
Here is a different idea with only margin:
.container-box {
width: 400px;
display: flex;
background-color: red;
margin: 30px;
}
.box {
background-color: #9009A0;
height: 50px;
width: 50px;
}
.box:first-child {
margin-right: auto;
}
.box:last-child {
margin-left: auto;
}
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
</div>
If you will have more than 3 elements you can add an extra rule
.container-box {
width: 400px;
display: flex;
background-color: red;
margin: 30px;
}
.box {
background-color: #9009A0;
height: 50px;
width: 50px;
}
.box:not(:last-child):not(:first-child) {
margin:auto;
}
.box:first-child {
margin-right: auto;
}
.box:last-child {
margin-left: auto;
}
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
</div>

css3 flex: How to create 2 columns with : 100% + fixed width?

I am trying to make a simple flex layout:
#header {
background-color: grey;
}
#container {
display:flex;
height: calc(100vh - 50px);
}
#chatAndUserContainer {
display: flex;
width: 100%;
}
#chatContainer {
background-color: red;
width:100%;
}
#usersContainer {
background-color: green;
width:320px;
}
<div id="header">header</div>
<div id="container">
<div id="chatAndUserContainer">
<div id="chatContainer">
chatContainer
</div>
<div id="usersContainer">
usersContainer
</div>
</div>
</div>
The problem is : when rendered, the width of #usersContainer is not 320px but... 274px !
Any idea on how to correct that ? (I need to use display:flex, not absolute)
You are facing the shrink effect. Since the total width (100% + 320px) is bigger than 100% both your elements will shrink equally to fit their parent container.
To avoid this you can disable the shrink for the second div:
#header {
background-color: grey;
}
#container {
display:flex;
height: calc(100vh - 50px);
}
#chatAndUserContainer {
display: flex;
width: 100%;
}
#chatContainer {
background-color: red;
width:100%;
}
#usersContainer {
background-color: green;
width:320px;
flex-shrink:0;
}
<div id="header">header</div>
<div id="container">
<div id="chatAndUserContainer">
<div id="chatContainer">
chatContainer
</div>
<div id="usersContainer">
usersContainer
</div>
</div>
</div>
Or don't use width:100% and replace it with flex:1 so that your first div will fill the remaining space left by the second one:
#header {
background-color: grey;
}
#container {
display:flex;
height: calc(100vh - 50px);
}
#chatAndUserContainer {
display: flex;
width:100%;
}
#chatContainer {
background-color: red;
flex:1;
}
#usersContainer {
background-color: green;
width:320px;
}
<div id="header">header</div>
<div id="container">
<div id="chatAndUserContainer">
<div id="chatContainer">
chatContainer
</div>
<div id="usersContainer">
usersContainer
</div>
</div>
</div>
You can use calc() in #chatContainer, or min-width in #usersContainer, or use them both like in example below.
#header {
background-color: grey;
}
#container {
display:flex;
height: calc(100vh - 50px);
}
#chatAndUserContainer {
display: flex;
width: 100%;
}
#chatContainer {
background-color: red;
width:calc(100% - 320px);
}
#usersContainer {
background-color: green;
width:320px;
min-width: 320px;
}
<div id="header">header</div>
<div id="container">
<div id="chatAndUserContainer">
<div id="chatContainer">
chatContainer
</div>
<div id="usersContainer">
usersContainer
</div>
</div>
</div>

CSS How do I force a container to be displayed underneath a preceding container whose elements float left

I want the div which displays "D" to appear beneath that one which displays "A" so that divs with matching background colours appear stacked over one another. However, I am getting this:
Where exactly in my CSS code must I clear my float?
#container {
background-color: #333333;
width: 990px;
}
#left {
background-color: red;
width: 300px;
float: left;
}
#splitter {
background-color: green;
width: 90px;
float: left;
}
#right {
background-color: blue;
width: 200px;
float: left;
}
<div id="container">
<div id="left">A</div>
<div id="splitter">B</div>
<div id="right">C</div>
</div>
<div id="container">
<div id="left">D</div>
<div id="splitter">E</div>
<div id="right">F</div>
</div>
You have to deal with floats and for this you need to understand what floats and BFC are :
a few ways to do this, that you should understand once you been reading a bit about floats, clearing and Block formating context.
(last example in the snippet below, oldish, even avoids the floats but does the layout)
/* DEMO purpose : Show the id or class being used on that container*/
section:before {
content: attr(id)' 'attr(class);
display: table;
background: #177EE5;
padding: 5px;
margin: 5px;
color: #fff;
text-shadow: 0 0 1px black, 0 0 1px black, 0 0 1px black, 0 0 1px black, 0 0 1px black, 0 0 1px black;
letter-spacing: 1px;
font-variant: small-caps;
}
/* your css turned into class to be valid since used for many tags */
.container {
background-color: #333333;
width: 990px;
}
.left {
background-color: red;
width: 300px;
float: left;
}
.splitter {
background-color: green;
width: 90px;
float: left;
}
.right {
background-color: blue;
width: 200px;
float: left;
}
/* wrapper for each examples */
section {
clear: both;
overflow: hidden;
margin: 1em;
}
/* different ways shown, usefull for testing only if you read about floats and dig a bit */
/* table */
.table .container {
display: table;
}
/* overflow */
.overflow .container {
overflow: hidden;
}
/* float */
.float .container {
float: left;
}
/* flex */
.flex .container {
display: flex;
}
/* inline-block */
.inline-block .container {
display: inline-block;
vertical-align: top;
}
/* last examples without floats */
/*no float & ie8 */
#table div {
float: none
}
#table #first-row,
#table > div {
display: table-row;
}
#table > div > div {
display: table-cell;
}
#table {
background-color: #333333;
width: 990px;
table-layout: fixed;
}
#left {
width: 300px;
}
#splitter {
width: 90px;
}
#right {
width: 200px;
}
#table > div > div {
background-color: red;
}
#table > div > div + div {
background-color: green;
}
#table > div > div + div + div {
background-color: blue;
}
#table:before {
display: table-caption;
width: 100%;
margin: 0;
}
#table > div:after {
content: "Notice there's a gap to fill here since cols do not cover the 990px";
display: table-cell;
}
<section class="your CSS :-: no BFC involved">
<div class="container">
<div class="left">A</div>
<div class="splitter">B</div>
<div class="right">C</div>
</div>
<div class="container">
<div class="left">D</div>
<div class="splitter">E</div>
<div class="right">F</div>
</div>
</section>
<section class="table">
<div class="container">
<div class="left">A</div>
<div class="splitter">B</div>
<div class="right">C</div>
</div>
<div class="container">
<div class="left">D</div>
<div class="splitter">E</div>
<div class="right">F</div>
</div>
</section>
<section class="overflow">
<div class="container">
<div class="left">A</div>
<div class="splitter">B</div>
<div class="right">C</div>
</div>
<div class="container">
<div class="left">D</div>
<div class="splitter">E</div>
<div class="right">F</div>
</div>
</section>
<section class="float">
<div class="container">
<div class="left">A</div>
<div class="splitter">B</div>
<div class="right">C</div>
</div>
<div class="container">
<div class="left">D</div>
<div class="splitter">E</div>
<div class="right">F</div>
</div>
</section>
<section class="flex">
<div class="container">
<div class="left">A</div>
<div class="splitter">B</div>
<div class="right">C</div>
</div>
<div class="container">
<div class="left">D</div>
<div class="splitter">E</div>
<div class="right">F</div>
</div>
</section>
<section class="inline-block">
<div class="container">
<div class="left">A</div>
<div class="splitter">B</div>
<div class="right">C</div>
</div>
<div class="container">
<div class="left">D</div>
<div class="splitter">E</div>
<div class="right">F</div>
</div>
</section>
<p>another way without float including IE8 ?</p>
<section id="table" class="table">
<div id="first-row">
<div id="left">A</div>
<div id="splitter">B</div>
<div id="right">C</div>
</div>
<div>
<div>D</div>
<div>E</div>
<div>F</div>
</div>
</section>
There could be more examples from the same chunks of code and floatting children.
Clear the floats in the container.
You have 3 simple ways to do that:
1. Float
#container {
clear: both;
}
2. Overflow
#container {
overflow: hidden;
}
3. Micro clearfix hack
Link
Here is what you want done bro..
this one is by using display:inline-block https://jsfiddle.net/p4domjrb/
this one is by using float:left https://jsfiddle.net/p4domjrb/1/
.container {
background-color: #333333;
width: 990px;
display: block;
position: relative;
}
.left {
background-color: red;
width: 300px;
display: inline-block;
margin-left: -4px;
}
.splitter {
background-color: green;
width: 90px;
display: inline-block;
margin-left: -4px;
}
.right {
background-color: blue;
width: 200px;
display: inline-block;
margin-left: -4px;
}
don't use id I suggest use class isntead because idis called only once.
<style>
.container{
background-color: #333333;
width:990px;
display:block;
clear:both;
}
#left{
background-color: red;
width:300px;
float:left;
}
#splitter{
background-color: green;
width:90px;
float:left;
}
#right{
background-color: blue;
width: 200px;
float:left;
}
</style>
<body>
<div class="container">
<div id="left">A</div>
<div id="splitter">B</div>
<div id="right">C</div>
</div>
<div class="container">
<div id="left">D</div>
<div id="splitter">E</div>
<div id="right">F</div>
</div>
</body>
result is

CSS : Apply background to full width in a div with a fixed width

My page is divided in rows with limited width. (<div class='row'>)
I would like to apply a background (color) to each row, but I would like the back ground not to take into consideration the width limit of the div, is there a way to achieve this ?
Thanks!
Were you going for something like this? It'd be easier to answer your question if you provided a fiddle or atleast some code so we can help you with your problem.
I came to this solution:
<div class="row1">
...
</div>
<div class="row2">
...
</div>
.row1 {
background-color: red;
width: 100%;
height: 50%;
}
.row2 {
background-color: pink;
width: 100%;
height: 50%;
}
You can run it here: JSFiddle
This is possible with a pseudo-element, no need for additional HTML.
.wrapper {
width: 50%;
margin: auto;
}
[class^=row] {
height: 50px;
position: relative;
margin-bottom: 10px;
}
[class^=row]:before {
content: '';
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
height: 100%;
width: 100vw;
background: purple;
z-index: -1;
}
.row1 {
background-color: red;
}
.row2 {
background-color: pink;
}
<div class="wrapper">
<div class="row1">...</div>
<div class="row2">...</div>
</div>
You may be better to place each row inside a .container-fluid div with a {min-width: 100%} and a custom class for the colour you need
.container-fluid {
min-width: 100%
}
.row {
max-width: 300px;
margin: 0 auto;
padding: 10px;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.blue {
background-color: blue;
}
<div class="container-fluid red">
<div class="row">
<p>Row Content 1</p>
</div>
</div>
<div class="container-fluid green">
<div class="row">
<p>Row Content 2</p>
</div>
</div>
<div class="container-fluid blue">
<div class="row">
<p>Row Content 3</p>
</div>
</div>

Resources