horizontally align and vertically center three elements in a container - html

I need to align 3 items inside Div.
Every item must be placed vertically in the center.
First item 2% margin-left.
Second item in the center and must be a textbox.
Third item 2% margin-right.
Item First and Third must fit the div(square).
I used alignment but it didn't work. Here there is a graphic example:

HTML
<div id="container">
<div class="box" id="left"></div>
<input type="text" name="search" placeholder="SEARCH HERE" id="searchbox">
<div class="box" id="right"></div>
</div><!-- end #container-->
CSS
#container {
display: flex;
justify-content: space-between;
align-items: center;
width: 95%;
height: 90px;
background-color: orangered;
}
.box {
height: 75px;
width: 75px;
background-color: lightgreen;
}
#left {
margin-left: 2%;
}
#right {
margin-right: 2%;
}
input {
width: 250px;
padding: 18px;
font-size: 2em;
}
DEMO: http://jsfiddle.net/xptx9wxn/2/
For more information about CSS Flexbox visit:
A Complete Guide to Flexbox
Using CSS flexible boxes - Web developer guide | MDN

Related

How to center the middle item in a flex row? [duplicate]

This question already has answers here:
Center one and right/left align other flexbox element
(11 answers)
Keep the middle item centered when side items have different widths
(12 answers)
Closed 4 years ago.
What I want as a result:
I have three elements in a container that is a display: flex I want the left item to be aligned to the left, and the right item to the right. With the center item aligned in the center.
space-between is not the fix. It is not the solution I am looking for. This is because the elements are differing widths. Even with differing widths, I still want the middle element to be centered.
This could be fixed with a wrapper. and then put a flex: 1 on the wrappers, then within those wrappers, have the elements themselves. Again, this is not the fix I am looking for. I cannot use wrappers in my situation.
.parentContainer {
display: flex;
justify-content: center;
align-items: center;
}
.parentContainer > *{
background: red;
text-align: center;
}
<div class="parentContainer">
<div class="left">small</div>
<div class="middle">medium element here</div>
<div class="right">longer element is here too</div>
</div>
The primary way to achieve this layout – because it's clean and valid – is with flex: 1 on the items. That method is explained in the following post, but is also ruled out in this question.
Keep the middle item centered when side items have different widths
An alternative method involves CSS absolute positioning:
.parentContainer {
display: flex;
justify-content: space-between;
position: relative;
}
.middle {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
/* non-essential decorative styles */
.parentContainer > * { background: orange; text-align: center; padding: 5px; }
p { text-align: center;}
p > span { background-color: aqua; padding: 5px; }
P > span:first-child { font-size: 1.5em; }
<div class="parentContainer">
<div class="left">small</div>
<div class="middle">medium element here</div>
<div class="right">longer element is here too</div>
</div>
<p>
<span>↑</span><br>
<span>true center</span>
</p>
This method is explained in the following posts:
Methods for Aligning Flex Items along the Main Axis (see Box #71)
Element will not stay centered, especially when re-sizing screen
I think you can use a different approach. This is my suggestion.
.parentContainer {
display: table;
width: 100%;
background: lightblue;
border-collapse: collapse;
}
.parentContainer > div {
display: table-cell;
width: 33%;
}
.parentContainer > div:nth-child(1) {
text-align: left;
}
.parentContainer > div:nth-child(2) {
text-align: center;
}
.parentContainer > div:nth-child(3) {
text-align: right;
}
<div class="parentContainer">
<div>small</div>
<div>medium element here</div>
<div>longer element is here too</div>
</div>

CSS Flexbox float elements [duplicate]

This question already has answers here:
Is it possible for flex items to align tightly to the items above them?
(5 answers)
Make a div span two rows in a grid
(2 answers)
Closed 5 years ago.
I'm trying to float two elements at the right of a "figure" element using flex but it end up floating just div1 at the right of figure and div2 is moved bellow, if I make div1 and div2 narrow enough, they are floated inline at the right of figure.
This is the CSS:
.container {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
}
Desired Result:
Actual Result:
How it works?
First, you make a flex-container (flexc in this case) and apply the display:flex property on it which aligns the elements by default in row alignment. If you want an element to preserve its dimensions set it to flex:0 0 auto; else you can make use of flex:1; which shrinks or grows as the browser is resized.
Then to align the contents in column (div1 and div2) you can just wrap then in a different container and since div isn't an inline container, and the flex property doesn't have any effect on any other than the direct children of the flex parent, they are aligned in seperate lines.
.flexc {
display: flex;
justify-content: flex-start;
}
#fig {
flex: 0 0 auto;
width: 200px;
height: 200px;
background: gray;
text-align: center;
color: white;
margin: 10px;
border: 2px solid black;
}
#d1,
#d2 {
width: 200px;
height: 50px;
background: purple;
text-align: center;
color: white;
margin: 10px;
border: 2px solid black;
}
<div class="flexc">
<div id="fig">Figure</div>
<div class="col">
<div id="d1">div1</div>
<div id="d2">div2</div>
</div>
</div>
Without altering the html:
.flexc {
display: flex;
flex-direction:column;
position:relative;
}
#fig {
flex: 0 0 auto;
width: 200px;
height: 200px;
background: gray;
text-align: center;
color: white;
margin: 10px;
border: 2px solid black;
}
#d1,
#d2 {
position:absolute;
left:250px;
width: 200px;
height: 50px;
background: purple;
text-align: center;
color: white;
margin: 10px;
border: 2px solid black;
}
#d2{
top:70px;
}
<div class="flexc">
<div id="fig">Figure</div>
<div id="d1">div1</div>
<div id="d2">div2</div>
</div>
Not sure what your HTML looks like, but display: flex is best used on the container wrapping all the elements you want aligned. Imagine it to be the largest box that you put smaller boxes inside.
Codepen example demonstrating this: https://codepen.io/corviday/pen/VyYdar
Following this hierarchy with .container as your largest box, since you want two columns, you can divide it further into two smaller boxes (.left in red and .right in blue in this case).
From there you would need to group div1/div2 together to float the way you'd like, and would be the items that fill the box .right.
You can use Bootstrap to resolve or put div1 and div2 in one div main to drop div main
Bootstrap exemple
<div class='container'>
<div class="col-md-12">
<div class="col-md-6">
1 text
</div>
<div class="col-md-6">
<div class="col-md-6">
2 text
</div>
<div class="col-md-6">
3 text
</div>
</div>
</div>
</div>
I think the best layout engine to use for your use case is hinted at in your description of the problem: Floats.
Here is a solution that doesn't require you to alter your html.
<div class="container">
<div class="medium-box">figure</div>
<div class="small-box">div 1</div>
<div class="small-box">div 2</div>
</div>
.container{
width: 500px;
}
.medium-box {
height: 200px;
width: 200px;
margin: 10px;
background: grey;
float:left
}
.small-box {
float:left;
height: 30px;
width: 200px;
background: blue;
margin: 10px;
}
https://codepen.io/stacyvlasits/pen/aVPZbY

