Flexbox creates blank space on the right of a page - html

Whenever i remove the flex display- it goes away. Can't understand what's happening there. Been going through source up and down, but no element seems to be stretching there.
html of it
<div class="newheadwrap">
<div class="newlogo newhead">with contents</div>
<div class="newtagline newhead" >with contents</div>
<div class="mainhead newhead">with contents</div>
</div>
and the css
.newheadwrap {
-o-display:flex;
-webkit-display:flex;
-ms-display:flex;
-moz-display:flex;
display:flex;
flex-direction:row;
width:966px;
margin:0 auto;
}
.newlogo {
width:17%;
padding-top:43px;
}
.newtagline {
width:33%;
color:white;
padding-top:93px;
font-family: berkeleyFont;
font-size:16px;
float:right !important;
}
.mainhead {
width:50%;
}
I know it's not advised to post live links here, but fiddle will not do in this case, so, here is a link
https://aps-direct.myshopify.com

One way to remove the extra padding to the right side of your current page:
Add overflow: hidden; to the .newheadwrap
.newheadwrap {
-o-display: flex;
-webkit-display: flex;
-ms-display: flex;
-moz-display: flex;
display: flex;
flex-direction: row;
width: 966px;
margin: 0 auto;
overflow: hidden;
}
You have extra space because of this:
.span9 {
width: 717px;
}
reduce the width and it will fit

Related

Issues with alignment when it comes to flex

I have two issues with my flex I require assistance resolving. I created a fiddle here to access: https://jsfiddle.net/dmj5yscz/
Issue 1: I am unable to move the elements to the center (see red in screenshot). Tried margin-left:auto and margin-right:auto in various places but no luck. (note: should only happen if width is no more than 1144px)
Issue 2: I want the text to be vertically aligned in the center (any screen width)
Here is the code:
<!-- newsletter section -->
<div class="newsletter_section">
<div class="newsletter_inner_section">
<div class="newsletter_left content-box">
<img src="xxx">
</div>
<div class="newsletter_mobile_col">
<div class="newsletter_center content-box">
<p class="newsletter_text_section">Text1 </p>
</div>
<p class="newsletter_input_section">Text2 </p>
</div>
</div>
</div>
/* newsletter section */
.newsletter_inner_section{
display:flex;
}
.newsletter_gif{
width:150px;
height:auto;
}
.newsletter_left,
.newsletter_center,
.newsletter_right{
display:inline-flex;
}
.newsletter_left{
width:auto;
}
.newsletter_center{
width:100%;
}
.newsletter_right{
width:40%;
justify-content:flex-end;
}
.newsletter_text_section{
color:black !important;
font-size:20px !important;
font-weight:bold;
}
/* Media Newsletter section only */
#media (max-width:1144px){
.newsletter_right,
.newsletter_center{
width:auto;
}
.content-box {
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
}
.newsletter_inner_section{
justify-content:center;
display: flex;
flex-direction:row;
}
.newsletter_text_section{
padding-left:15px;
margin-bottom:0;
}
.newsletter_mobile_col {
flex-grow: 1;
display: flex;
flex-direction: column;
}
}
#media (max-width:565px){
.newsletter_inner_section{
flex-direction:column;
}
.newsletter_left{
margin-left:auto;
margin-right:auto;
}
.newsletter_gif{
padding-bottom:20px;
}
}
You have set: flex-grow:1; which is making second flex-div to take available space. Please remove this and it will be center aligned
.newsletter_mobile_col {
/* flex-grow: 1; */
display: flex;
flex-direction: column;
}
And yes, use align-items:center; on flex container to make it center aligned across cross-axis.
#media (max-width: 1144px){
.newsletter_inner_section {
justify-content: center;
display: flex;
flex-direction: row;
align-items: center;/* here */
}
}
And if you want to behaviour on all screens, just write the above CSS outside media query :)
To display flex items into center
Flexbox link
(justify content)
For the second, set another display flex with: flex direction column and center it

how to make a percentage height div responsive to content inside 100vh section

