How to make flex-basis work in IE11 - css

My website is completely broken in IE11. The problem comes from flex: 1 1 0%;, which I use everywhere thanks to autoprefixer and postcss-flexbugs-fixes.
The site does work on IE when I change it to flex: 1 1 auto;, but then some behaviors change (e.g. one flexbox with two flex: 1 1 auto; children which do not take exactly the same space). Therefore this solution breaks my designs on other browsers (while making it a lot nicer - not broken - on IE11).
How do people manage to make their sites built with Flexbox work on IE11?
Edit: here is a pen which highlights the problem I am facing: https://codepen.io/Zephir77167/pen/GMjBrd (try it on Chrome and IE11).
Edit2: here is the code:
HTML:
<div id="a" class="flex">
<div id="b" class="item flex-1">
Hey
</div>
<div id="c" class="item flex-0">
Ho
</div>
<div id="d" class="item flex-1">
Heyheyheyheyho
</div>
</div>
<br />
<div id="a" class="flex">
<div id="b" class="item flex-1-variation">
Hey
</div>
<div id="c" class="item flex-0">
Ho
</div>
<div id="d" class="item flex-1-variation">
Heyheyheyheyho
</div>
</div>
CSS:
* {
box-sizing: border-box;
}
#a {
background-color: pink;
height: 300px;
width: 100px;
}
#b {
background-color: green;
height: 50px;
}
#c {
background-color: blue;
height: 100px;
}
#d {
background-color: yellow;
height: 150px;
}
.flex {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
}
.item.flex-0 {
flex: none;
}
.item.flex-1 {
flex: 1 1 0%;
}
.item.flex-1-variation {
flex: 1 1 auto;
}

When it comes to IE11, you could target it explicit using this CSS rule:
_:-ms-fullscreen, :root .IE11-only-class {
/* IE11 specific properties */
}
Stack snippet
* {
box-sizing: border-box;
}
#a {
background-color: pink;
height: 300px;
width: 100px;
}
#b {
background-color: green;
height: 50px;
}
#c {
background-color: blue;
height: 100px;
}
#d {
background-color: yellow;
height: 150px;
}
.flex {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
}
.item.flex-0 {
flex: none;
}
.item.flex-1 {
flex: 1 1 0%;
}
_:-ms-fullscreen, :root .IE-FlexAuto {
flex-basis: auto;
}
<div id="a" class="flex">
<div id="b" class="item flex-1 IE-FlexAuto">
Hey
</div>
<div id="c" class="item flex-0">
Ho
</div>
<div id="d" class="item flex-1 IE-FlexAuto">
Heyheyheyheyho
</div>
</div>
Here is a post with an answer of mine, which talks some more about this, and also provide some script solutions which might be helpful
Instead of using prefixes I want to ask site visitors to upgrade their browser

I had a massive headache over this, rather than do a hack, set your flex-basis to auto, then if you have a container size, set the with to the same size, ie:
#include breakpoint(m){
flex: 0 48%;
flex-basis: auto;
width: 48%;
}

Related

Flexbox how to create this layout