CSS Flex Stacking Items on Top of Each Other [duplicate]

This question already has answers here:
Prevent flex items from rendering side to side
(3 answers)
Closed 5 years ago.
I'm trying to place some <h1></h1> text, and an email form from Angular Material, into the center of a <div></div> section that has a colored background. The items are coming out stacked on top of each other, as if they were layers. The email form needs to be underneath the <h1></h1> tags. The only way I could get this to align properly was with position:flex, which I suspect is the underlying cause.
Here's my html and css:
<div class="top-section">
<h1 class="top-h1">
mytitle
</h1>
<md-input-container class="email-form" color="accent">
<input mdInput placeholder="Email us" value="Your email address">
</md-input-container>
</div>
.top-section {
height: 350px;
background-color: #04041b;
align-items: center;
display: flex;
justify-content: center;
}
.top-h1 {
color: #E8E8E8;
font-size: 60px;
position: absolute;
}
.email-form {
color: white;
font-size: 30px;
}
Any thoughts?
You're using position: absolute on the h1 which removes it from the flow of the page, and positions it relative to it's closest positioned parent. So other elements won't flow around it. Remove that. Then your items will display side-by-side since the default flex-direction for a flex parent is row. To display the items vertically, use flex-direction: column and the items will stack on top of one another in a column instead of side-by-side in a row.
.top-section {
height: 350px;
background-color: #04041b;
align-items: center;
display: flex;
justify-content: center;
flex-direction: column;
}
.top-h1 {
color: #E8E8E8;
font-size: 60px;
}
.email-form {
color: white;
font-size: 30px;
}
<div class="top-section">
<h1 class="top-h1">
mytitle
</h1>
<md-input-container class="email-form" color="accent">
<input mdInput placeholder="Email us" value="Your email address">
</md-input-container>
</div>
I would imagine this is due to the fact that you have .top-h1 with the position set to absolute.
Create something like the following and it should sort out your issue:
<div class="container">
<h1>Example</h1>
<div class="form">
<!-- ignore this div, this is an example of where your form will be. -->
</div>
</div>
.container {
height: 350px;
background-color: #E0E0E0;
width: 100%;
margin: auto;
text-align: center;
}
.form {
width: 100%;
margin: auto;
}
This should do what you want. If I have misunderstood the question please reply and I can adjust my response but this is what I get from you wanting the elements not to stack and for the form to be located under the h1 but remain centred.
For future reference, if you ever need to align a div, give it a width and then use margin: auto;
Best of luck.