morning all,
thought this one would be straight forward but not (unless I'm missing something obvious)
[EDIT] The Layout of the front-page section has to match the front cover of a book that has a yellow stripe 28% of the height of the book, 60% down the page [/EDIT]
I have a section that I want 100vh within that section I have two divs set to percentage height, each with content. It all looks great until I reduce the screen size. How can I have a percentage height div and keep it responsive to the content (apart from using media queries). Note, I'm using flex to position the content within the divs.
[EDIT] In other words (if necessary) increase the height of the 60% .intro div and the 28% .stripe div to accommodate the text wrapping
I've tried playing with using min-height:28%; on the .stripe class but that then breaks the constraints of the image height being 80% of the .stripe height. Can anyone help please.
.fs {
height: 100vh;
}
.container {
margin:0;
background-color:#545454;
overflow: auto;
}
.intro {
height:60%;
}
.bees-intro {
font-size:60px;
color:#f4d00b;
text-align:center;
}
.stripe {
height:28%;
background-color:#f4d00b;
color:#000000;
}
.bee-quest {
font-size:80px;
margin-right:0px;
height:100%;
margin-right:40px;
}
.bee-quest img {
margin-right:20px;
height:80%;
}
.align-center-center {
display: flex;
justify-content: center;
align-items: center;
}
.align-right-center {
display: flex;
align-items: center;
justify-content: flex-end;
flex-wrap: wrap;
}
<section id="front-page">
<div class="fs container">
<div class="intro align-center-center">
<h1 class="bees-intro">The Bees of Greater Manchester</h1>
</div>
<div class="stripe">
<div class="bee-quest align-right-center">
<img src="bee-quest.png">
<span class="">QUEST</span>
</div>
</div>
</div>
</section>
A working pen can be seen HERE
I'm not 100% sure what you mean by it's not responsive but i'm guessing you want the yellow box to wrap around the bee logo and text when it's in mobile? To do this, remove the 28% height from the stripe and and use the content within it to determine the height.
Example here:
https://jsfiddle.net/m3fnp0nL/
Let me know if this isn't what you're after :)
Thanks to Shaun I've figured out a good solution
The .stripe is set to min-height: 28vh; and the image is set to height: calc(28vh - 20px);
I've set the .intro to min-height:60vh so as the wrapping text will increase the container size.
.fs {
height: 100vh;
}
.container {
margin:0;
background-color:#545454;
overflow: auto;
}
.intro {
min-height:60vh;
}
.bees-intro {
font-size:60px;
color:#f4d00b;
text-align:center;
}
.stripe{
background-color:#f4d00b;
color:#000000;
min-height:28vh;
}
.bee-quest {
font-size:80px;
margin:10px;
display:flex;
flex-wrap:wrap;
justify-content: center;
align-items: center;
}
.bee-quest img {
height: calc(28vh - 20px);
}
#media (min-width: 768px) {
.bee-quest img {
margin-right:20px;
}
.bee-quest span {
margin-right:20px;
}
}
.align-center-center {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
}
.align-right-center {
display: flex;
align-items: center;
justify-content: flex-end;
flex-wrap: wrap;
}
<section id="front-page">
<div class="fs container">
<div class="intro align-center-center">
<h1 class="bees-intro">The Bees of Greater Manchester</h1>
</div>
<div class="stripe align-right-center">
<div class="bee-quest">
<img src="http://www.beequest.co.uk/images/bee-quest.png">
<span class="">QUEST</span>
</div>
</div>
</section>
The original Pen has been updated with the correct answer
The only problem I have now is that the content scrolls within the divs

CSS Flexbox how to centre divs which are different size? [duplicate]