I am using Elementor Pro and was looking to see if it is possible to create this layout with Flexbox:
I was hoping to create a gallery with this layout, but not sure if this is possible using Flexbox?
Here is the site link: https://davidandgeorge.co.uk/
Thanks for any tips.
Cheers
flex:
body {
margin: 0;
}
.wrap, .flex-col {
display: flex;
}
.flex-col {
flex-direction: column;
}
.wrap {
padding: .25rem;
flex-grow: 1;
}
.basis-1\/3 {
flex: 0 0 33.333333%;
}
.aspect-4\/5 {
aspect-ratio: 4/5;
}
.wrap img {
object-fit: cover;
width: 100%;
height: 100%;
}
<div class="wrap">
<div class="wrap aspect-4/5">
<img src="https://images.squarespace-cdn.com/content/v1/5938092adb29d602a8eb55d8/1653045352509-PWI7Q226NN0ZD85GVHR8/david-and-george-squarespace-website-designer-london-edinburgh-uk-portfolio-makers-weaver-woven-textiles-majeda-clarke-min.jpg?format=2500w" />
</div>
<div class="flex-col basis-1/3">
<div class="wrap">
<img src="https://images.squarespace-cdn.com/content/v1/5938092adb29d602a8eb55d8/1648550640739-ABYK0CIPHJIZ9V1LQ872/squarespace-website-design-food-and-drink-london-dry-gin-spirits-uk-no-3-gin-thumbnail-min.jpg?format=1000w" />
</div>
<div class="wrap">
<img src="https://images.squarespace-cdn.com/content/v1/5938092adb29d602a8eb55d8/1648551399057-U3TMJ3YJMHZRK1W8D3LL/david-and-george-squarespace-website-designer-london-edinburgh-uk-portfolio-consultants-media-and-content-creators-professional-business-bespoke-pr-campaigns-luxury-travel-wellness-lifestyle-nadia-walford-pr-min.jpg?format=1000w" />
</div>
</div>
</div>
grid:
body {
margin: 0;
}
.grid-1 {
display: grid;
grid-template-columns: 2fr 1fr;
grid-gap: .5rem;
padding: .5rem;
}
.grid-1 div:first-child {
grid-area: 1/1/3/2;
aspect-ratio: .8;
}
.grid-1 div img {
object-fit: cover;
width: 100%;
height: 100%;
display: block;
}
<div class="grid-1">
<div>
<img src="https://images.squarespace-cdn.com/content/v1/5938092adb29d602a8eb55d8/1653045352509-PWI7Q226NN0ZD85GVHR8/david-and-george-squarespace-website-designer-london-edinburgh-uk-portfolio-makers-weaver-woven-textiles-majeda-clarke-min.jpg?format=2500w" />
</div>
<div>
<img src="https://images.squarespace-cdn.com/content/v1/5938092adb29d602a8eb55d8/1648550640739-ABYK0CIPHJIZ9V1LQ872/squarespace-website-design-food-and-drink-london-dry-gin-spirits-uk-no-3-gin-thumbnail-min.jpg?format=1000w" />
</div>
<div>
<img src="https://images.squarespace-cdn.com/content/v1/5938092adb29d602a8eb55d8/1648551399057-U3TMJ3YJMHZRK1W8D3LL/david-and-george-squarespace-website-designer-london-edinburgh-uk-portfolio-consultants-media-and-content-creators-professional-business-bespoke-pr-campaigns-luxury-travel-wellness-lifestyle-nadia-walford-pr-min.jpg?format=1000w" />
</div>
</div>
Grid has slightly cleaner syntax, for both CSS and HTML so... why flex?
It is. I would create a wrapper div for all of the images, then another wrapper div for the two smaller images aside.
Then, just use display: flex for the big wrapper, and display: flex with flex-direction: column for the smaller one.

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%;
}

flexbox makes content disappear

I'm playing around with flexbox to get the hang of it but I am running into some issues. My goal is to have the window separated by four background colors where the first is just a header row and then the rest of the page is filled by 3 columns each a different background color. But for some reason if I write display: flex it doesn't show anything. Can someone explain to me how to get this desired effect?
.container {
width: 100%;
height: 100%;
}
.header {
height: 150px;
background-color: red;
}
.col-container {
widows: auto;
height: auto;
display: flex;
flex-direction: row;
}
.col {
flex: 1;
}
.col-container:nth-child(1) {
background: green;
}
.col-container:nth-child(2) {
background: blue;
}
.col-container:nth-child(3) {
background: yellow;
}
<body>
<div class="container">
<div class="header"></div>
<div class="col-container">
<div class="col"></div>
<div class="col"></div>
<div class="col"></div>
</div>
</div>
</body>
Here is a working example:
.container {
width: 100%;
height: 100%;
}
.header {
height: 150px;
background-color: red;
}
.col-container {
widows: auto;
height: auto;
display: flex;
flex-direction: row;
}
.col-1 {
flex: 1 1 33.333%;
background-color: green;
}
.col-2 {
flex: 1 1 33.333%;
background-color: blue;
}
.col-3 {
flex: 1 1 33.333%;
background-color: yellow;
}
<body>
<div class="container">
<div class="header"></div>
<div class="col-container">
<div class="col-1">ts</div>
<div class="col-2">dtd</div>
<div class="col-3">dt</div>
</div>
</div>
</body>
Here's what you needed to fix:
Set flex-direction to row. You most likely want the columns next to each other.
Add the classes to your HTML for the col-1, col-2 and col-3.
You need content in those col classes, or you won't see anything anyway.
I set a flex-basis (the third parameter in the flex shorthand) to 33.333%. You don't necessarily need this, but it's nice to see how much space a particular element will fill or change it.
EDIT For the comments:
body {
margin: 0;
padding: 0;
}
.container {
width: 100%;
height: 100%;
}
.header {
height: 150px;
background-color: red;
}
.col-container {
widows: auto;
height: auto;
display: flex;
flex-direction: row;
height: calc(100vh - 150px);
}
.col-1 {
flex: 1 1 33.333%;
background-color: green;
}
.col-2 {
flex: 1 1 33.3333%;
background-color: blue;
}
.col-3 {
flex: 1 1 33.3333%;
background-color: yellow;
}
<body>
<div class="container">
<div class="header"></div>
<div class="col-container">
<div class="col-1"></div>
<div class="col-2"></div>
<div class="col-3"></div>
</div>
</div>
</body>
Basically, you need to give the col-container a height. To achieve this, I used vh units in the calc statement. It subtracts your header height from the viewport height and gives the remainder. This also removes the necessity for filler content.

