flexbox refuses to justify content as i intended - css

i am so confused about flexbox. i tried to use it to align some inputs in a simple form but it won't work the way i was intending. first i did this:
.container {
width: 40vw;
display: flex;
justify-content: space-between;
}
and in html:
<div class="container">
<form id="location">
<input type="text" placeholder="Location">
<input type="submit" value="Get the weather!">
</form>
</div>
i was hoping the justify-content: space-between would add space between the two inputs so they floating out to the outer bounds of the container. not happening. after reading this: justify-content property isn't working i tried the following:
.container {
width: 40vw;
display: flex;
justify-content: center;
}
.item {
flex-grow: 1;
}
and in html
<div class="container">
<form id="location">
<div class="item"><input type="text" placeholder="Location"></div>
<div class="item"><input type="submit" value="Get the weather!"></div>
</form>
</div>
now it looks even worse, because the divs are on top of each other, instead of next to each other. adding flex-direction: row doesn't change a thing. any advice?

#location{
width: 40vw;
display: flex;
justify-content: space-between;
}
<div class="container">
<form id="location">
<div class="item"><input type="text" placeholder="Location"></div>
<div class="item"><input type="submit" value="Get the weather!"></div>
</form>
</div>
You have made .container div as your flex-container, which has only one flex-item #location form: You must make #location form your flex container so that it has two child elements to space-between your 400px width container And it will work fine
To brush up some fundamentals about flex-box visit: https://css-tricks.com/snippets/css/a-guide-to-flexbox/

If i understands correctly you need to add flexbox to parent. Your location is parent of the input elements.
.container {
width: 40vw;
#location {
display: flex;
justify-content: space-between;
}
}

This is happening because you are targeting the wrong element.
Flex works on a parent of the element that you want to move.
You want to move elements of the form, so you should apply flex to your form tag instead of the div.container.
Because the form tag is also just a div, not an element to be moved.
Here is solution to your problem : https://codepen.io/Juka99/pen/OJRmPVN

Try use flex box for #location.
The parent of 2 inputs, are form not container.

Related

Why does `justify-content: stretch` require `flex-grow` to make input elements expand

In the following snippet, where I am making response form, where labels are above on mobile, and to left with desktop. The elements with a .field class have justify-content: stretch, which should make the items expand to fit the available space.
However I find that the <input> elements do not expand. I have to add flex-grow: 1 to it in order to make it expand to fill the available width.
This shows I don't understand what stretch is doing. Why is the flex-grow required.
MDN says:
justify-content: stretch; /* Distribute items evenly
Stretch 'auto'-sized items to fit
the container */
And you can see below the .input elements have width: auto.
UPDATE: I added the div.not-needed elements below to show a flew child can be a flex parent to and it does not make the difference. This way I separated the two layers of flex parents.
Later on in the MDN link it says:
Note: stretch is not supported by flexible boxes (flexbox).
So the stretch value is only valid for grid for now I think, and not flexbox.
.container {
display: flex;
align-items: stretch;
flex-direction: column;
}
.label {
width: 100px;
}
.input {
width: auto;
flex-grow: 1;
}
.field {
display: flex;
justify-content: stretch;
flex-wrap: wrap;
}
<div class="container">
<div class="not-needed">
<div class="field">
<label for="ID_FIELD_1" class="label">Label 1</label>
<input id="ID_FIELD_1" class="input" type="text" name="field_1" value="Value 1">
</div>
</div>
<div class="not-needed">
<div class="field">
<label for="ID_FIELD_2" class="label">Label 2</label>
<input id="ID_FIELD_2" class="input" type="text" name="field_2" value="Value 2">
</div>
</div>
<div class="not-needed">
<div class="field">
<label for="ID_FIELD_3" class="label">Label 3</label>
<input id="ID_FIELD_3" class="input" type="text" name="field_3" value="Value 3">
</div>
</div>
</div>
The justify-content property has to be applied to flex containers and not to it's items.
Even then it just defines how the space between and around content items is distributed (see CSS justify-content).
For filling the available space, the item element (your input) has to grow (e.g. flex-grow: 1) or it's width to be set (e.g. width: 100%).

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

Why changing flex direction changes the child height?