Imagine the following layout, where the dots represent the space between the boxes:
[Left box]......[Center box]......[Right box]
When I remove the right box, I like the center box to still be in the center, like so:
[Left box]......[Center box].................
The same goes for if I would remove the left box.
................[Center box].................
Now when the content within the center box gets longer, it will take up as much available space as needed while remaining centered. The left and right box will never shrink and thus when where is no space left the overflow:hidden and text-overflow: ellipsis will come in effect to break the content;
[Left box][Center boxxxxxxxxxxxxx][Right box]
All the above is my ideal situation, but I have no idea how to accomplish this effect. Because when I create a flex structure like so:
.parent {
display : flex; // flex box
justify-content : space-between; // horizontal alignment
align-content : center; // vertical alignment
}
If the left and right box would be exactly the same size, I get the desired effect. However when one of the two is from a different size the centered box is not truly centered anymore.
Is there anyone that can help me?
Update
A justify-self would be nice, this would be ideal:
.leftBox {
justify-self : flex-start;
}
.rightBox {
justify-self : flex-end;
}
If the left and right boxes would be exactly the same size, I get the desired effect. However when one of the two is a different size the centered box is not truly centered anymore. Is there anyone that can help me?
Here's a method using flexbox to center the middle item, regardless of the width of siblings.
Key features:
pure CSS
no absolute positioning
no JS/jQuery
Use nested flex containers and auto margins:
.container {
display: flex;
}
.box {
flex: 1;
display: flex;
justify-content: center;
}
.box:first-child > span { margin-right: auto; }
.box:last-child > span { margin-left: auto; }
/* non-essential */
.box {
align-items: center;
border: 1px solid #ccc;
background-color: lightgreen;
height: 40px;
}
p {
text-align: center;
margin: 5px 0 0 0;
}
<div class="container">
<div class="box"><span>short text</span></div>
<div class="box"><span>centered text</span></div>
<div class="box"><span>loooooooooooooooong text</span></div>
</div>
<p>↑<br>true center</p>
Here's how it works:
The top-level div (.container) is a flex container.
Each child div (.box) is now a flex item.
Each .box item is given flex: 1 in order to distribute container space equally (more details).
Now the items are consuming all space in the row and are equal width.
Make each item a (nested) flex container and add justify-content: center.
Now each span element is a centered flex item.
Use flex auto margins to shift the outer spans left and right.
You could also forgo justify-content and use auto margins exclusively.
But justify-content can work here because auto margins always have priority.
8.1. Aligning with auto
margins
Prior to alignment via justify-content and align-self, any
positive free space is distributed to auto margins in that dimension.
Use three flex items in the container
Set flex: 1 to the first and last ones. This makes them grow equally to fill the available space left by the middle one.
Thus, the middle one will tend to be centered.
However, if the first or last item has a wide content, that flex item will also grow due to the new min-width: auto initial value.
Note Chrome doesn't seem to implement this properly. However, you can set min-width to -webkit-max-content or -webkit-min-content and it will work too.
Only in that case the middle element will be pushed out of the center.
.outer-wrapper {
display: flex;
}
.item {
background: lime;
margin: 5px;
}
.left.inner-wrapper, .right.inner-wrapper {
flex: 1;
display: flex;
min-width: -webkit-min-content; /* Workaround to Chrome bug */
}
.right.inner-wrapper {
justify-content: flex-end;
}
.animate {
animation: anim 5s infinite alternate;
}
#keyframes anim {
from { min-width: 0 }
to { min-width: 100vw; }
}
<div class="outer-wrapper">
<div class="left inner-wrapper">
<div class="item animate">Left</div>
</div>
<div class="center inner-wrapper">
<div class="item">Center</div>
</div>
<div class="right inner-wrapper">
<div class="item">Right</div>
</div>
</div>
<!-- Analogous to above --> <div class="outer-wrapper"><div class="left inner-wrapper"><div class="item">Left</div></div><div class="center inner-wrapper"><div class="item animate">Center</div></div><div class="right inner-wrapper"><div class="item">Right</div></div></div><div class="outer-wrapper"><div class="left inner-wrapper"><div class="item">Left</div></div><div class="center inner-wrapper"><div class="item">Center</div></div><div class="right inner-wrapper"><div class="item animate">Right</div></div></div>
The key is to use flex-basis. Then the solution is simple as:
.parent {
display: flex;
justify-content: space-between;
}
.left, .right {
flex-grow: 1;
flex-basis: 0;
}
CodePen is available here.
Here's an answer that uses grid instead of flexbox. This solution doesn't require extra grandchild elements in the HTML like the accepted answer does. And it works correctly even when the content on one side gets long enough to overflow into the center, unlike the grid answer from 2019.
The one thing this solution doesn't do is show an ellipsis or hide the extra content in the center box, as described in the question.
section {
display: grid;
grid-template-columns: 1fr auto 1fr;
}
section > *:last-child {
white-space: nowrap;
text-align: right;
}
/* not essential; just for demo purposes */
section {
background-color: #eee;
font-family: helvetica, arial;
font-size: 10pt;
padding: 4px;
}
section > * {
border: 1px solid #bbb;
padding: 2px;
}
<section>
<div>left</div>
<div>center</div>
<div>right side is longer</div>
</section>
<section>
<div>left</div>
<div>center</div>
<div>right side is much, much longer</div>
</section>
<section>
<div>left</div>
<div>center</div>
<div>right side is much, much longer, super long in fact</div>
</section>
Instead of defaulting to using flexbox, using grid solves it in 2 lines of CSS without additional markup inside the top level children.
HTML:
<header class="header">
<div class="left">variable content</div>
<div class="middle">variable content</div>
<div class="right">variable content which happens to be very long</div>
</header>
CSS:
.header {
display: grid;
grid-template-columns: [first] 20% auto [last] 20%;
}
.middle {
/* use either */
margin: 0 auto;
/* or */
text-align: center;
}
Flexbox rocks but shouldn't be the answer for everything. In this case grid is clearly the cleanest option.
Even made a codepen for your testing pleasure:
https://codepen.io/anon/pen/mooQOV
You can do this like so:
.bar {
display: flex;
background: #B0BEC5;
}
.l {
width: 50%;
flex-shrink: 1;
display: flex;
}
.l-content {
background: #9C27B0;
}
.m {
flex-shrink: 0;
}
.m-content {
text-align: center;
background: #2196F3;
}
.r {
width: 50%;
flex-shrink: 1;
display: flex;
flex-direction: row-reverse;
}
.r-content {
background: #E91E63;
}
<div class="bar">
<div class="l">
<div class="l-content">This is really long content. More content. So much content.</div>
</div>
<div class="m">
<div class="m-content">This will always be in the center.</div>
</div>
<div class="r">
<div class="r-content">This is short.</div>
</div>
</div>
Here is another way to do it, using display: flex in the parents and childs:
.Layout{
display: flex;
justify-content: center;
}
.Left{
display: flex;
justify-content: flex-start;
width: 100%;
}
.Right{
display: flex;
justify-content: flex-end;
width: 100%;
}
<div class = 'Layout'>
<div class = 'Left'>I'm on the left</div>
<div class = 'Mid'>Centered</div>
<div class = 'Right'>I'm on the right</div>
</div>
A slightly more robust grid solution looks like this:
.container {
overflow: hidden;
border-radius: 2px;
padding: 4px;
background: orange;
display: grid;
grid-template-columns: minmax(max-content, 1fr) auto minmax(max-content, 1fr);
}
.item > div {
display: inline-block;
padding: 6px;
border-radius: 2px;
background: teal;
}
.item:last-child > div {
float: right;
}
<div class="container">
<div class="item"><div contenteditable>edit the text to test the layout</div></div>
<div class="item"><div contenteditable>just click me and</div></div>
<div class="item"><div contenteditable>edit</div></div>
</div>
And here you can see it in Codepen: https://codepen.io/benshope2234/pen/qBmZJWN
I wanted the exact result shown in the question, I combined answers from gamliela and Erik Martín Jordán and it works best for me.
.parent {
display: flex;
justify-content: space-between;
}
.left, .right {
flex-grow: 1;
flex-basis: 0;
}
.right {
display: flex;
justify-content: flex-end;
}
you can also use this simple way to reach exact center alignment for middle element :
.container {
display: flex;
justify-content: space-between;
}
.container .sibling {
display: flex;
align-items: center;
height: 50px;
background-color: gray;
}
.container .sibling:first-child {
width: 50%;
display: flex;
justify-content: space-between;
}
.container .sibling:last-child {
justify-content: flex-end;
width: 50%;
box-sizing: border-box;
padding-left: 100px; /* .center's width divided by 2 */
}
.container .sibling:last-child .content {
text-align: right;
}
.container .sibling .center {
height: 100%;
width: 200px;
background-color: lightgreen;
transform: translateX(50%);
}
codepen: https://codepen.io/ErAz7/pen/mdeBKLG
Althought I might be late on this one, all those solutions seems complicated and may not work depending on the cases you're facing.
Very simply, just wrap the component you want to center with position : absolute, while letting the other two with justify-content : space-between, like so :
CSS:
.container {
display: flex;
justify-content: space-between;
align-items: center;
background-color: lightgray;
}
.middle {
position: absolute;
margin-left: auto;
margin-right: auto;
/* You should adapt percentages here if you have a background ; else, left: 0 and right: 0 should do the trick */
left: 40%;
right: 40%;
text-align: center;
}
/* non-essential, copied from #Brian Morearty answer */
.element {
border: 1px solid #ccc;
background-color: lightgreen;
}
p {
margin: 5px;
padding: 5px;
}
<div class="container">
<p class="element">First block</p>
<p class="middle element">Middle block</p>
<p class="element">Third THICC blockkkkkkkkk</p>
</div>
Michael Benjamin has a decent answer but there is no reason it can't / shouldn't be simplified further:
.container {
display: flex;
}
.box {
flex: 1;
display: flex;
justify-content: center;
}
.box:first-child { justify-content: left; }
.box:last-child { justify-content: right; }
And html
<div class="container">
<div class="box">short text</div>
<div class="box">centered tex</div>
<div class="box">loooooooooooooooong text</div>
</div>