Add space before and after first and last grid items

My question is identical to this question, but the given solution does not work.
Here is a codepen of what I'm working with.
I've tried two different approaches, both of which are almost correct but not quite:
1. Applying ::before and ::after psuedo classes to first and last grid items
Unfortunately when I add margin-left and margin-right properties to the first and last grid item respectively, it adds the space to the grid items as if it were padding space and not margin space, otherwise this works fine.
2. Applying ::before and ::after psuedo classes to grid container
It will not allow me to manipulate the width of ::before. For some reason the width property of ::before does not take effect. Notably, it seems as if the value of its width is the same width value as any given grid item.
I noticed another peculiarity, which is ultimately irrelevant, with this approach too. If I apply a width to ::after, grid-gap also gets applied as if it is inserting an invisible grid item.
:root {
--gap: 25px;
}
body {
width: 100vw;
overflow-x: hidden;
margin: 0
}
#c {
width: 100%;
height: 50px;
overflow-x: auto;
display: grid;
grid-gap: 20px;
grid-auto-flow: column;
grid-auto-columns: calc(calc(100% - calc(var(--gap) * 2)) / 1.5);
border: solid red 1px;
}
/* second approach */
#c::before {
content: '';
width: var(--gap);
}
#c::after {
content: '';
width: 1px; /* works out to about 25px or var(--gap) */
}
.i {
width: 100%;
height: 25px;
}
/* first approach */
/*
.i:first-child::before {
content: '';
margin-left: var(--gap);
}
.i:last-child::after {
content: '';
margin-right: var(--gap);
}
*/
.i:nth-child(odd) {
background: skyblue;
}
.i:nth-child(even) {
background: pink;
}
<div id='c'>
<div class='i'>1</div>
<div class='i'>2</div>
<div class='i'>3</div>
<div class='i'>4</div>
<div class='i'>5</div>
<div class='i'>6</div>
<div class='i'>7</div>
<div class='i'>8</div>
<div class='i'>9</div>
<div class='i'>10</div>
<div class='i'>11</div>
<div class='i'>12</div>
<div class='i'>13</div>
<div class='i'>14</div>
<div class='i'>15</div>
<div class='i'>16</div>
<div class='i'>17</div>
<div class='i'>18</div>
<div class='i'>19</div>
<div class='i'>20</div>
<div class='i'>21</div>
<div class='i'>22</div>
<div class='i'>23</div>
<div class='i'>24</div>
</div>
Does anybody have any idea why this stuff is happening?
How can I change the width of ::before?
One idea to change the width of before is to define a column template like below that will force the width of the first element only then the other will follow the grid-auto-columns. Basically we define an explicit grid with 1 column then the browser will add more column as needed to create the implicit grid:
:root {
--gap: 25px;
}
body {
width: 100vw;
overflow-x: hidden;
margin: 0
}
#c {
width: 100%;
height: 50px;
overflow-x: auto;
display: grid;
grid-gap: 20px;
grid-template-columns:1px;
grid-auto-flow: column;
grid-auto-columns: calc(calc(100% - calc(var(--gap) * 2)) / 1.5);
border: solid red 1px;
}
/* second approach */
#c::before {
content: '';
}
#c::after {
content: '';
width: 1px; /* works out to about 25px or var(--gap) */
}
.i {
/*width: 100%; not needed*/
height: 25px;
/*display: inline-block; not needed*/
}
.i:nth-child(odd) {
background: skyblue;
}
.i:nth-child(even) {
background: pink;
}
<div id='c'>
<div class='i'>1</div>
<div class='i'>2</div>
<div class='i'>3</div>
<div class='i'>4</div>
<div class='i'>5</div>
<div class='i'>6</div>
<div class='i'>7</div>
<div class='i'>8</div>
<div class='i'>9</div>
<div class='i'>10</div>
<div class='i'>11</div>
<div class='i'>12</div>
<div class='i'>13</div>
<div class='i'>14</div>
<div class='i'>15</div>
<div class='i'>16</div>
<div class='i'>17</div>
<div class='i'>18</div>
<div class='i'>19</div>
<div class='i'>20</div>
<div class='i'>21</div>
<div class='i'>22</div>
<div class='i'>23</div>
<div class='i'>24</div>
</div>
This is another one of those instances where flexbox may provide a simpler, easier and more effective solution that grid.
:root {
--gap: 25px;
}
#c {
display: flex;
overflow-x: auto;
height: 50px;
border: solid red 1px;
}
.i {
height: 25px;
flex: 0 0 calc(calc(100% - calc(var(--gap) * 2)) / 1.5); /* fg, fs, fb */
}
#c::before {
content: '';
flex: 0 0 var(--gap);
}
.i {
margin-right: 20px;
}
#c::after {
content: '';
flex: 0 0 calc(var(--gap) - 20px); /* gap less margin */
}
.i:nth-child(odd) { background: skyblue; }
.i:nth-child(even) { background: pink; }
body { margin: 0; }
* { box-sizing: border-box; }
<div id='c'>
<div class='i'>1</div>
<div class='i'>2</div>
<div class='i'>3</div>
<div class='i'>4</div>
<div class='i'>5</div>
<div class='i'>6</div>
<div class='i'>7</div>
<div class='i'>8</div>
<div class='i'>9</div>
<div class='i'>10</div>
<div class='i'>11</div>
<div class='i'>12</div>
<div class='i'>13</div>
<div class='i'>14</div>
<div class='i'>15</div>
<div class='i'>16</div>
<div class='i'>17</div>
<div class='i'>18</div>
<div class='i'>19</div>
<div class='i'>20</div>
<div class='i'>21</div>
<div class='i'>22</div>
<div class='i'>23</div>
<div class='i'>24</div>
</div>
You may also want to consider a transparent border for start- and end-side spacing. Last margin / padding collapsing in flexbox / grid layout

