Element does not expand to fill parent flex div - css

html,
body {
margin: 0;
height: 100%;
}
.navbar {
position: fixed;
top: 0;
width: 100%;
height: 50px;
background-color: #2D4256;
}
.nav-centre {
margin: 0 auto;
width: 40%;
height: 100%;
}
.nav-container {
display: flex;
height: 100%;
align-items: center;
/* vertically centre */
}
.nav-item {
color: white;
width: 40px;
text-align: center;
}
.main-content {
height: calc(100% - 50px);
width: 100%;
position: absolute;
bottom: 0;
overflow-y: overlay;
display: flex;
justify-content: center;
}
.main-wrap {
width: 40%;
border-left: 1px solid black;
border-right: 1px solid black;
}
.box {
width: 200px;
height: 200px;
background: white;
border: 1px solid black;
margin: 10px;
}
<body>
<div class="navbar">
<div class="nav-centre">
<div class="nav-container">
<div class="nav-item">1</div>
<div class="nav-item">2</div>
<div class="nav-item">3</div>
<div class="nav-item">4</div>
</div>
</div>
</div>
<div class="main-content">
<div class="main-wrap">
<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>
</body>
The main-wrap div is not expanding to fill the parent main-content div, how can I get the main-wrap element to expand to the full height of the parent?
https://codepen.io/woooof/pen/VwBLprj

The .main-wrapper is getting by default display:block, which doesn't match with the display:flex parent.
To get the value from the parent, you can use display: inherit. Once done, the elements inside won't respect their width. To fix that, you must wrap the elements, and for making it total height, You can use max-content.
.main-wrapper {
display: inherit;
flex-wrap: wrap;
height: max-content;
}
Result:
html,
body {
margin: 0;
height: 100%;
}
.navbar {
position: fixed;
top: 0;
width: 100%;
height: 50px;
background-color: #2D4256;
}
.nav-centre {
margin: 0 auto;
width: 40%;
height: 100%;
}
.nav-container {
display: flex;
height: 100%;
align-items: center;
/* vertically centre */
}
.nav-item {
color: white;
width: 40px;
text-align: center;
}
.main-content {
height: calc(100% - 50px);
width: 100%;
position: absolute;
bottom: 0;
overflow-y: overlay;
display: flex;
justify-content: center;
}
.main-wrap {
width: 40%;
border-left: 1px solid black;
border-right: 1px solid black;
display: inherit;
flex-wrap: wrap;
height: max-content;
}
.box {
width: 200px;
height: 200px;
background: white;
border: 1px solid black;
margin: 10px;
}
<body>
<div class="navbar">
<div class="nav-centre">
<div class="nav-container">
<div class="nav-item">1</div>
<div class="nav-item">2</div>
<div class="nav-item">3</div>
<div class="nav-item">4</div>
</div>
</div>
</div>
<div class="main-content">
<div class="main-wrap">
<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>
</body>

