flexbox item 100% of remaining width - css

I want to achieve the following scenario with flexbox
the green element is a text element and the width is flexible. The blue elements should have 100% of the remaining width beside the green element.
My current solution looks like this:
<div class="container">
<span class="title">title</span>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
</div>
and the css:
.container {
display: flex;
align-items: center;
flex-wrap: wrap;
background-color: #EAEBEF;
.title {
padding: 20px;
background-color: #48CFAE;
}
.fullwidth {
background-color: #87BDFF;
flex: 0 0 100%;
height: 60px;
margin: 10px 0;
}
}
But it looks currently like this
here is a codepen example

Without changing the HTML this can be managed with CSS-Grid as an alternative to flexbox.
.container {
display: grid;
grid-template-columns: max-content 1fr;
grid-gap: 1em;
background-color: #EAEBEF;
margin-bottom: 1em;
}
.title {
padding: 10px;
grid-row: 2;
background-color: #48CFAE;
}
.fullwidth {
grid-column: 2;
background-color: #87BDFF;
height: 40px;
}
<div class="container">
<div class="title">title</div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
</div>
<div class="container">
<div class="title">Longer title</div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
</div>

Try this HTML and CSS markup. Basically You need to keep the left side in one div and the right side elements in another div.
.container {
display: flex;
align-items: center;
flex-wrap: nowrap;
background-color: #eaebef;
}
.container .title {
padding: 20px;
background-color: #48cfae;
}
.container .div1 {
width: 20%;
}
.container .div2 {
width: 80%;
}
.container .fullwidth {
background-color: #87bdff;
height: 60px;
margin: 10px 0;
}
<div class="container">
<div class="div1">
<span class="title">title</span>
</div>
<div class="div2">
<div class="fullwidth"></div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
</div>
</div>

See code below:
You have to warp fullwidth in div and set width to this div
also set width and margin to title
.container {
display: flex;
align-items: center;
flex-wrap: wrap;
background-color: #EAEBEF;
}
.title {
width: 20%;
padding: 20px;
background-color: #48CFAE;
margin-left: 15px;
}
.fullwidth {
background-color: #87BDFF;
flex: 0 0 100%;
height: 60px;
margin: 10px 0;
}
.a{
margin: 50px;
width: 50%;
}
<div class="container">
<span class="title">title</span>
<div class="a">
<div class="fullwidth"></div>
<div class="fullwidth"></div>
<div class="fullwidth"></div>
</div>
</div>

If you want to achive this without change your html but only your less, try this:
.container {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
background-color: #EAEBEF;
justify-content: flex-end;
.title {
padding: 20px;
background-color: #48CFAE;
margin-right: 20px;
flex-grow: 1
}
.fullwidth {
background-color: #87BDFF;
height: 60px;
margin: 10px 0;
width: 80%;
}
}
your codepen edited

Related

How to remove the empty space between elements?