I'm trying to make a media query to display an input below the other instead on your side using Flexbox. As you can see, with my current code, I'm getting this:
But if I change the flex-direction to column, the input width is not the original. This is the result:
This is the my HTML:
<div id="mc_embed_signup">
<form action="//eliasgarcia.us8.list-manage.com/subscribe/post?u=55cf7078733f0b62eb97733e3&id=ace40b1824" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate>
<div id="mc_embed_signup_scroll">
<label for="mce-EMAIL">No te pierdas ningún artículo</label>
<div class="mc-wrapper">
<input type="email" value="" name="EMAIL" id="mce-EMAIL" placeholder="Correo electrónico" required>
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true">
<input type="text" name="b_55cf7078733f0b62eb97733e3_ace40b1824" tabindex="1" value="">
</div>
<div>
<input type="submit" value="Suscríbete" name="subscribe" id="mc-embedded-subscribe" class="button">
</div>
</div>
<div class="mc-error">
</div>
</div>
</form>
</div>
And this is my CSS:
#mc_embed_signup {
label {
font-size: 2em;
font-weight: bold;
display: block;
text-align: center;
}
.mc-wrapper {
display: flex;
justify-content: space-between;
padding: 30px 0px 0px 0px;
}
#mce-EMAIL {
width: 100%;
margin: 0px 30px 0px 0px;
border: 2px solid $medium-grey;
border-radius: 4px;
text-indent: 20px;
}
.button {
margin: 0px auto;
cursor: pointer;
}
}
Why is this happening?
NOTE: I can't provide a Fiddle because this is an integration with MailChip, so it calls a JS Script and it's not working properly on Fiddle, I don't know why... But the script doesn't add any extra classes, only the ones above.
The flex children of a flex parent with flex-direction: row (the default for display: flex) will be equal heights. So since your left input is a direct child of .mc-wrapper, it's height will be equal to the height of the item beside it, and that will cause the input's height to grow since the flex child on the right is taller.
When you switch to a flex-direction: column you no longer have adjacent children in a row, and flexbox will not try to match the heights, so the input will be whatever height it is naturally.
Add
flex-flow: wrap;
This way, the height will remain as it.
display: flex; won't affect it
IMPORTANT
There is a style called align-items which by default is stretch. This is what it makes the elements width/height to match it's parents depending on flex-direction.
For anyone getting here, this might be useful: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
You must change just "align-items".
I have this HTML case:
<section>
<hgroup>
<h1>Our Products</h1>
<h3>We build all kind of containers</h3>
<p>Lorem Ipsum is simply dummy text of the printing..</p>
</hgroup>
<button class="full-color pull-right">View All Products</button>
</section>
...and the CSS is like that:
section {
display: flex;
flex-direction: row;
justify-content: space-between;
}
Now input height is same as hgroup
But, if I add to the section:
align-items: baseline;
the input height is like you expected. You must avoid:
align-items: inherit/unset/stretch/initial/normal
You just need to add flex-flow: wrap-reverse to the flex parent and then everything goes well :)
example:
.parent {
display:flex;
flex-direction: column-reverse;
flex-flow: wrap-reverse;
}
Good Luck

Flex box not vertically and horizontally centering