How to use flex to align button with centered text but icon to one side? [duplicate]

I'm using flexbox to align my child elements. What I'd like to do is center one element and leave the other aligned to the very left. Normally I would just set the left element using margin-right: auto. The problem is that pushes the center element off center. Is this possible without using absolute positioning?
HTML & CSS
#parent {
align-items: center;
border: 1px solid black;
display: flex;
justify-content: center;
margin: 0 auto;
width: 500px;
}
#left {
margin-right: auto;
}
#center {
margin: auto;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
</div>
Add third empty element:
<div class="parent">
<div class="left">Left</div>
<div class="center">Center</div>
<div class="right"></div>
</div>
And the following style:
.parent {
display: flex;
}
.left, .right {
flex: 1;
}
Only left and right are set to grow and thanks to the facts that...
there are only two growing elements (doesn't matter if empty) and
that both get same widths (they'll evenly distribute the available space)
...center element will always be perfectly centered.
This is much better than accepted answer in my opinion because you do not have to copy left content to right and hide it to get same width for both sides, it just magically happens (flexbox is magical).
In action:
.parent {
display: flex;
}
.left,
.right {
flex: 1;
}
/* Styles for demonstration */
.parent {
padding: 5px;
border: 2px solid #000;
}
.left,
.right {
padding: 3px;
border: 2px solid red;
}
.center {
margin: 0 3px;
padding: 3px;
border: 2px solid blue;
}
<div class="parent">
<div class="left">Left</div>
<div class="center">Center</div>
<div class="right"></div>
</div>
EDIT: See Solo's answer below, it is the better solution.
The idea behind flexbox is to provide a framework for easily aligning elements with variable dimensions within a container. As such, it makes little sense to provide a layout where the width of one element is totally ignored. In essence, that is exactly what absolute positioning is for, as it takes the element out of the normal flow.
As far as I know, there is no nice way of doing this without using position: absolute;, so I would suggest using it... but If you REALLY don't want to, or can't use absolute positioning then I suppose you could use one of the following workarounds.
If you know the exact width of the "Left" div, then you could change justify-content to flex-start (left) and then align the "Center" div like this:
#center {
position: relative;
margin: auto;
left: -{half width of left div}px;
}
If you do not know the width, then you could duplicate "Left" on the right side, use justify-content: space-between;, and hide the new right element:
Just to be clear, this is really, really ugly... better to use absolute positioning than to duplicate content. :-)
#parent {
align-items: center;
border: 1px solid black;
display: flex;
justify-content: space-between;
margin: 0 auto;
width: 500px;
}
#right {
opacity: 0;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
<span id="right">Left</span>
</div>
.parent {
display: flex;
}
.left {
flex: 1;
}
.parent::after {
flex: 1;
content: '';
}
<div class="parent">
<div class="left">Left</div>
<div>Center</div>
</div>
I have another solution. In my opinion, Adding an empty block to the center element is fine but code-wise it bit ugly.
Since this is 4 years old I figured I'd update this with a much easier CSS Grid solution.
#parent {
display: grid;
grid-template-columns: repeat(3, 1fr);
border: 1px solid black;
margin: 0 auto;
width: 500px;
}
#center {
text-align: center;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
</div>
If you don't want to rely on positioning, the only way I've found that makes it truly centered is to use a combination of auto margin and negative margin prevent the centered element to getting pushed over by the left aligned element. This requires that you know the exact width of the left aligned element though.
.container {
height: 100px;
border: solid 10px skyblue;
display: flex;
justify-content: center;
}
.block {
width: 120px;
background: tomato;
}
.justify-start {
margin-right: auto;
}
.justify-center {
margin-right: auto;
margin-left: -120px;
}
<div class="container">
<div class="block justify-start"></div>
<div class="block justify-center"></div>
</div>
As far as I know this is possible with the following code.
https://jsfiddle.net/u5gonp0a/
.box {
display: flex;
justify-content: center;
background-color: green;
text-align: left;
}
.left {
padding: 10px;
background-color: pink;
}
.center {
padding: 10px;
background-color: yellow;
margin: 0 auto;
}
<div class="box">
<div class="left">left</div>
<div class="center">center</div>
</div>
Try this no hacks :)
CSS
.container{
width: 500px;
margin: 0 auto;
}
.box{
display: flex;
align-items: center;/* just in case*/
justify-content: space-between;
}
.box p:nth-child(2){
text-align: center;
background-color: lime;
flex: 1 1 0px;
}
HTML
<div class="container">
<div class="box">
<p>One</p>
<p>Two</p>
</div>
</div>
http://codepen.io/whisher/pen/XpGaEZ
If you have a grid system you can use it to do what you want without "extra" css.
Below with bootstrap (V 4.X)
Note: It uses flex under the hood
<div class="row">
<div class="col text-left">left</col>
<div class="col text-center">center</col>
<div class="col text-right">right</col>
</div>
Doc bootstrap: https://getbootstrap.com/docs/4.6/layout/grid/
Et voilà ! :)
Solution 1: give 50% width to center element and use justify-content:space-between
#parent {
display: flex;
justify-content: space-between;
}
#center {
flex-basis: 50%;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
</div>
Solution 2: Add one dummy element and hide it.
#parent {
display: flex;
justify-content: space-between;
}
#right {
visibility:hidden;
}
<div id="parent">
<span id="left">Left</span>
<span id="center">Center</span>
<span id="right">Right</span>
</div>

Position flex children next to each other with align-self

I am trying to make a simple nav with next and previous buttons. Previous is at the far left of the container, and next at the far right. I know what you're thinking: this is the ideal time to use justify-content: space-between. However, when a user is on the first page or the last page, the backend doesn't output the previous and next buttons respectively. This causes the next button to be aligned left on the first page, and that's not what I want.
I thought I could use align-self on the children. The problem I encounter now is that the first child pushes the second one down and I don't know how to fix this.
Here's a snippet
.container {
display: flex;
}
.container * {
width: 10%;
height: 80px;
}
#d1 {
background: green;
align-self: flex-start;
}
#d2 {
background: red;
align-self: flex-end;
}
<div class="container">
<div id="d1">
div 1
</div>
<div id="d2">
div 2
</div>
</div>
I completely forgot about magic margins in flex. Here goes:
.container {
display: flex;
}
.container * {
width: 10%;
height: 80px;
}
#d1 {
margin-right: auto;
background: red;
}
#d2 {
margin-left: auto;
background: green;
}
<div class="container">
<div id="d1">
div 1
</div>
<div id="d2">
div 2
</div>
</div>