I have made a calculator using one parent div and plenty of child divs, the children are in html. After that I styled it using flex-box and it is almost done; nevertheless there is an empty space between first div (.result) and the rest of the divs (.btn).
I want to remove that empty space which is shown in picture below:
I tried to use flex-box method to arrange these div elements like blocks.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
h1 {
margin: 0 auto 0 auto;
background-color: gray;
text-align: center;
margin-bottom: 5vh;
}
.kalkulator {
display: flex;
flex-wrap: wrap;
height: 50vh;
width: 30vw;
margin: 0 auto 0 auto;
}
.kalkulator .result {
flex-basis: 100%;
height: 10vh;
background-color: #333;
}
.kalkulator div {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
flex-basis: 33%;
background-color: #666;
border: 1px solid black;
}
.btn:nth-last-child(2),
.btn:nth-last-child(1) {
flex-basis: 50%;
}
<h1>kalkulator</h1>
<div class="kalkulator">
<div class="result">wynik</div>
<div class="btn">1</div>
<div class="btn">2</div>
<div class="btn">3</div>
<div class="btn">4</div>
<div class="btn">5</div>
<div class="btn">6</div>
<div class="btn">7</div>
<div class="btn">8</div>
<div class="btn">9</div>
<div class="btn">+</div>
<div class="btn">0</div>
<div class="btn">-</div>
<div class="btn">/</div>
<div class="btn">.</div>
<div class="btn">*</div>
<div class="btn">C</div>
<div class="btn">=</div>
</div>
Apply align-content: flex-start to the flex container.
The default setting is align-content: stretch, which will spread the items across the container. With flex-start, they'll be packed together at the top.
Your code:
.kalkulator {
display: flex;
flex-wrap: wrap;
height: 50vh;
width: 30vw;
margin: 0 auto 0 auto;
border: 2px dashed red;
background-color: yellow;
}
.kalkulator .result {
flex-basis: 100%;
height: 10vh;
background-color: #333;
}
.kalkulator div {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
flex-basis: 33%;
background-color: #666;
border: 1px solid black;
}
.btn:nth-last-child(2),
.btn:nth-last-child(1) {
flex-basis: 50%;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
h1 {
margin: 0 auto 0 auto;
background-color: gray;
text-align: center;
margin-bottom: 5vh;
}
<h1>kalkulator</h1>
<div class="kalkulator">
<div class="result">wynik</div>
<div class="btn">1</div>
<div class="btn">2</div>
<div class="btn">3</div>
<div class="btn">4</div>
<div class="btn">5</div>
<div class="btn">6</div>
<div class="btn">7</div>
<div class="btn">8</div>
<div class="btn">9</div>
<div class="btn">+</div>
<div class="btn">0</div>
<div class="btn">-</div>
<div class="btn">/</div>
<div class="btn">.</div>
<div class="btn">*</div>
<div class="btn">C</div>
<div class="btn">=</div>
</div>
Modified code:
.kalkulator {
display: flex;
flex-wrap: wrap;
height: 50vh;
width: 30vw;
margin: 0 auto 0 auto;
border: 2px dashed red;
background-color: yellow;
align-content: flex-start;
}
.kalkulator .result {
flex-basis: 100%;
height: 10vh;
background-color: #333;
}
.kalkulator div {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
flex-basis: 33%;
background-color: #666;
border: 1px solid black;
}
.btn:nth-last-child(2),
.btn:nth-last-child(1) {
flex-basis: 50%;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
h1 {
margin: 0 auto 0 auto;
background-color: gray;
text-align: center;
margin-bottom: 5vh;
}
<h1>kalkulator</h1>
<div class="kalkulator">
<div class="result">wynik</div>
<div class="btn">1</div>
<div class="btn">2</div>
<div class="btn">3</div>
<div class="btn">4</div>
<div class="btn">5</div>
<div class="btn">6</div>
<div class="btn">7</div>
<div class="btn">8</div>
<div class="btn">9</div>
<div class="btn">+</div>
<div class="btn">0</div>
<div class="btn">-</div>
<div class="btn">/</div>
<div class="btn">.</div>
<div class="btn">*</div>
<div class="btn">C</div>
<div class="btn">=</div>
</div>
It seems too much* for one flexbox. Create the layout with two nested ones: one for the vertical partition of the calculator to the result and the buttons, and another one for the fluid positioning of the buttons within the buttons div:
<div class="kalkulator">
<div class="result">wynik</div>
<div class="buttons">[...]</div>
</div>
.kalkulator {
display: flex;
flex-direction: column;
}
.result {
flex-basis: 10vh;
}
.buttons {
flex-grow: 1; /* Fill the rest */
display: flex;
flex-wrap: wrap;
}
.btn {
flex-grow: 1;
flex-basis: 33%;
justify-content: center;
align-items: center;
display: flex;
}
For placing the buttons under the result box you need a flexbox with a vertical main axis (flex-direction: column). For placing the buttons in a row, a flexbox with a horizontal main axis (the default flex-direction: row).
See the following code, here I removed height: 50vh; property from .kalkulator class:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
h1 {
margin: 0 auto 0 auto;
background-color: gray;
text-align: center;
margin-bottom: 5vh;
}
.kalkulator {
display: flex;
flex-wrap: wrap;
/* height: 50vh; */
width: 30vw;
margin: 0 auto 0 auto;
}
.kalkulator .result {
flex-basis: 100%;
height: 10vh;
background-color: #333;
}
.kalkulator div {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
flex-basis: 33%;
background-color: #666;
border: 1px solid black;
}
.btn:nth-last-child(2),
.btn:nth-last-child(1) {
flex-basis: 50%;
}
<h1>kalkulator</h1>
<div class="kalkulator">
<div class="result">wynik</div>
<div class="btn">1</div>
<div class="btn">2</div>
<div class="btn">3</div>
<div class="btn">4</div>
<div class="btn">5</div>
<div class="btn">6</div>
<div class="btn">7</div>
<div class="btn">8</div>
<div class="btn">9</div>
<div class="btn">+</div>
<div class="btn">0</div>
<div class="btn">-</div>
<div class="btn">/</div>
<div class="btn">.</div>
<div class="btn">*</div>
<div class="btn">C</div>
<div class="btn">=</div>
</div>
Viewport Height (vh): This unit is based on the height of the viewport. A value of 1vh is equal to 1% of the viewport height.
Height of container is 50vh and height of result is 10vh. This leaves 40vh for button panel, or 6.67vh per row. If you want to preserve container height, you can just add height: 6.67vh; to .kalkulator div. This will set button height to fixed value, so there won't be any empty space.

How to make right elements space-between?

It doesn't work when I set justify-content: space-between on rightContainer, I want Apple on the top and Sony on the bottom.
<div className={styles.mainContainer}>
<div className={styles.leftContainer}>
<div className={styles.profilePicture} />
<p className={styles.profileUsername}>Test Name</p>
</div>
<div className={styles.rightContainer}>
<p>Apple</p>
<p>Sony</p>
</div>
</div>
css
.mainContainer {
display: flex;
width: 100%;
background-color: cadetblue;
}
.leftContainer {
width: 100%;
background-color: red;
text-align: left;
}
.rightContainer {
width: 100%;
background-color: blue;
text-align: right;
justify-content: space-between;
}
justify-content: space-evenly is only applicable to a flexbox. You can use a vertical flexbox to apply space-evenly.
.mainContainer {
display: flex;
width: 100%;
background-color: cadetblue;
}
.leftContainer {
width: 100%;
background-color: red;
text-align: left;
}
.rightContainer {
width: 100%;
background-color: blue;
text-align: right;
justify-content: space-evenly;
display: flex; /*Create a flexbox*/
flex-direction: column; /*Vertical flexbox*/
}
<div class="mainContainer">
<div class="leftContainer">
<div class="profilePicture" />
<p class="profileUsername">Test Name</p>
</div>
<div class="rightContainer">
<p>Apple</p>
<p>Sony</p>
</div>
</div>

Div with position absolute is wider than its container

In the following code:
HTML
<div class="cards-wrapper">
<div class="cards_item">
<div class="card">
<div class="card__header">
<div class="=card__title">
<div>title</div>
</div>
</div>
<div class="card__content">
<p class="card__description">Some text</p>
<p class="card__frequency">more text</p>
</div>
<div class="card__footer">
<div class="card__tick"><input type="hidden" value="0"><label class="checkbox-container"><input type="checkbox" class="list-checkbox" value="false"><span class="checkmark"></span></label></div>
<div class="card__see">Even more</div>
</div>
</div>
</div>
</div>
SCSS
.cards-wrapper {
display: flex;
flex-wrap: wrap;
box-sizing: border-box;
outline: 2px solid blue
}
.cards_item {
display: flex;
justify-content: space-between;
box-sizing: border-box;
width: 100%;
padding: 0.5rem;
}
.card {
position: relative;
flex: 0 1 100%;
justify-self: stretch;
box-sizing: border-box;
padding: 0.625rem;
overflow: hidden;
&__header {
display: flex;
flex-direction: row;
align-items: center;
}
&__title {
margin: 0;
}
&__frequency {
margin-bottom: 80px;
}
&__footer {
position: absolute;
bottom: 0.8rem;
display: inline-flex;
align-items: center;
justify-content: space-between;
width: 100%;
outline: 2px solid red;
}
}
Why does .card__footer div with a width of 100% wider than its container?
It fits in the container if you change its width to 90%.
But something seems to be not right here.
Can someone help me please with this?
I see that the container div has padding to it.
can you try this width value on your footer?
width: calc(100% - 1.25rem);
since you are using scss
calc(100% - 2*0.625rem)

How create proper flexbox to make one column inside of content scrollable and another one static?

I want to create a layout where we have a header (responsive, with any height), footer (responsive, with any height), and content that fills the rest of space. Content should have two columns - first(right) that fits the content and second(left) that is very long and should have overflow with y-axis scrolling.
Detailed snipped with HTML and CSS attached.
I have problem with making them work inside of flexible height. I know how to make it work when I have only two columns, but with a responsive footer and header, I have problems.
I also have a code snippet inside of codepen
Thanks in advance for any help :)
html,
body {
height: 100%;
width: 100%;
}
.container {
height: 100%;
display: flex;
flex-direction: column;
}
.column {
background-color: white;
display: flex;
flex-direction: column;
flex-basis: 100%;
flex: 1;
color: black;
border: 5px purple solid;
}
.column-with-overflow {
overflow: auto;
max-height: 100%;
flex-grow: 1;
}
.column-with-overflow-content {
height: 1000px;
background-color: blue;
display: flex;
}
.columns {
display: flex;
flex-direction: row;
background-color: yellow;
width: 100%;
max-height: 100%;
}
.content {
background-color: blue;
flex-grow: 1;
}
.box {
text-align: center;
color: white;
display: flex;
justify-content: center;
}
.header {
background-color: green;
height: 60px; // assume that It's not known - any height
}
.footer {
background-color: red;
height: 60px; // assume that It's not known - any height
}
<div class="container">
<div class="box header">Header</div>
<div class="box content">
<div class="columns">
<div class='column column-with-overflow'>
<div class='column-with-overflow-content'>
box 1
</div>
</div>
<div class='column'>box 2</div>
</div>
</div>
<div class="box footer">Footer</div>
</div>
Set a fixed height to your .box.content div element.
And use min-height in .column-with-overflow-content insted of height
html,
body {
height: 100%;
width: 100%;
}
.container {
height: 100%;
display: flex;
flex-direction: column;
}
.column {
background-color: white;
display: flex;
flex-direction: column;
flex-basis: 100%;
flex: 1;
color: black;
border: 5px purple solid;
}
.column-with-overflow {
overflow: auto;
max-height: 100%;
flex-grow: 1;
}
.column-with-overflow-content {
min-height: 1000px; /* use min-height */
background-color: blue;
display: flex;
}
.columns {
display: flex;
flex-direction: row;
background-color: yellow;
width: 100%;
max-height: 100%;
}
.content {
background-color: blue;
flex-grow: 1;
}
.box.content { height: 100px; } /* set height to columns container */
.box {
text-align: center;
color: white;
display: flex;
justify-content: center;
}
.header {
background-color: green;
height: 60px; // assume that It's not known - any height
}
.footer {
background-color: red;
height: 60px; // assume that It's not known - any height
}
<div class="container">
<div class="box header">Header</div>
<div class="box content">
<div class="columns">
<div class='column column-with-overflow'>
<div class='column-with-overflow-content'>
box 1
</div>
</div>
<div class='column'>box 2</div>
</div>
</div>
<div class="box footer">Footer</div>
</div>

ie 11: flex grow parent issue

I have such code:
https://plnkr.co/edit/ZAEzfAOCO0ZcSq2OR4Lp?p=preview
but this isn't working in ie, until I add height:0 (it's a very bad idea on parent element)
<body>
<div class="container">
<div class="container-item container-item-1"></div>
<div class="container-item container-item-2"></div>
<div class="container-item container-item-3"></div>
</div>
</body>
body, html {
min-height: 100%;
height: 100%;
}
.container {
width: 100%;
min-height: calc(100% - 80px);
margin: 30px;
padding: 20px;
border: 1px solid gray;
border-radius: 16px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
}
.container-item {
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
content: "someText";
border-bottom: 1px solid #cecece;
}
.container-item-1 {
background-color: red;
}
.container-item-2 {
background-color: orange;
}
.container-item-3 {
background-color: green;
}
everything works fine in chrome and ff
(my parents should expand to fit parent)
Important!
I need a flexible solution, my code can have a lot of nested div's (not a constant value) between body and content divs.
for example:
<body>
<div>
<div>
<div class="container">
<div class="container-item container-item-1"></div>
<div class="container-item container-item-2"></div>
<div class="container-item container-item-3"></div>
</div>
</div>
</div>
</body>
or
<body>
<div>
<h3>text</h3>
<div class="container">
<div class="container-item container-item-1"></div>
<div class="container-item container-item-2"></div>
<div class="container-item container-item-3"></div>
</div>
</div>
</body>
If you have an unknown or nested markup before the container, you could add an extra wrapper within it (here inner), to overcome IE's min-height bug.
Fiddle sample 1 -- Fiddle sample 2
Stack snippet sample 1
html, body {
margin: 0;
}
.container {
display: flex;
}
.container .inner {
width: 100%;
min-height: calc(100vh - 100px);
margin: 30px;
padding: 20px;
border: 1px solid gray;
border-radius: 16px;
display: flex;
flex-direction: column;
}
.container-item {
flex-grow: 1;
border: 1px solid #cecece;
}
.container-item-1 {
background-color: red;
}
.container-item-2 {
background-color: orange;
}
.container-item-3 {
background-color: green;
}
<div>
<h3>text</h3>
<div class="container">
<div class="inner">
<div class="container-item container-item-1">
</div>
<div class="container-item container-item-2">
</div>
<div class="container-item container-item-3">
</div>
</div>
</div>
</div>
Stack snippet sample 2
html, body {
margin: 0;
}
.container {
display: flex;
}
.container .inner {
width: 100%;
min-height: calc(100vh - 100px);
margin: 30px;
padding: 20px;
border: 1px solid gray;
border-radius: 16px;
display: flex;
flex-direction: column;
}
.container-item {
flex-grow: 1;
border: 1px solid #cecece;
}
.container-item-1 {
background-color: red;
}
.container-item-2 {
background-color: orange;
}
.container-item-3 {
background-color: green;
}
<div>
<div>
<div class="container">
<div class="inner">
<div class="container-item container-item-1">
</div>
<div class="container-item container-item-2">
</div>
<div class="container-item container-item-3">
</div>
</div>
</div>
</div>
</div>

Resources