I have a 2x2 grid next to one big image that I need to line up. (here's a codepen) I used a combination of Bootstrap 3.3.7 and Flexbox and it looks great in everything BUT IE (go figure). I'm just beating my head against a wall trying to fix this.
I've got everything for the 2x2 grid positioned in a row like so.
<div class="row || flex-row">
<div class="col-xs-12 || col-md-6 || core-values-left">
<div>
<img class="img-responsive" src="http://impact-web.azurewebsites.net/wp-content/uploads/2017/02/corevaluesmain-1.jpg">
</div>
</div>
<div class="col-xs-12 || col-md-6 || core-values-right">
<div class="row">
<div class="col-xs-12 || col-md-6 || core-values-section">
<div class="core-values-img">
<img class="img-responsive" src="http://impact-web.azurewebsites.net/wp-content/uploads/2017/02/coretopleft.jpg">
<h4 class="core-values-heading">We Scout</h4>
<div class="core-hover">
<h5>We are a talent scout and agent for the grocery industry</h5>
<div>
Learn more
</div>
</div>
</div>
</div>
<div class="col-xs-12 || col-md-6 || core-values-section">
<div class="core-values-img">
<img class="img-responsive" src="http://impact-web.azurewebsites.net/wp-content/uploads/2017/02/coretopright-1.jpg">
<h4 class="core-values-heading">We Discover</h4>
<div class="core-hover">
<h5>We seek out new CPG opportunities and innovations</h5>
Learn More
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 || col-md-6 || core-values-section">
<div class="core-values-img">
<img class="img-responsive" src="http://impact-web.azurewebsites.net/wp-content/uploads/2017/02/corebottomleft.jpg">
<h4 class="core-values-heading">We Grow</h4>
<div class="core-hover">
<h5>We expand your brand’s horizons and elevate your success</h5>
Learn more
</div>
</div>
</div>
<div class="col-xs-12 || col-md-6 || core-values-section">
<div class="core-values-img">
<img class="img-responsive" src="http://impact-web.azurewebsites.net/wp-content/uploads/2017/02/corebottomright.jpg">
<h4 class="core-values-heading">We Champion</h4>
<div class="core-hover">
<h5>We value our client relationships and always go the extra mile</h5>
Learn more
</div>
</div>
</div>
</div>
</div>
</div>
Then I applied this css to the row and columns to line it up with flex. Works like a charm....except in IE
.flex-row {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap; }
.flex-row > [class*='col-'] {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column; }
Things I've tried:
Adding min-height to the columns
Wrapping the rows in another div to
make them non-flex containers
Explicitly setting flex: 1 1 0% on the
rows and the columns
Rubbing a magic lamp and summoning a genie to
fix my problem
Does anyone has a clue what might be happening??? I hate IE so much.
First you have IE, which does everything it can to prevent coding from being fun or easy...
Then you have the many flexbox-related bugs in IE10 and IE11...
Add to that the multiple bugs related to flex-direction: column...
Then finally throw images into flex items (an entirely different set of challenges and inconsistencies)...
And you're pretty much guaranteed to find trouble.
My suggestion would be to switch the flex container from column to row. This should make your layout easier to handle by IE browsers.
Try these adjustments:
.flex-row > [class*='col-'] {
display: flex;
/* flex-direction: column; */
flex-direction: row; /* new */
flex-wrap: wrap; /* new */
align-content: space-between; /* new */
}
.core-values-left > div {
flex: 1; /* new */
}
revised codepen
Related
My scenario
I have these two flex containers (the difficulty options and the max-score options):
I want the 'easy', 'medium' and 'hard' button to share the same width, but also to fit they're content (in this case, because 'medium' is the longest, they should all equal its width).
I want the same behavior with the bottom buttons (but for them to have a smaller width since they need to accommodate for smaller content).
Right now the flex containers for both of them is set to:
display: flex;
flex-direction: wrap;
flex-wrap: wrap;
And the flex children are each set to their default flex values, with a set height and an auto width.
Approaches I've tried
First approach - flex-basis and flex-grow
Setting the children to flex-basis: 0 and flex-grow: 1, as I've seen in past questions, but then my wrapped child fills the entire width, and the top buttons aren't the same width:
Second approach - -- hardcoded flex-basis
Setting all children to flex-basis: 90px (90px to accommodate for the biggest button, 'medium') which does make them all the same width, but then the width is fixed and doesn't adjust to only fit the content (specifically this is desired so the score buttons can fit in two rows instead of three).
Third approach - max-width
The closest I've got to is to set the children to:
```
max-width: 90px;
flex-basis: 0;
flex-grow: 1;
```
Which makes them behave as wanted:
But when the screen width shrinks, the buttons start to differ in width (the obvious one is the '200' button bigger than the other scores, but also 'medium' is bigger than 'easy' and 'hard'):
My code:
.flex-col,
.flex-row {
display: flex;
flex-wrap: wrap;
gap: 4px;
justify-content: center;
}
.flex-col {
flex-direction: column;
}
.flex-row {
flex-direction: row;
}
.button {
border-style: solid;
padding: 4px;
}
.parent {
height: auto;
width: auto;
}
<div class="parent flex-col">
<div class="flex-col">
<div class="flex-row">
DIFFICULTY
</div>
<div class="flex-row">
<div class="button">EASY</div>
<div class="button">MEDIUM</div>
<div class="button">HARD</div>
</div>
</div>
<div class="flex-col">
<div class="flex-row">
MAX SCORE
</div>
<div class="flex-row">
<div class="button">50</div>
<div class="button">75</div>
<div class="button">100</div>
<div class="button">150</div>
<div class="button">200</div>
</div>
</div>
</div>
Help appreciated, thanks!
The closest way to do this with CSS only, is to use a grid instead of a flexbox for reasons well explained here.
The only way to truly do what you are asking (make all children have the same width as the widest child), is with JavaScript. Loop through the elements to find the biggest width and set them all to have the found width.
Here is a snippet demonstrating both concepts:
const equalizers = document.querySelectorAll('.equalize')
let r = 0
equalizers.forEach(equalizer => {
const widths = []
for (const btn of equalizer.children) {
const w = btn.getBoundingClientRect().width
// Math.ceil() is optional to avoid long floats
widths.push(Math.ceil(w)) // 82
// widths.push(w) // 81.31945037841797
}
const biggest = Math.max(...widths)
console.log(`biggest width found in row[${r++}]:`, biggest)
for (const btn of equalizer.children) {
btn.style.width = `${biggest}px`
}
})
.flex-col,
.flex-row {
display: flex;
flex-wrap: wrap;
gap: 4px;
justify-content: center;
}
.flex-col {
flex-direction: column;
}
.flex-row {
flex-direction: row;
}
.button {
border-style: solid;
padding: 4px;
}
.parent {
height: auto;
width: auto;
}
.grid-row {
display: grid;
gap: 4px;
}
.grid-row>* {
text-align: center;
}
#media (min-width: 25em) {
.grid-row {
grid-auto-flow: column;
grid-auto-columns: 1fr;
}
}
.flex-row>* {
text-align: center;
}
<hr>
<strong>JavaScript</strong> (only ever as wide as the widest sibling, with wrapping)
<hr>
<div class="parent flex-col">
<div class="flex-col">
<div class="flex-row">
DIFFICULTY
</div>
<div class="flex-row equalize">
<div class="button">EASY</div>
<div class="button">MEDIUM</div>
<div class="button">HARD</div>
</div>
</div>
<div class="flex-col">
<div class="flex-row">
MAX SCORE
</div>
<div class="flex-row equalize">
<div class="button">50</div>
<div class="button">75</div>
<div class="button">100</div>
<div class="button">150</div>
<div class="button">200</div>
</div>
</div>
</div>
<hr>
<strong>Grid</strong> (always as wide as posible and no wrapping, either all stacked, or all inline with breakpoint)
<hr>
<div class="parent flex-col">
<div class="flex-col">
<div class="flex-row">
DIFFICULTY
</div>
<div class="grid-row">
<div class="button">EASY</div>
<div class="button">MEDIUM</div>
<div class="button">HARD</div>
</div>
</div>
<div class="flex-col">
<div class="flex-row">
MAX SCORE
</div>
<div class="grid-row">
<div class="button">50</div>
<div class="button">75</div>
<div class="button">100</div>
<div class="button">150</div>
<div class="button">200</div>
</div>
</div>
</div>
I am trying to get the price under the annual plan.
.paymentsection {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
gap: 2rem;
}
<div class="paymentsection">
<img src="/images/icon-music.svg" alt="Music" class="icon-img" />
<div class="plan">Annual Plan</div>
<div class="price">$59.99/year</div>
</div>
Change
final image
The .plan and .price needs to be inside a div and then if display flex is applied to the paymentsection, you get your desired result.
<div class="paymentsection">
<img src="/images/icon-music.svg" alt="Music" class="icon-img" />
<div class="plan-container">
<div class="plan">Annual Plan</div>
<div class="price">$59.99/year</div>
</div>
Change
</div>
.paymentsection {
display: flex;
flex-direction: row;
}
.plan-container{
flex-grow:1;
}
You need different flex boxes for implementation your image. Each flex box should have different direction. first you need to wrap your .plan div and .price div with another div. This help you to separate pricing component:
<div class="paymentsection">
<img src="/images/icon-music.svg" alt="Music" class="icon-img" />
<div class="plan-wrapper">
<div class="plan">Annual Plan</div>
<div class="price">$59.99/year</div>
</div>
</div>
Change
next you need to set flex direction to your new div element. this is your desire style:
.paymentsection {
display: flex;
}
.plan-wrapper{
display: flex;
flex-direction: column; /* default is row */
}
this changes should fix your issue.
To have the pricing aligned below the text, you'd have to nest the div further and specify the styles of the nested div to be oriented vertically, i.e, flex-direction: column.
You could do something like this:
<div class="paymentsection">
<img src="/images/icon-music.svg" alt="Music" class="icon-img" />
<div class="pricing">
<div class="plan">Annual Plan</div>
<div class="price">$59.99/year</div>
</div>
</div>
Change
Styles for pricing class:
.pricing{
display:flex;
flex-direction: column;
}
I am trying to split my webpage into two vertical columns which can be clicked on to take you to the right pages. I've gotten this far.
HTML
<!-- Choices -->
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-xs-12 vertical-center webd">
<h1 class="text-muted text-center">Web Design</h1>
</div>
<div class="col-md-6 col-xs-12 vertical-center circ">
<h1 class="text-muted text-center">Circus</h1>
</div>
</div>
</div>
CSS
.vertical-center {
min-height: 100%;
min-height: 100vh;
display: flex;
align-items: center;
}
.webd {
background-image: url('webd.jpg');
}
.circ {
background-image: url(circ.JPG);
}
My issue is, no matter where I put the text-center class. My <h1>s stay left aligned on the page. Can anybody help?
It is because you have added display flex to the parent container. This means the children are not full width anymore.
If you add the following style, it will fix your error:
.vertical-center > .text-center
{
flex-grow: 1;
}
Example bootply
If you don't want to grow the children, you can just add the following to your vertical center: justify-content: center;
Example bootply 2
In IE10, when I wrap the children in a div and a href container, the children are displayed in a column instead of a row. All other browsers work. I have no idea what to do about this. Can someone shine some light on this?
HTML:
<div id="container">
<a class="item_container1">
<div class="item_container2">
<img src="http://placehold.it/250x200">
</div>
</a>
<a class="item_container1">
<div class="item_container2">
<img src="http://placehold.it/250x200">
</div>
</a>
<a class="item_container1">
<div class="item_container2">
<img src="http://placehold.it/250x200">
</div>
</a>
</div>
CSS:
#container {
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-ms-flex-flow: row wrap;
-webkit-flex-flow: row wrap;
flex-flow: row wrap;
}
Codepen: http://codepen.io/LeMiguel72/pen/wWGEmq
Figured it out. The a elements need to be displayed as block.
a {
display: block;
}
I am trying to create a masonry layout using flexboxes but I can't find a way to fill the gaps.
I attached a code pen example below
http://codepen.io/anon/pen/KpgMKX?editors=110
.wrapper {
margin: auto;
width: 1024px;
height: 100%;
display: flex;
flex-flow: row wrap;
align-items: stretch;
align-content: stretch;
}
Update:
Please note that flex-direction: column will not work for me as it breaks the order of the content.
Here's how I would do it:
http://codepen.io/anon/pen/gpwwpX
I made two more wrappers, one that is for the two boxes on the left and one that surrounds the two wrappers. Like this:
<div class="big-wrapper">
<div class="wrapper2">
<div class="box oneTwo"></div>
<div class="box oneOne"></div>
</div>
<div class="wrapper">
<div class="box oneOne"></div>
<div class="box oneOne"></div>
<div class="box twoOne"></div>
<div class="box oneTwo"></div>
<div class="box threes"></div>
</div>
</div>
Then in the CSS I just added the two new wrappers adjusted their widths a bit, but you can play with that of course.