I'm currently making an Electron app with the View powered by Vue.js
I currently have this (for testing purposes)
<template>
<div class="formWrapper">
<div class="inputGroup">
<span class="inputPrepend"><i class="fa fa-user"></i></span>
<input type="text" name="" value="">
</div>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
.formWrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.inputGroup {
align-self: center;
}
</style>
I end up with this result:
But I cannot seem to get the vertical centering to happen.
I have made sure all parent elements have a height: 100%; but still can't get it to go down, also why do I need to specify align-self if the parent flex container formWrapper has specified center for align-items and justify-content
Thanks.
You need to set body to height: 100vh, and formWrapper and all parent elements to height: 100%.
Live example:
body {
height: 100vh;
}
.formWrapper {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
<div class="formWrapper">
<div class="inputGroup">
<span class="inputPrepend"><i class="fa fa-user"></i></span>
<input type="text" name="" value="">
</div>
</div>
There might be a smarter way to do this, but this is the best I could figure out.

How do I right align div elements?

The body of my html document consists of 3 elements, a button, a form, and a canvas. I want the button and the form to be right aligned and the canvas to stay left aligned. The problem is when I try to align the first two elements, they no longer follow each other and instead are next to each other horizontally?, heres the code I have so far, I want the form to follow directly after the button on the right with no space in between.
#cTask {
background-color: lightgreen;
}
#button {
position: relative;
float: right;
}
#addEventForm {
position: relative;
float: right;
border: 2px solid #003B62;
font-family: verdana;
background-color: #B5CFE0;
padding-left: 10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
<script type="text/javascript" src="timeline.js"></script>
<link rel="stylesheet" href="master.css" type="text/css" media="screen" />
</head>
<body bgcolor="000" TEXT="FFFFFF">
<div id="button">
<button onclick="showForm()" type="button" id="cTask">
Create Task
</button>
</div>
<div id="addEventForm">
<form>
<p><label>Customer name: <input></label></p>
<p><label>Telephone: <input type=tel></label></p>
<p><label>E-mail address: <input type=email></label></p>
</form>
</div>
<div>
<canvas id="myBoard" width="600" height="600" style="background:lightgray;">
<p>Your browser doesn't support canvas.</p>
</canvas>
</div>
</body>
</html>
Floats are okay, but problematic with IE 6 & 7.
I'd prefer using the following on the inner div:
margin-left: auto;
margin-right: 0;
See the IE Double Margin Bug for clarification on why.
You can make a div that contains both the form & the button, then make the div float to the right by setting float: right;.
Old answers. An update: use flexbox, pretty much works in all browsers now.
<div style="display: flex; justify-content: flex-end">
<div>I'm on the right</div>
</div>
And you can get even fancier, simply:
<div style="display: flex; justify-content: space-around">
<div>Left</div>
<div>Right</div>
</div>
And fancier:
<div style="display: flex; justify-content: space-around">
<div>Left</div>
<div>Middle</div>
<div>Right</div>
</div>
You can use flexbox with flex-grow to push the last element to the right.
<div style="display: flex;">
<div style="flex-grow: 1;">Left</div>
<div>Right</div>
</div>
Note that while this answer is not wrong, it is very outdated methodology written in 2015
Other answers for this question are not so good since float:right can go outside of a parent div (overflow: hidden for parent sometimes might help) and margin-left: auto, margin-right: 0 for me didn't work in complex nested divs (I didn't investigate why).
I've figured out that for certain elements text-align: right works, assuming this works when the element and parent are both inline or inline-block.
Note: the text-align CSS property describes how inline content like text is aligned in its parent block element. text-align does not control the alignment of block elements itself, only their inline content.
An example:
<div style="display: block; width: 80%; min-width: 400px; background-color: #caa;">
<div style="display: block; width: 100%">
I'm parent
</div>
<div style="display: inline-block; text-align: right; width: 100%">
Caption for parent
</div>
</div>
Here's a JS Fiddle.
If you have multiple divs that you want aligned side by side at the right end of the parent div, set text-align: right; on the parent div.
Do you mean like this? http://jsfiddle.net/6PyrK/1
You can add the attributes of float:right and clear:both; to the form and button
Maybe just:
margin: auto 0 auto auto;
Simple answer is here:
<div style="text-align: right;">
anything:
<select id="locality-dropdown" name="locality" class="cls" style="width: 200px; height: 28px; overflow:auto;">
</select>
</div>
Sometimes float: left leads to design problems, for that cases you can use display flex like this:
.right {
display: flex;
justify-content: flex-end;
margin-left: auto;
margin-right: 0;
}
<div>
<div class="right">Right</div>
</div>
If you are using bootstrap, then:
<div class="pull-right"></div>
One way could be setting a parent div for those elements that need to be pulled right and do the rest like the way shown in the the example below to have them right-aligned:
.parent-div {
display: flex;
float: right;
}
/*Below: child-div styling is not needed for this purpose! this is just for demonstration:*/
.child-div {
text-align: center;
background-color: powderblue;
margin: auto 10px;
height: 100px;
width: 50px;
}
<div class="">CANVAS div </div>
<div class="parent-div">
<div class="child-div">child 1</div>
<div class="child-div">child 2</div>
<div class="child-div">...</div>
<div class="child-div">child n</div>
</div>
If you don't have to support IE9 and below you can use flexbox to solve this: codepen
There's also a few bugs with IE10 and 11 (flexbox support), but they are not present in this example
You can vertically align the <button> and the <form> by wrapping them in a container with flex-direction: column. The source order of the elements will be the order in which they're displayed from top to bottom so I reordered them.
You can then horizontally align the form & button container with the canvas by wrapping them in a container with flex-direction: row. Again the source order of the elements will be the order in which they're displayed from left to right so I reordered them.
Also, this would require that you remove all position and float style rules from the code linked in the question.
Here's a trimmed down version of the HTML in the codepen linked above.
<div id="mainContainer">
<div>
<canvas></canvas>
</div>
<div id="formContainer">
<div id="addEventForm">
<form></form>
</div>
<div id="button">
<button></button>
</div>
</div>
</div>
And here is the relevant CSS
#mainContainer {
display: flex;
flex-direction: row;
}
#formContainer {
display: flex;
flex-direction: column;
}
display: flex;
justify-content: space-between;
hasnt been mentioned. if there are 2 elements (even if one is an empty div) it will place one on the left and one on the right.
<div style="display: flex; justify-content: space-between;">
<div id="emptyDiv"></div>
<div>I'm on the right</div>
</div>
You can simply use padding-left:60% (for ex) to align your content to right and simultaneously wrap the content in responsive container (I required navbar in my case)
to ensure it works in all examples.
You can do it easy by just add this css:
(Works in IE11)
<div>
<!-- Subtract with the amount of your element width -->
<span style="margin-left: calc(100vw - 50px)">Right</span>
</div>
I know this is an old post but couldn't you just use <div id=xyz align="right"> for right.
You can just replace right with left, center and justify.
Worked on my site:)

Resources