Alignment issue with flexbox in css

I want to align menu on the left side and page content which has multiple dashboard panels/cards on the right side. The problem is dashboard panels/cards are dynamic sometimes number of cards might be 1 and sometimes more than 1. I want all the dashboard panels on the right side to be center aligned.
I tried with the following code but its not working as expected:
main {
display: flex;
flex-wrap: wrap;
}
aside {
width: 200px;
height: 200px;
border: 2px solid red;
}
.flex-items {
display: flex;
justify-content: center;
flex-wrap: wrap;
}
.flex-item {
margin-left: 50px;
border: 2px solid red;
flex: 1;
width: 250px;
height: 100px;
}
<main>
<aside>Menu</aside>
<section class="flex-items">
<div class="flex-item">item1</div>
<div class="flex-item">item2</div>
<div class="flex-item">item3</div>
</section>
</main>
Codepen
Finally, I would like to have all the items to be responsive when page is shrunk.
I removed the flex: 1; attribute from .flex-item as it looks like you wanted them to be a specific size. width and flex don't make sense used together as flex: 1; enables flex-grow and that tells the div to use all available space.
I then added flex-grow: 1; to .flex-items so it uses all the available space (before it was just as wide as it needed to be) so the justify-content: center can do it's work.
main {
display:flex;
}
aside {
width:200px;
height:200px;
border:2px solid red;
}
.flex-items {
display:flex;
justify-content:center;
flex-wrap:wrap;
flex-grow: 1;
}
.flex-item {
margin-left:10px;
border:2px solid red;
width:80px;
height:100px;
}
<main>
<aside>Menu</aside>
<section class="flex-items">
<div class="flex-item">item1</div>
<div class="flex-item">item2</div>
<div class="flex-item">item3</div>
</section>
</main>
Note: I changed the widths and margins to allow better rendering in small spaces