Making an input and two buttons aligned using SCSS

I want my two buttons, that are actually <a> tags, stick with my input, and be the same size as input. Image perfectly describes what I want to achieve.
Note that I am just starting to learn SASS and CSS. I have tried with this but no luck
NumberInput.js
<div
className="NumberInput"
data-key={dataKey}>
<div className="numberInputField">
<input
data-key={dataKey}
type="text"
name="number"
value={getValue(datakey)}
onChange={onChange(datakey)}/>
</div>
<div className="buttonsField">
<div className="row">
<ValueChangeButton/>
</div>
<div className="row">
<ValueChangeButton/>
</div>
</div>
</div>
NumberInput.scss
$inputMaxWidth: 450px;
$maxHeight: 80px;
$btnFieldMaxWidth: 150px;
.NumberInput{
max-width: $inputMaxWidth;
max-height: $maxHeight;
.numberInputField{
display: inline-block;
text-align: center;
max-width: inherit;
max-height: inherit;
}
.buttonsField{
display: inline-block;
max-width: $btnFieldMaxWidth;
max-height: $maxHeight;
.button{
width: auto;
height: auto;
}
}
}
The result I get is, buttons are contained in their respective rows, but are not the same size as input, and they are flying all around the page. Also, if I change the className of my input, and set the className of its <div> to "numberInputField", it doesn't change its width and height.
Flexbox is perfect for this:
body {
margin: 1em;
}
.NumberInput {
display: flex;
max-width:450px;
margin:auto;
}
.numberInputField {
flex: 3; /* say 3/4 of width */
display: flex;
flex-direction: column;
}
input {
padding: 1em 4em;
flex: 1;
}
.buttonsField {
flex: 1; /* say 1/4 of width */
display: flex;
flex-direction: column;
}
.row {
flex: 1; /* share width equally */
}
a {
width: 100%;
display: block;
background: rebeccapurple;
text-align:center;
text-decoration: none;
font-size: 1.5em;
color: white;
border:1px solid grey;
}
<div class="NumberInput">
<div class="numberInputField">
<input type="submit" />
</div>
<div class="buttonsField">
<div class="row">
↑
</div>
<div class="row">
↓
</div>
</div>
</div>

Resources