Bootstrap 3 container with justify-content: space-between not working properly - css

I am trying to apply flex to bootstrap 3 container and found strange behaviour of child elements Here is the code.
<div class="container">
<div class="child">One</div>
<div class="child">Two</div>
</div>
.container {
display: flex;
justify-content: space-between;
}
(see example on jsfiddle JSFiddle)
I cannot find out what's the problem with the space-between.
Thank you for the help.

Combining Bootstrap 3 with Flexbox is not recommended.
That said, Bootstraps container class also uses both the pseudo elements, hence they will participate in the flex container being flex items, and here one can see them when giving them a small width/height and background color.
And as you can see, the justify-content: space-between; work as it is supposed to.
.container {
display: flex;
justify-content: space-between;
}
.container::before, .container::after {
width: 30px;
height: 30px;
background: red;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="child">One</div>
<div class="child">Two</div>
</div>
One workaround would be a wrapper
.container .flex {
display: flex;
justify-content: space-between;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="flex">
<div class="child">One</div>
<div class="child">Two</div>
</div>
</div>

I think the issue is that you're using a classname from bootstrap .container you're attempting to change the style. Just use a id instead of the classname container.
#main {
display: flex;
justify-content: space-between;
}
<div id="main">
<div class="child">One</div>
<div class="child">Two</div>
</div>

Related

Make flex children width the same and also fit-content

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>

How do I move one item under another in Flexbox? I am trying to get the price under the annual plan

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

How to fix buttons above footer using flex

I am using Materializecss to create React app. I have already applied flex inside my app class. And now I want to apply flex inside main tag where buttons get fixed at bottom of main tag & above the footer.
I have tried {margin-top: auto;} , justify-content: flex-end which didn't help. The buttons always print after content class. I can set the height of the content class, but small devices render view badly and it's not fixing my problem.
JSX code:
<div className="app">
<header> <header>
<main>
<div className="box">
<div className="content"> Long text less than 100 words <div>
<div className="buttons"> <button> Button-1 </button> <button> Button-2 </button>
<div>
<main>
<footer><footer>
<div>
My css
app {
display: flex;
min-height: 100vh;
flex-direction: column;
}
main {
flex: 1 0 auto;
}
I want to stick my button above the footer. My content class has 100 words then the button should stick above the footer not rendered after the content class.
I would appreciate the help.
You haven't applied display:flex etc to the main element. If you do that the margin-top:auto will work.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
::before,
::after {
box-sizing: inherit;
}
.app {
display: flex;
min-height: 100vh;
flex-direction: column;
background: ;
}
main {
flex: 1;
display: flex;
flex-direction: column;
}
.buttons {
margin-top: auto;
}
<div class="app">
<header>header </header>
<main>
<div class="box">box</div>
<div class="content"> Long text less than 100 words </div>
<div class="buttons">
<button> Button-1 </button>
<button> Button-2 </button>
</div>
</main>
<footer>footer</footer>
</div>

Flexbox Style Only Works When Manually Entered in Chrome Developer Tools

I am trying to get an ag-Grid to fill the vertical space in a panel on a page. If I put the style on the .HTML page like this:
<style>
.right_panel > div {
display: flex;
flex: 1;
height: 95%;
flex-direction: column;
}
</style>
... or include it in the Javascript:
$(".right_panel > div").css("display", "flex");
$(".right_panel > div").css("flex-direction", "column");
$(".right_panel > div").css("height", "95%");
$(".right_panel > div").css("flex", "1");
... the styles will correctly show up in the Chrome CSS Debugger:
... but my ag-Grid is crushed down to zero height.
{image of a page with a grid that only has a navbar under which there's a lot of white space}
Disabling them and retyping them into the CSS Debugger verbatim:
... and the grid works fine
{image of a page with a grid that properly fills the page}
Is there something obvious (obviously) that I'm missing? I've read questions like this one to get the grid to fill the available vertical space. Why does this seemingly correct css only work when manually entered in the CSS debugger, and how do I fix it in my code?
Heavily edited HTML for the page:
<html>
<head>...</head>
<body>
<div id="main-view" ui-view="" class="ng-scope">
<div class="vbox ng-scope">
<div class="vbox-grow page-sidebar ng-scope splitter_panel" split-v="splitterCtrl">
<main class="hbox-grow right_panel" style="width: 1233px;">
<div ui-view="" class="ng-scope"><div class="task page ng-scope"> <!-- THIS is the line with the CSS I'm editing -->
<div class="task page ng-scope">
<article class="page-content">
<ui-view class="ng-scope">
<article class="page-content ng-scope" style="height: 100%; background-color: aliceblue; display: flex; flex-direction: column; flex: 1;">
<div id="gridContainer" style="height: 100%; background-color: yellow; flex-direction: column; flex: 1 1 0%; display: flex;">
<!-- THIS is the div that gets populated with the ag-grid -->
<div id="gridContent" style="width: 100%; background-color: hotpink; flex: 1; display: flex; flex-direction: column;" class="ag-fresh">

Can't seem to center elements in flex (top and bottom)

I'm having big trouble centering two elements in a flex container. What I would like to do is to center one element at the top of the flex container (using flex-start ?) and one element at the bottom of the container (flex-end ?). I have tried several options, but was unable to get what I want. Most of my tries ended in one element in the top left half of the container, and the other one in the bottom right one.....
Please have a look at: jsfiddle
<!DOCTYPE html>
<body>
<div class="flexcontainer1">
<div class="txt1"> Some text here </div>
</div>
<div class="flexcontainer2">
<div class="row">
<div class="txt2"> Some more text </div>
<div class="txt2"> Even more text </div>
</div>
</div>
</body>
Is this at all possible ?
Furthermore: I'm telling the elements to be centered, but it looks like the second line (Even more text) is not centered at all. Or is this just optical ?
Thanks,
Hans
The .row container between the flex container and the flex items is annoying, so get rid of it.
And then,
.flexcontainer1, .flexcontainer2 {
display: flex; /* Magic begins */
flex-direction: column; /* Vertical layout */
align-items: center; /* Center horizontally */
}
.flexcontainer1 { justify-content: space-around; }
.flexcontainer2 { justify-content: space-between; }
.flexcontainer1, .flexcontainer2 {
display: flex;
flex-direction: column;
align-items: center;
border: 1px solid black;
}
.flexcontainer1 {
justify-content: space-around;
height: 250px;
}
.flexcontainer2 {
justify-content: space-between;
height: 150px;
}
.txt1 {
font-size: 3.0vw;
}
.txt2 {
font-size: 2.2vw;
}
<div class="flexcontainer1">
<div class="txt1">Some text here</div>
</div>
<div class="flexcontainer2">
<div class="txt2">Some more text</div>
<div class="txt2">Even more text</div>
</div>

Resources