Suppose that I have 12 elements with width: 25%; float: left; it'll be like this:
---------
|a|b|c|d|
---------
|e|f|g|h|
---------
|i|j|k|l|
---------
I have added overflow: visible; to these divs and a div inside each of these divs which will expand on hover. It's working alright. The problem is I want it to expand to right for all the divs except d, h and l for which it should expand to left. I wonder if it's possible to do it without javascript. Is there any css selector that can select d, h and l (consider that it's responsive and it's not always 4 divs per row. It may be 10 or 2 rows per row.) Or maybe there's another solution for this selective expansion problem without above mentioned selector.
You have a flexbox solution to this. Choose better values to achive the desired output.
ul{
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
align-content: space-around;
}
li{
padding: 20px;
margin: 5px;
background-color: #8056ff;
color: white;
text-align: center;
flex-basis: 40px;
transition: flex-basis 1s;
}
li:hover{
flex-basis: 100px;
}
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
<li>f</li>
<li>g</li>
<li>h</li>
<li>i</li>
<li>j</li>
<li>k</li>
<li>l</li>
</ul>
Related
https://codepen.io/fluark/pen/VwxGawr
.header {
display: flex;
font-family: monospace;
background: papayawhip;
align-items: center;
justify-content: space-between;
margin-left: auto;
}
ul {
display: flex;
background: papayawhip;
gap: 10em;
list-style-type: none;
flex-direction: row;
margin: 0;
padding: 0;
}
Desired Outcome
Visually my header looks fairly close to the desired outcome, however when I shrink down the page, the right links/ul (child items) spill out of the header (parent).
I am pretty sure this is a matter of not having the proper flex settings. Is the error maybe in the flex-basis? Or potentially the relationship between flex-shrink and flex-basis?
I have looked up flex settings and tried separately adding “flex: 1;” on both the parent .header as well as the div.right-links and ul.
I have also tried creating a separate div... div.header and then adding flex: 1 to that with the intention of making it so the parent is able to grow when the window is resized. That didn't seem to do anything.
I am a little confused because with “display: flex” on both the .header element and the ul, that means the flex-shrink is 1 (flex = 0, 1, auto), so shouldn’t the links be shrinking when the parent element is resized, not spilling out?
I’m looking for some guidance/talk throughs because I am at the point where I am just adding to the code to “see what happens”, and that’s when I know I need help.
Thanks in advance!
The ul element has a default padding of 26px and when you narrow the viewport it's that padding that's pushing the div to the right. If you set padding-left: to 0 then it removes it. I've also set the li display type to inline-block so that the padding on the a element does not overflow the logo on small screen sizes. At really small screen sizes (below 612px or so), the logo, a tags, gaps and padding will all be the lowest they can be so if you want to restyle it any further then I'd use a media query. See below
.header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
font-family: monospace;
background: papayawhip;
padding: 5px;
}
.logo {
font-size: 48px;
font-weight: 900;
color: tomato;
background: white;
padding: 4px 32px;
}
ul {
padding-left: 0;
display: flex;
gap: 1em;
flex-direction: row;
/* this removes the dots on the list items*/
list-style-type: none;
}
li {
display: inline-block;
}
a {
font-size: 22px;
background: white;
/* this removes the line under the links */
padding: 8px;
text-decoration: none;
}
<div class="header">
<div class="left-links">
<ul>
<li>ONE</li>
<li>TWO</li>
<li>THREE</li>
</ul>
</div>
<div class="logo">LOGO</div>
<div class="right-links">
<ul>
<li>FOUR</li>
<li>FIVE</li>
<li>SIX</li>
</ul>
</div>
</div>
I would like to have A B and C aligned in the middle.
How can I get D to go completely to the right?
BEFORE:
AFTER:
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
li:last-child {
background: #ddd;
/* magic to throw to the right*/
}
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
https://jsfiddle.net/z44p7bsx/
Below are five options for achieving this layout:
CSS Positioning
Flexbox with Invisible DOM Element
Flexbox with Invisible Pseudo-Element
Flexbox with flex: 1
CSS Grid Layout
Method #1: CSS Positioning Properties
Apply position: relative to the flex container.
Apply position: absolute to item D.
Now this item is absolutely positioned within the flex container.
More specifically, item D is removed from the document flow but stays within the bounds of the nearest positioned ancestor.
Use the CSS offset properties top and right to move this element into position.
li:last-child {
position: absolute;
top: 0;
right: 0;
background: #ddd;
}
ul {
position: relative;
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p {
text-align: center;
margin-top: 0;
}
span {
background-color: aqua;
}
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
One caveat to this method is that some browsers may not completely remove an absolutely-positioned flex item from the normal flow. This changes the alignment in a non-standard, unexpected way. More details: Absolutely positioned flex item is not removed from the normal flow in IE11
Method #2: Flex Auto Margins & Invisible Flex Item (DOM element)
With a combination of auto margins and a new, invisible flex item the layout can be achieved.
The new flex item is identical to item D and is placed at the opposite end (the left edge).
More specifically, because flex alignment is based on the distribution of free space, the new item is a necessary counterbalance to keep the three middle boxes horizontally centered. The new item must be the same width as the existing D item, or the middle boxes won't be precisely centered.
The new item is removed from view with visibility: hidden.
In short:
Create a duplicate of the D element.
Place it at the beginning of the list.
Use flex auto margins to keep A, B and C centered, with both D elements creating equal balance from both ends.
Apply visibility: hidden to the duplicate D
li:first-child {
margin-right: auto;
visibility: hidden;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>D</li><!-- new; invisible spacer item -->
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
Method #3: Flex Auto Margins & Invisible Flex Item (pseudo-element)
This method is similar to #2, except it's cleaner semantically and the width of D must be known.
Create a pseudo-element with the same width as D.
Place it at the start of the container with ::before.
Use flex auto margins to keep A, B and C perfectly centered, with the pseudo and D elements creating equal balance from both ends.
ul::before {
content:"D";
margin: 1px auto 1px 1px;
visibility: hidden;
padding: 5px;
background: #ddd;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
Method #4: Add flex: 1 to left and right items
Starting with Method #2 or #3 above, instead of worrying about equal width for the left and right items to maintain equal balance, just give each one flex: 1. This will force them both to consume available space, thus centering the middle item.
You can then add display: flex to individual items in order to align their content.
NOTE about using this method with min-height: Currently in Chrome, Firefox, Edge and possibly other browsers, the shorthand rule flex: 1 breaks down to this:
flex-grow: 1
flex-shrink: 1
flex-basis: 0%
That percentage unit (%) on flex-basis causes this method to break when min-height is used on the container. This is because, as a general rule, percentage heights on the children require an explicit height property setting on the parent.
This is an old CSS rule dating back to 1998 (CSS Level 2) which is still in effect in many browsers to some degree or another. For complete details see here and here.
Here's an illustration of the problem posted in the comments by user2651804:
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container>div {
background: orange;
margin: 5px;
}
#flex-container>div:first-child {
flex: 1;
}
#flex-container::after {
content: "";
flex: 1;
}
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
The solution is to not use the percentage unit. Try px or just nothing at all (which is what the spec actually recommends, despite the fact that at least some of the major browsers have appended a percentage unit for whatever reason).
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container > div {
background: orange;
margin: 5px;
}
/* OVERRIDE THE BROWSER SETTING IN THE FLEX PROPERTY */
#flex-container > div:first-child {
flex: 1;
flex-basis: 0;
}
#flex-container::after {
content: "";
flex: 1;
flex-basis: 0;
}
/* OR... JUST SET THE LONG-HAND PROPERTIES INDIVIDUALLY
#flex-container > div:first-child {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
}
#flex-container::after {
content: "";
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
}
*/
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
Method #5: CSS Grid Layout
This may be the cleanest and most efficient method. There is no need for absolute positioning, fake elements or other hackery.
Simply create a grid with multiple columns. Then position your items in the middle and end columns. Basically, just leave the first column empty.
ul {
display: grid;
grid-template-columns: 1fr repeat(3, auto) 1fr;
grid-column-gap: 5px;
justify-items: center;
}
li:nth-child(1) { grid-column-start: 2; }
li:nth-child(4) { margin-left: auto; }
/* for demo only */
ul { padding: 0; margin: 0; list-style: none; }
li { padding: 5px; background: #aaa; }
p { text-align: center; }
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>| true center |</span></p>
The simplest solution will be to justify-content center to the parent container and giving margin-left auto to first and last child element.
ul {
display:flex;
justify-content:center;
}
.a,.d {
margin-left:auto;
}
<ul>
<li class="a">A</li>
<li>B</li>
<li>C</li>
<li class="d">D</li>
</ul>
Most easy way
.box{
display:flex;
justify-content:center;
}
.item1{
flex:1;
display: flex;
justify-content: center;
transform: translateX(10px);/*D element Width[if needed]*/
}
<div class="box">
<div class="item1">
<div>A</div>
<div>B</div>
<div>C</div>
</div>
<div class="item2">D</div>
</div>
Using the display:grid approach, you can simply put all of the ul children into the same cell and then set justify-self:
.ul {
display: grid;
}
.ul > * {
grid-column-start: 1;
grid-row-start: 1;
justify-self:center;
}
.ul > *:last-child {
justify-self: right;
}
/* Make Fancy */
.li {
display:inline-block;
margin: 1px;
padding: 5px;
background: #bbb;
}
<div class='ul'>
<span>
<span class='li'>A</span>
<span class='li'>B</span>
<span class='li'>C</span>
</span>
<span class='li'>D</span>
</div>
Inspired by the Method #5: CSS Grid Layout of #Michal Benjamin's solution and because I'm using Tailwind and as of now still don't have access to all the grid options by default. This seems to work:
ul {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
li {
align-self: center;
}
li:nth-child(1) {
justify-content: flex-start; /* OR margin-right: auto */
}
li:nth-child(3) {
justify-content: flex-end; /* OR margin-left:auto */
}
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
PS: Not sure if mixing up flex and grid like this is a good idea!
If you want to make it aligned, you can simply attach an empty span and split the three child spans into them.
The easiest way:
.wrap {
display:flex;
}
.full-width {
width: 100%;
}
.centered {
display: flex;
justify-content:center;
}
.btn {
display: flex;
justify-content: end;
}
<div class="wrap">
<div class="full-width"></div>
<div class="full-width centered">
<div>A</div>
<div>B</div>
<div>C</div>
</div>
<div class="full-width btn">D</div>
</div>
Very clear question. I couldn't help but post the answer after a few hours of digging. We Could of solved this with tables, table-cell, absolute positions, transforms but we just had to do it with flexbox :)
.parent {
display: flex;
justify-content: flex-end;
}
.center {
margin: auto;
}
http://codepen.io/rgfx/pen/BLorgd
The accepted answer can be changed a bit because you can use grid template areas and do it without fake element
grid-template-areas '. b c'
grid-template-columns: 1fr 1fr 1fr
I expanded on Michael_B's answer
.center-flex__2-of-3 > :nth-child(1), .center-flex__2-of-3 > :nth-child(3) {
flex: 1;
}
.center-flex__2-of-3 > :nth-child(1) {
justify-content: flex-start;
}
.center-flex__2-of-3 > :nth-child(3) {
justify-content: flex-end;
}
.center-flex__1-of-2 > :nth-child(1) {
margin: auto;
}
.center-flex__1-of-2 > :nth-child(2) {
flex: 1;
justify-content: flex-end;
}
.center-flex__2-of-2 > :nth-child(1) {
flex: 1;
justify-content: flex-start;
}
.center-flex__2-of-2 > :nth-child(2) {
margin: auto;
}
.center-flex__1-of-2:before, .center-flex__1-of-1:before {
content: '';
flex: 1;
}
.center-flex__1-of-1:after, .center-flex__2-of-2:after {
content: '';
flex: 1;
}
[class*=center-flex] {
display: flex;
list-style: none;
margin: 0;
padding: 0;
border: 10px solid rgba(0, 0, 0, 0.1);
}
[class*=center-flex] > * {
display: flex;
}
li {
padding: 3px 5px;
}
2 of 3
<ul class="center-flex__2-of-3">
<span>
<li>Accusamus</li>
<li>Porro</li>
</span>
<span>
<li>Center</li>
<li>this</li>
</span>
<span>
<li>Accusamus</li>
<li>Porro</li>
<li>Culpa</li>
<li>Sit</li>
</span>
</ul>
<br><br>
1 of 2
<ul class="akex center-flex__1-of-2">
<span>
<li>Center</li>
<li>this</li>
</span>
<span>
<li>Accusamus</li>
<li>Porro</li>
<li>Culpa</li>
<li>Sit</li>
</span>
</ul>
<br><br>
2 of 2
<ul class="akex center-flex__2-of-2">
<span>
<li>Accusamus</li>
<li>Porro</li>
<li>Culpa</li>
<li>Sit</li>
</span>
<span>
<li>Center</li>
<li>this</li>
</span>
</ul>
<br><br>
1 of 1
<ul class="center-flex__1-of-1">
<span>
<li>Center</li>
<li>this</li>
</span>
</ul>
Here with the help of SASS as a codepen
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
li:last-child {
background: #ddd;
position:absolute;
right:10px;
}
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
I would like to have A B and C aligned in the middle.
How can I get D to go completely to the right?
BEFORE:
AFTER:
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
li:last-child {
background: #ddd;
/* magic to throw to the right*/
}
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
https://jsfiddle.net/z44p7bsx/
Below are five options for achieving this layout:
CSS Positioning
Flexbox with Invisible DOM Element
Flexbox with Invisible Pseudo-Element
Flexbox with flex: 1
CSS Grid Layout
Method #1: CSS Positioning Properties
Apply position: relative to the flex container.
Apply position: absolute to item D.
Now this item is absolutely positioned within the flex container.
More specifically, item D is removed from the document flow but stays within the bounds of the nearest positioned ancestor.
Use the CSS offset properties top and right to move this element into position.
li:last-child {
position: absolute;
top: 0;
right: 0;
background: #ddd;
}
ul {
position: relative;
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p {
text-align: center;
margin-top: 0;
}
span {
background-color: aqua;
}
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
One caveat to this method is that some browsers may not completely remove an absolutely-positioned flex item from the normal flow. This changes the alignment in a non-standard, unexpected way. More details: Absolutely positioned flex item is not removed from the normal flow in IE11
Method #2: Flex Auto Margins & Invisible Flex Item (DOM element)
With a combination of auto margins and a new, invisible flex item the layout can be achieved.
The new flex item is identical to item D and is placed at the opposite end (the left edge).
More specifically, because flex alignment is based on the distribution of free space, the new item is a necessary counterbalance to keep the three middle boxes horizontally centered. The new item must be the same width as the existing D item, or the middle boxes won't be precisely centered.
The new item is removed from view with visibility: hidden.
In short:
Create a duplicate of the D element.
Place it at the beginning of the list.
Use flex auto margins to keep A, B and C centered, with both D elements creating equal balance from both ends.
Apply visibility: hidden to the duplicate D
li:first-child {
margin-right: auto;
visibility: hidden;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>D</li><!-- new; invisible spacer item -->
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
Method #3: Flex Auto Margins & Invisible Flex Item (pseudo-element)
This method is similar to #2, except it's cleaner semantically and the width of D must be known.
Create a pseudo-element with the same width as D.
Place it at the start of the container with ::before.
Use flex auto margins to keep A, B and C perfectly centered, with the pseudo and D elements creating equal balance from both ends.
ul::before {
content:"D";
margin: 1px auto 1px 1px;
visibility: hidden;
padding: 5px;
background: #ddd;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
Method #4: Add flex: 1 to left and right items
Starting with Method #2 or #3 above, instead of worrying about equal width for the left and right items to maintain equal balance, just give each one flex: 1. This will force them both to consume available space, thus centering the middle item.
You can then add display: flex to individual items in order to align their content.
NOTE about using this method with min-height: Currently in Chrome, Firefox, Edge and possibly other browsers, the shorthand rule flex: 1 breaks down to this:
flex-grow: 1
flex-shrink: 1
flex-basis: 0%
That percentage unit (%) on flex-basis causes this method to break when min-height is used on the container. This is because, as a general rule, percentage heights on the children require an explicit height property setting on the parent.
This is an old CSS rule dating back to 1998 (CSS Level 2) which is still in effect in many browsers to some degree or another. For complete details see here and here.
Here's an illustration of the problem posted in the comments by user2651804:
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container>div {
background: orange;
margin: 5px;
}
#flex-container>div:first-child {
flex: 1;
}
#flex-container::after {
content: "";
flex: 1;
}
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
The solution is to not use the percentage unit. Try px or just nothing at all (which is what the spec actually recommends, despite the fact that at least some of the major browsers have appended a percentage unit for whatever reason).
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container > div {
background: orange;
margin: 5px;
}
/* OVERRIDE THE BROWSER SETTING IN THE FLEX PROPERTY */
#flex-container > div:first-child {
flex: 1;
flex-basis: 0;
}
#flex-container::after {
content: "";
flex: 1;
flex-basis: 0;
}
/* OR... JUST SET THE LONG-HAND PROPERTIES INDIVIDUALLY
#flex-container > div:first-child {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
}
#flex-container::after {
content: "";
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
}
*/
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
Method #5: CSS Grid Layout
This may be the cleanest and most efficient method. There is no need for absolute positioning, fake elements or other hackery.
Simply create a grid with multiple columns. Then position your items in the middle and end columns. Basically, just leave the first column empty.
ul {
display: grid;
grid-template-columns: 1fr repeat(3, auto) 1fr;
grid-column-gap: 5px;
justify-items: center;
}
li:nth-child(1) { grid-column-start: 2; }
li:nth-child(4) { margin-left: auto; }
/* for demo only */
ul { padding: 0; margin: 0; list-style: none; }
li { padding: 5px; background: #aaa; }
p { text-align: center; }
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>| true center |</span></p>
The simplest solution will be to justify-content center to the parent container and giving margin-left auto to first and last child element.
ul {
display:flex;
justify-content:center;
}
.a,.d {
margin-left:auto;
}
<ul>
<li class="a">A</li>
<li>B</li>
<li>C</li>
<li class="d">D</li>
</ul>
Most easy way
.box{
display:flex;
justify-content:center;
}
.item1{
flex:1;
display: flex;
justify-content: center;
transform: translateX(10px);/*D element Width[if needed]*/
}
<div class="box">
<div class="item1">
<div>A</div>
<div>B</div>
<div>C</div>
</div>
<div class="item2">D</div>
</div>
Using the display:grid approach, you can simply put all of the ul children into the same cell and then set justify-self:
.ul {
display: grid;
}
.ul > * {
grid-column-start: 1;
grid-row-start: 1;
justify-self:center;
}
.ul > *:last-child {
justify-self: right;
}
/* Make Fancy */
.li {
display:inline-block;
margin: 1px;
padding: 5px;
background: #bbb;
}
<div class='ul'>
<span>
<span class='li'>A</span>
<span class='li'>B</span>
<span class='li'>C</span>
</span>
<span class='li'>D</span>
</div>
Inspired by the Method #5: CSS Grid Layout of #Michal Benjamin's solution and because I'm using Tailwind and as of now still don't have access to all the grid options by default. This seems to work:
ul {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
li {
align-self: center;
}
li:nth-child(1) {
justify-content: flex-start; /* OR margin-right: auto */
}
li:nth-child(3) {
justify-content: flex-end; /* OR margin-left:auto */
}
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
PS: Not sure if mixing up flex and grid like this is a good idea!
If you want to make it aligned, you can simply attach an empty span and split the three child spans into them.
The easiest way:
.wrap {
display:flex;
}
.full-width {
width: 100%;
}
.centered {
display: flex;
justify-content:center;
}
.btn {
display: flex;
justify-content: end;
}
<div class="wrap">
<div class="full-width"></div>
<div class="full-width centered">
<div>A</div>
<div>B</div>
<div>C</div>
</div>
<div class="full-width btn">D</div>
</div>
Very clear question. I couldn't help but post the answer after a few hours of digging. We Could of solved this with tables, table-cell, absolute positions, transforms but we just had to do it with flexbox :)
.parent {
display: flex;
justify-content: flex-end;
}
.center {
margin: auto;
}
http://codepen.io/rgfx/pen/BLorgd
The accepted answer can be changed a bit because you can use grid template areas and do it without fake element
grid-template-areas '. b c'
grid-template-columns: 1fr 1fr 1fr
I expanded on Michael_B's answer
.center-flex__2-of-3 > :nth-child(1), .center-flex__2-of-3 > :nth-child(3) {
flex: 1;
}
.center-flex__2-of-3 > :nth-child(1) {
justify-content: flex-start;
}
.center-flex__2-of-3 > :nth-child(3) {
justify-content: flex-end;
}
.center-flex__1-of-2 > :nth-child(1) {
margin: auto;
}
.center-flex__1-of-2 > :nth-child(2) {
flex: 1;
justify-content: flex-end;
}
.center-flex__2-of-2 > :nth-child(1) {
flex: 1;
justify-content: flex-start;
}
.center-flex__2-of-2 > :nth-child(2) {
margin: auto;
}
.center-flex__1-of-2:before, .center-flex__1-of-1:before {
content: '';
flex: 1;
}
.center-flex__1-of-1:after, .center-flex__2-of-2:after {
content: '';
flex: 1;
}
[class*=center-flex] {
display: flex;
list-style: none;
margin: 0;
padding: 0;
border: 10px solid rgba(0, 0, 0, 0.1);
}
[class*=center-flex] > * {
display: flex;
}
li {
padding: 3px 5px;
}
2 of 3
<ul class="center-flex__2-of-3">
<span>
<li>Accusamus</li>
<li>Porro</li>
</span>
<span>
<li>Center</li>
<li>this</li>
</span>
<span>
<li>Accusamus</li>
<li>Porro</li>
<li>Culpa</li>
<li>Sit</li>
</span>
</ul>
<br><br>
1 of 2
<ul class="akex center-flex__1-of-2">
<span>
<li>Center</li>
<li>this</li>
</span>
<span>
<li>Accusamus</li>
<li>Porro</li>
<li>Culpa</li>
<li>Sit</li>
</span>
</ul>
<br><br>
2 of 2
<ul class="akex center-flex__2-of-2">
<span>
<li>Accusamus</li>
<li>Porro</li>
<li>Culpa</li>
<li>Sit</li>
</span>
<span>
<li>Center</li>
<li>this</li>
</span>
</ul>
<br><br>
1 of 1
<ul class="center-flex__1-of-1">
<span>
<li>Center</li>
<li>this</li>
</span>
</ul>
Here with the help of SASS as a codepen
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
li:last-child {
background: #ddd;
position:absolute;
right:10px;
}
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
This question already has answers here:
In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
(6 answers)
Center one and right/left align other flexbox element
(11 answers)
Closed 1 year ago.
I would like to ask for a little help. I have the following code, and I would like to move to the right the number "4" box. I tried with "justify-self" but it doesn't move at all.
What would be the reason of that?
ul {
display: flex;
flex-direction: row;
justify-content: center;
background-color: pink;
}
li {
padding: 20px;
margin: 30px;
background-color: grey;
list-style-type: none;
}
.rightBox {
justify-self: flex-end;
}
<div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li class="rightBox">4</li>
</ul>
</div>
justify-self doesn't apply to to flexbox. You can however use margin auto to push that last element to the right.
Keep in mind that previously your total margin between elements would be 60px. If the width of your container could shrink, you might want to double up the right margin on the adjacent element to preserve the total space.
Example:
ul {
display: flex;
flex-direction: row;
justify-content: center;
background-color: pink;
}
li {
padding: 20px;
margin: 30px;
background-color: grey;
list-style-type: none;
}
.rightBox {
margin-left: auto;
}
<div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li class="rightBox">4</li>
</ul>
</div>
I have been attempting to use flexbox for this, but any other css-only solution would be acceptable.
I want all items along a row to expand to the width of the largest item, so the result is identical widths. However, at the same time without the parent element expanding beyond the minimum size needed to accomplish this.
If you look at my Codepen example, altering the flex-grow value on <ul> elements will make this work for some of the demo examples, but not all.
http://codepen.io/MattyBalaam/pen/VepxWq
div {
display: flex;
justify-content: center;
}
ul {
display: flex;
justify-content: center;
padding: 0 0 2em;
flex-grow: 0.15;
}
li {
list-style: none;
margin: 2em;
flex: 1 1 0;
}
<div>
<ul>
<li>1</li>
<li>2</li>
<li>----3----</li>
</ul>
</div>