I am not a huge fan of making the size of one element (navbar) determine the position of the second element main-content (margin-top). where you have height: calc(100% - 50px); I would rather if the style of the first changes. Say for example we increase navbar font size, you would not need to adjust the second manually.
Here in this example I set the font-size on an ancestor block to change the nav buttons size and not have to change the content. font-size: 1.5rem;
Change it even larger; again no change to the content CSS;
I put a lot of comments in and some borders just to show where things line - that can and should all be removed for a production version.
html,
body {
margin: 0;
height: 100%;
/* stack the nav and the content blocks */
display: grid;
grid-template-rows: 1fr auto;
}
.navbar {
/* put the navbar at the top */
position: sticky;
top: 0;
background-color: #2D4256;
/* flex, default vertical/horizontal centers nav-centre in the flex */
display: flex;
}
.nav-centre {
margin: 0 auto;
display: flex;
}
.nav-container {
display: flex;
/* again these are the default here
flex-direction: row;
align-items: center;
justify-content: center;
*/
/* how much space above and below the yellow border nav container */
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
.nav-item {
color: white;
/* 2 times font-size for cyan border items */
width: 2em;
text-align: center;
}
.main-content {
display: grid;
justify-content: center;
}
.main-wrap {
border-left: 1px solid black;
border-right: 1px solid black;
}
.box {
width: 200px;
height: 200px;
background: white;
border: 1px solid black;
margin: 10px;
}
/* below here is just for visual clarification and can be removed */
.navbar {
/* just to show you can style and not effect content block *
/* this can be on any of the three containers */
font-size: 1.5rem;
font-family: Verdana, Arial, Helvetica, sans-serif;
}
.nav-centre {
border: 1px solid magenta;
padding: 2px;
}
.nav-container {
border: 1px solid yellow;
}
.nav-item {
border: 1px solid cyan;
/* you can space out the nav buttons */
margin: 0 0.25rem;
}
.main-content {
/* just to show it is below the navbar and separate */
border: solid red 1px;
margin-top: 0.25rem;
margin-left: 0.5rem;
margin-right: 0.5rem;
}
.box {
background-color: #ffffdd;
}
<body>
<div class="navbar">
<div class="nav-centre">
<div class="nav-container">
<div class="nav-item">1</div>
<div class="nav-item">2</div>
<div class="nav-item">3</div>
<div class="nav-item">4</div>
</div>
</div>
</div>
<div class="main-content">
<div class="main-wrap">
<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>
</body>

Related

How can we shrink middle flex item?

I am trying to make a layout from flexbox. I have 3 column of boxes which have following layout till they reach mobile layout where they will stack on top of another.
But before I reach mobile layout I am trying to shrink all the items proportionally. (i.e when I reduce the browsers width, it should equally be small). But only the left and right items are equally reducing except the middle item. How do I make that shrink so that all the items proportionally shrink while reducing browsers width?
CODE GOES HERE
.container {
width: 100%;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding-top: 80px;
}
.box {
width: 400px;
/* min-width: 280px; */
height: 400px;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid black;
font-size: 30px;
font-weight: bold;
font-family: cursive;
box-shadow: 1px 4px 3px rgba(0, 0, 0, 0.5);
}
.box1 {
background: grey;
}
.box2 {
background: green;
margin-bottom: 20px;
}
.box3 {
background: greenyellow;
}
.box4 {
background: orange;
}
.middle-part {
margin: 0px 20px;
/* min-width: 280px; */
}
<div class="container">
<div class="box box1">
I am box1
</div>
<div class="middle-part">
<div class="box box2">
I am box2
</div>
<div class="box box3">
I am box3
</div>
</div>
<div class="box box4">
I am box4
</div>
</div>
If you want it to shrink dynamically, you need to remove the width set. Add flex-grow: 1 on .box and .middle-part to make it grow. In addition, padding-top only accept 1 value, so perhaps some typos there.
.container {
width: 100%;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding-top: 80px 40px; /* padding top only accept 1 value */
}
.middle-part {
flex-grow: 1;
}
.box {
flex-grow: 1;
/* min-width: 280px; */
height: 400px;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid black;
font-size: 30px;
font-weight: bold;
font-family: cursive;
box-shadow: 1px 4px 3px rgba(0, 0, 0, 0.5);
}
.box1 {
background: grey;
}
.box2 {
background: green;
margin-bottom: 20px;
}
.box3 {
background: greenyellow;
}
.box4 {
background: orange;
}
.middle-part {
margin: 0px 20px;
/* min-width: 280px; */
}
<body>
<div class="container">
<div class="box box1">
I am box1
</div>
<div class="middle-part">
<div class="box box2">
I am box2
</div>
<div class="box box3">
I am box3
</div>
</div>
<div class="box box4">
I am box4
</div>
</div>
</body>

Horizontally-scrolling div inside a flex column

I can't seem to have a horizontally-scrolling div inside a flex column.
Codepen
.container { display: flex; margin: 20px; height: 300px; border: 1px solid blue; }
.side-nav { flex-shrink: 0; width: 100px; min-height: 100%; background: grey; }
.main { padding: 20px; }
.scrollable { overflow-x: auto; max-width: 100%; }
.long-content { width: 2000px; height: 50px; background: red; }
<div class='container'>
<div class='side-nav'>
</div>
<div class='main'>
<h1>Test</h1>
<div class='scrollable'>
<div class='long-content'>
This is supposed to scroll horizontally unless your window is super wide
</div>
</div>
<p>Some paragraph below the scrollable box</p>
</div>
</div>
If I change the max-width of .scrollable to px it would work, but I need it to fill the column.
What am I missing?
In my opinion, this is a Module"bug" (Wierd).
Anyway, one very simple solution is to use flex-basis (Instead of width).
Step 1 for main add width: 0;
.container {
display: flex;
margin: 20px;
height: 300px;
border: 1px solid blue;
}
.side-nav { flex-shrink: 0; width: 100px; min-height: 100%; background: grey; }
.main {
padding: 20px;
border: 5px dashed orange;
/* "new code" */
width: 0px;
}
.scrollable { overflow-x: auto; max-width: 100%; }
.long-content { width: 2000px; height: 50px; background: red; }
<div class='container'>
<aside class='side-nav'>
Aside
</aside>
<main class='main'>
<h1>Test</h1>
<div class='scrollable'>
<div class='long-content'>
This is supposed to scroll horizontally unless your window is super wide
</div>
</div>
<p>Some paragraph below the scrollable box</p>
</main>
</div>
Step 2 - main add flex-basis: 100%;
.container {
display: flex;
margin: 20px;
height: 300px;
border: 1px solid blue;
}
.side-nav { flex-shrink: 0; width: 100px; min-height: 100%; background: grey; }
.main {
padding: 20px;
border: 5px dashed orange;
/* "new code" */
width: 0px;
flex-basis: 100%;
}
.scrollable { overflow-x: auto; max-width: 100%; }
.long-content { width: 2000px; height: 50px; background: red; }
<div class='container'>
<aside class='side-nav'>
Aside
</aside>
<main class='main'>
<h1>Test</h1>
<div class='scrollable'>
<div class='long-content'>
This is supposed to scroll horizontally unless your window is super wide
</div>
</div>
<p>Some paragraph below the scrollable box</p>
</main>
</div>
One more option is to use width: 0; & flex-grow:1
.container {
display: flex;
margin: 20px;
height: 300px;
border: 1px solid blue;
}
.side-nav { flex-shrink: 0; width: 100px; min-height: 100%; background: grey; }
.main {
padding: 20px;
border: 5px dashed orange;
/* "new code" */
width: 0px;
flex-grow: 1;
}
.scrollable { overflow-x: auto; max-width: 100%; }
.long-content { width: 2000px; height: 50px; background: red; }
<div class='container'>
<aside class='side-nav'>
Aside
</aside>
<main class='main'>
<h1>Test</h1>
<div class='scrollable'>
<div class='long-content'>
This is supposed to scroll horizontally unless your window is super wide
</div>
</div>
<p>Some paragraph below the scrollable box</p>
</main>
</div>
I don't like any of those ideas - but this is life hh.

How to shrink the width of div when the elements are removed in resize div

Question: I am having two div's A & B where DIV A is having min and max width with resize horizontal feature and Div B is auto width.
Now when Div A has 4 divs in it when each div is removed the width of DIVA is auto shrinked but when i dragg div A to right and remove an element in DIV A the width is not auto
.resizeE {
border-right: 6px solid;
display: flex;
align-items: stretch;
justify-content: flex-start;
align-content: center;
width: auto;
min-width: 150px;
max-width: 250px;
height: 100%;
resize: horizontal;
overflow: auto;
}
.E1 .E2 .E3 .E4 {
border: 2px solid #A0A0A0;
width: 50px;
height: 50px;
}
.box {
width: 30px;
float: left;
margin: 5px;
}
.red {
color: red;
background: pink;
}
.blue {
color: blue;
background: light-blue;
}
.green {
color: green;
background: pink;
}
.map {
width: 100%;
}
<div style="height:100%;width:100%;background: #e2e2e2;overflow-y: hidden;overflow-x: hidden;">
<div class="resizeE">
<div class="red box">E1</div>
<div class="red box">E2</div>
<div class="blue box">E3</div>
<div class="green box">E4</div>
</div>
<div class="col p-5">
<div class="map">
block B
</div>
</div>
</div>

Css solution for circle and line

I am looking for a css solution to the below image that is responsive.
I have the following html and css, but it isn't respnosive and I need the line to float alongside the circle.
<div class="col-xs-6 col-sm-2">
<div class="circle"> </div>
<div class="line"><img src="assets/line.png" class="black-line"></div>
</div>
.circle {
background-color:#fff;
border:2px solid #222;
height:50px;
border-radius:50%;
-moz-border-radius:50%;
-webkit-border-radius:50%;
width:50px;
float: left;
line-height: 50px;}
.line { line-height: 50px; text-align: center; float: left; padding: 0 8px;}
Here's a working responsive version of this:
.container {
border-bottom: 3px solid #111;
height: 1rem;
display: flex;
justify-content: space-between;
}
.circle {
display: inline-block;
background: #fff;
width: 2rem;
height: 2rem;
border: 2px solid #111;
border-radius: 2.5rem;
box-shadow: 0 0 0 0.5rem #fff;
}
#media (min-width: 768px) {
.container {
height: 2.5rem;
}
.circle {
width: 5rem;
height: 5rem;
}
}
<div class="container">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
Elements of this might not suit your needs, although with the information provided it's difficult to say. However, it should provide a solid starting point.
Here's my attempt on a responsive approach with flexbox. The crossing line has been done using a pseudoelement (no need to use markup for styling purpose)
The gap between a circle and the line has been done with the box-shadow property
<div class="circlesbox">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
CSS
.circlesbox {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
}
.circlesbox:before {
content: "";
position: absolute;
zindex: 1;
left: 0;
top: 50%;
transform: translateY(-50%);
height: 3px;
width: 100%;
background: #000;
}
.circle {
position: relative;
z-index: 2;
border: 2px solid #222;
background: #fff;
box-shadow: 0 0 0 20px #fff;
width:50px;
height:50px;
border-radius:50%;
}
Final result