Keep the middle item centered when side items have different widths

Imagine the following layout, where the dots represent the space between the boxes:
[Left box]......[Center box]......[Right box]
When I remove the right box, I like the center box to still be in the center, like so:
[Left box]......[Center box].................
The same goes for if I would remove the left box.
................[Center box].................
Now when the content within the center box gets longer, it will take up as much available space as needed while remaining centered. The left and right box will never shrink and thus when where is no space left the overflow:hidden and text-overflow: ellipsis will come in effect to break the content;
[Left box][Center boxxxxxxxxxxxxx][Right box]
All the above is my ideal situation, but I have no idea how to accomplish this effect. Because when I create a flex structure like so:
.parent {
display : flex; // flex box
justify-content : space-between; // horizontal alignment
align-content : center; // vertical alignment
}
If the left and right box would be exactly the same size, I get the desired effect. However when one of the two is from a different size the centered box is not truly centered anymore.
Is there anyone that can help me?
Update
A justify-self would be nice, this would be ideal:
.leftBox {
justify-self : flex-start;
}
.rightBox {
justify-self : flex-end;
}
If the left and right boxes would be exactly the same size, I get the desired effect. However when one of the two is a different size the centered box is not truly centered anymore. Is there anyone that can help me?
Here's a method using flexbox to center the middle item, regardless of the width of siblings.
Key features:
pure CSS
no absolute positioning
no JS/jQuery
Use nested flex containers and auto margins:
.container {
display: flex;
}
.box {
flex: 1;
display: flex;
justify-content: center;
}
.box:first-child > span { margin-right: auto; }
.box:last-child > span { margin-left: auto; }
/* non-essential */
.box {
align-items: center;
border: 1px solid #ccc;
background-color: lightgreen;
height: 40px;
}
p {
text-align: center;
margin: 5px 0 0 0;
}
<div class="container">
<div class="box"><span>short text</span></div>
<div class="box"><span>centered text</span></div>
<div class="box"><span>loooooooooooooooong text</span></div>
</div>
<p>↑<br>true center</p>
Here's how it works:
The top-level div (.container) is a flex container.
Each child div (.box) is now a flex item.
Each .box item is given flex: 1 in order to distribute container space equally (more details).
Now the items are consuming all space in the row and are equal width.
Make each item a (nested) flex container and add justify-content: center.
Now each span element is a centered flex item.
Use flex auto margins to shift the outer spans left and right.
You could also forgo justify-content and use auto margins exclusively.
But justify-content can work here because auto margins always have priority.
8.1. Aligning with auto
margins
Prior to alignment via justify-content and align-self, any
positive free space is distributed to auto margins in that dimension.
Use three flex items in the container
Set flex: 1 to the first and last ones. This makes them grow equally to fill the available space left by the middle one.
Thus, the middle one will tend to be centered.
However, if the first or last item has a wide content, that flex item will also grow due to the new min-width: auto initial value.
Note Chrome doesn't seem to implement this properly. However, you can set min-width to -webkit-max-content or -webkit-min-content and it will work too.
Only in that case the middle element will be pushed out of the center.
.outer-wrapper {
display: flex;
}
.item {
background: lime;
margin: 5px;
}
.left.inner-wrapper, .right.inner-wrapper {
flex: 1;
display: flex;
min-width: -webkit-min-content; /* Workaround to Chrome bug */
}
.right.inner-wrapper {
justify-content: flex-end;
}
.animate {
animation: anim 5s infinite alternate;
}
#keyframes anim {
from { min-width: 0 }
to { min-width: 100vw; }
}
<div class="outer-wrapper">
<div class="left inner-wrapper">
<div class="item animate">Left</div>
</div>
<div class="center inner-wrapper">
<div class="item">Center</div>
</div>
<div class="right inner-wrapper">
<div class="item">Right</div>
</div>
</div>
<!-- Analogous to above --> <div class="outer-wrapper"><div class="left inner-wrapper"><div class="item">Left</div></div><div class="center inner-wrapper"><div class="item animate">Center</div></div><div class="right inner-wrapper"><div class="item">Right</div></div></div><div class="outer-wrapper"><div class="left inner-wrapper"><div class="item">Left</div></div><div class="center inner-wrapper"><div class="item">Center</div></div><div class="right inner-wrapper"><div class="item animate">Right</div></div></div>
The key is to use flex-basis. Then the solution is simple as:
.parent {
display: flex;
justify-content: space-between;
}
.left, .right {
flex-grow: 1;
flex-basis: 0;
}
CodePen is available here.
Here's an answer that uses grid instead of flexbox. This solution doesn't require extra grandchild elements in the HTML like the accepted answer does. And it works correctly even when the content on one side gets long enough to overflow into the center, unlike the grid answer from 2019.
The one thing this solution doesn't do is show an ellipsis or hide the extra content in the center box, as described in the question.
section {
display: grid;
grid-template-columns: 1fr auto 1fr;
}
section > *:last-child {
white-space: nowrap;
text-align: right;
}
/* not essential; just for demo purposes */
section {
background-color: #eee;
font-family: helvetica, arial;
font-size: 10pt;
padding: 4px;
}
section > * {
border: 1px solid #bbb;
padding: 2px;
}
<section>
<div>left</div>
<div>center</div>
<div>right side is longer</div>
</section>
<section>
<div>left</div>
<div>center</div>
<div>right side is much, much longer</div>
</section>
<section>
<div>left</div>
<div>center</div>
<div>right side is much, much longer, super long in fact</div>
</section>
Instead of defaulting to using flexbox, using grid solves it in 2 lines of CSS without additional markup inside the top level children.
HTML:
<header class="header">
<div class="left">variable content</div>
<div class="middle">variable content</div>
<div class="right">variable content which happens to be very long</div>
</header>
CSS:
.header {
display: grid;
grid-template-columns: [first] 20% auto [last] 20%;
}
.middle {
/* use either */
margin: 0 auto;
/* or */
text-align: center;
}
Flexbox rocks but shouldn't be the answer for everything. In this case grid is clearly the cleanest option.
Even made a codepen for your testing pleasure:
https://codepen.io/anon/pen/mooQOV
You can do this like so:
.bar {
display: flex;
background: #B0BEC5;
}
.l {
width: 50%;
flex-shrink: 1;
display: flex;
}
.l-content {
background: #9C27B0;
}
.m {
flex-shrink: 0;
}
.m-content {
text-align: center;
background: #2196F3;
}
.r {
width: 50%;
flex-shrink: 1;
display: flex;
flex-direction: row-reverse;
}
.r-content {
background: #E91E63;
}
<div class="bar">
<div class="l">
<div class="l-content">This is really long content. More content. So much content.</div>
</div>
<div class="m">
<div class="m-content">This will always be in the center.</div>
</div>
<div class="r">
<div class="r-content">This is short.</div>
</div>
</div>
Here is another way to do it, using display: flex in the parents and childs:
.Layout{
display: flex;
justify-content: center;
}
.Left{
display: flex;
justify-content: flex-start;
width: 100%;
}
.Right{
display: flex;
justify-content: flex-end;
width: 100%;
}
<div class = 'Layout'>
<div class = 'Left'>I'm on the left</div>
<div class = 'Mid'>Centered</div>
<div class = 'Right'>I'm on the right</div>
</div>
A slightly more robust grid solution looks like this:
.container {
overflow: hidden;
border-radius: 2px;
padding: 4px;
background: orange;
display: grid;
grid-template-columns: minmax(max-content, 1fr) auto minmax(max-content, 1fr);
}
.item > div {
display: inline-block;
padding: 6px;
border-radius: 2px;
background: teal;
}
.item:last-child > div {
float: right;
}
<div class="container">
<div class="item"><div contenteditable>edit the text to test the layout</div></div>
<div class="item"><div contenteditable>just click me and</div></div>
<div class="item"><div contenteditable>edit</div></div>
</div>
And here you can see it in Codepen: https://codepen.io/benshope2234/pen/qBmZJWN
I wanted the exact result shown in the question, I combined answers from gamliela and Erik Martín Jordán and it works best for me.
.parent {
display: flex;
justify-content: space-between;
}
.left, .right {
flex-grow: 1;
flex-basis: 0;
}
.right {
display: flex;
justify-content: flex-end;
}
you can also use this simple way to reach exact center alignment for middle element :
.container {
display: flex;
justify-content: space-between;
}
.container .sibling {
display: flex;
align-items: center;
height: 50px;
background-color: gray;
}
.container .sibling:first-child {
width: 50%;
display: flex;
justify-content: space-between;
}
.container .sibling:last-child {
justify-content: flex-end;
width: 50%;
box-sizing: border-box;
padding-left: 100px; /* .center's width divided by 2 */
}
.container .sibling:last-child .content {
text-align: right;
}
.container .sibling .center {
height: 100%;
width: 200px;
background-color: lightgreen;
transform: translateX(50%);
}
codepen: https://codepen.io/ErAz7/pen/mdeBKLG
Althought I might be late on this one, all those solutions seems complicated and may not work depending on the cases you're facing.
Very simply, just wrap the component you want to center with position : absolute, while letting the other two with justify-content : space-between, like so :
CSS:
.container {
display: flex;
justify-content: space-between;
align-items: center;
background-color: lightgray;
}
.middle {
position: absolute;
margin-left: auto;
margin-right: auto;
/* You should adapt percentages here if you have a background ; else, left: 0 and right: 0 should do the trick */
left: 40%;
right: 40%;
text-align: center;
}
/* non-essential, copied from #Brian Morearty answer */
.element {
border: 1px solid #ccc;
background-color: lightgreen;
}
p {
margin: 5px;
padding: 5px;
}
<div class="container">
<p class="element">First block</p>
<p class="middle element">Middle block</p>
<p class="element">Third THICC blockkkkkkkkk</p>
</div>
Michael Benjamin has a decent answer but there is no reason it can't / shouldn't be simplified further:
.container {
display: flex;
}
.box {
flex: 1;
display: flex;
justify-content: center;
}
.box:first-child { justify-content: left; }
.box:last-child { justify-content: right; }
And html
<div class="container">
<div class="box">short text</div>
<div class="box">centered tex</div>
<div class="box">loooooooooooooooong text</div>
</div>