How to make equal space between boxes in one row via CSS

I have a requirement that there are 4 boxes in one row.
the boxes have fixed width and height
but the width of the row will change by screen size.
the first box should be aligned to the left border of the row
last box aligned to right border.
Also the space between any two boxes should be equal.
Is there a pure CSS way to make that happen? Here is the jsfiddle code.
HTML:
<div class="row">
<div class ="col">
<div class="box"></div>
</div>
<div class ="col">
<div class="box"></div>
</div>
<div class ="col">
<div class="box"></div>
</div>
<div class ="col">
<div class="box"></div>
</div>
</div>
CSS:
.row {
display: table;
border: 1px solid green;
width: 400px; /* it changes by screen size actually */
padding: 5px;
}
.row:before, .row:after {
content: "";
}
.row:after {
clear: both;
}
.col {
float: left;
width: 25%;
}
.box {
border: 1px solid #DDD;
width: 80px;
height: 80px;
margin: 0 auto;
}
.col:first-child .box {
margin-left: 0;
}
.col:last-child .box {
margin-right: 0;
}
Use text-align:justify on the container, this way it will work no matter how many elements you have in your div (you don't have to work out % widths for each list item
Updated CSS
.row {
text-align: justify;
min-width: 412px;
border: 1px solid green;
width: 80%; /* it changes by screen size actually */
height: 90px;
padding: 5px;
}
.row:after {
content: '';
display: inline-block;
width: 100%;
}
.col {
display: inline-block;
}
.box {
border: 1px solid #DDD;
width: 80px;
height: 80px;
margin: 0 auto;
}
FIDDLE
You can make use of css3 flex boxes which is supported in modern browsers.
.row {
display: flex;
justify-content: space-between;
border: 1px solid green;
}
.box {
border: 1px solid #DDD;
width: 80px;
height: 80px;
}
<div class="row">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
jsfiddle demo
more about flex boxes # css tricks
Why not use flexbox ?
Demo
css
.flex-container {
padding: 5px;
margin: 0;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
justify-content: space-between; /* this make the end divs at sides and equal space between other divs */
}
.flex-item {
background: tomato;
padding: 5px;
width: 200px;
height: 150px;
margin-top: 10px;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
}
html
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
</div>
Read here for more detail on flexbox
you simply have to remove the padding attribute from the following
.row {
display: table;
border: 1px solid green;
width: 400px; /* it changes by screen size actually */
/*padding: 5px;*/
}
here is the demo.
Let me know if this was helpful or if you have anymore queries.

Resources