::before/::after + flexbox in MDN
This was implemented in bug 867454. Not implementing it was a mistake, as comment #0 tells.
The spec says:
The contents of a flex container consists of zero or more flex items: each in-flow child of a flex container becomes a flex item, and each contiguous run of text that is directly contained inside a flex container is wrapped in an anonymous flex item.
And that does include ::before
/::after
pseudo elements (at least the mozilla folks interpret it this way now, and I'd concur).
"Firefox 23 for developers" also features this information, explicitly referring to ::before
and ::after
as "in-flow".
In-flow ::after and ::before pseudo-elements are now flex items (bug 867454).
Is there any polyfill for current CSS Flexible Box Layout Module as per W3C CR (display: flex etc.)?
There's currently no polyfill that implements the W3C Candidate Recommendation.
The author of flexie.js mentioned some time ago that he was working on updating flexie.js but there has not been anything published since then. So it's hard to say if or when it will actually materialize.
CSS style for ::after with plus(+) selector
This isn't going to be possible in pure CSS.
In the accepted version of this answer I was entirely wrong about the reason for this! I've always assumed that the ::after
pseudo-element was placed after the element -- hence, y'know, the name -- but apparently I've been wrong about that for years; the ::before
and ::after
pseudo-elements are actually first and last children of the main element. Many thanks to @MRNafisiA for pointing this out in comments!
Except not really, because they're still not treated as part of the DOM. Sibling selectors can not be used to match pseudo-elements, and they will not be included in any other selectors that would normally match child elements (first-child
, last-child
, etc).
So the closest you can get is probably input:checked::after {}
(though some extra layout fiddling is necessary to get past the sort-of-zero-width checkbox.)
label {display: block}
input::after {
content: "A";
color: red;
margin-left: 1.2em;
}
input:checked::after {
color: blue
}
<label><input type="checkbox"></label>
<label><input type="checkbox"></label>
<label><input type="checkbox"></label>
Why is ::before pseudo element taking up room in flexbox?
The first thing to know is that pseudo elements applied to a flex container become flex items (MDN).
Therefore, your container (.test
) has three flex items, with the ::before
being just another sibling.
Is there a way to tell flex to ignore
::before
&::after
?
Yes. Remove the pseudo element from the document flow. Use absolute positioning.
I would expect the width here to be 100% (200px).
Once the ::before
is removed from the document flow, it will be free to expand across the container.
.test { height: 200px; width: 200px; display: flex; flex-direction: row-reverse; position: relative; /* new */}
.test::before { position: absolute; /* new */ background-color: yellow; content: ""; height: 100%; width: 100%; opacity: 0.04;}
.first { background-color: green;}
.second { background-color: grey; flex: 1;}
body { background-color: purple;}
<div class="test"> <div class="first"> </div> <div class="second"> </div></div>
Better way to set distance between flexbox items
- Flexbox doesn't have collapsing margins.
- Flexbox doesn't have anything akin to
border-spacing
for tables (edit: CSS propertygap
fulfills this role in newer browsers, Can I use)
Therefore achieving what you are asking for is a bit more difficult.
In my experience, the "cleanest" way that doesn't use :first-child
/:last-child
and works without any modification on flex-wrap:wrap
is to set padding:5px
on the container and margin:5px
on the children. That will produce a 10px
gap between each child and between each child and their parent.
Demo
.upper {
margin: 30px;
display: flex;
flex-direction: row;
width: 300px;
height: 80px;
border: 1px red solid;
padding: 5px; /* this */
}
.upper > div {
flex: 1 1 auto;
border: 1px red solid;
text-align: center;
margin: 5px; /* and that, will result in a 10px gap */
}
.upper.mc /* multicol test */ {
flex-direction: column;
flex-wrap: wrap;
width: 200px;
height: 200px;
}
<div class="upper">
<div>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa<br/>aaa</div>
<div>aaa<br/>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa</div>
</div>
<div class="upper mc">
<div>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa<br/>aaa</div>
<div>aaa<br/>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa</div>
</div>
How to set a fixed width column with CSS flexbox
You should use the flex
or flex-basis
property rather than width
. Read more on MDN.
.flexbox .red {
flex: 0 0 25em;
}
The flex
CSS property is a shorthand property specifying the ability of a flex item to alter its dimensions to fill available space. It contains:
flex-grow: 0; /* do not grow - initial value: 0 */
flex-shrink: 0; /* do not shrink - initial value: 1 */
flex-basis: 25em; /* width/height - initial value: auto */
A simple demo shows how to set the first column to 50px
fixed width.
.flexbox { display: flex;}.red { background: red; flex: 0 0 50px;}.green { background: green; flex: 1;}.blue { background: blue; flex: 1;}
<div class="flexbox"> <div class="red">1</div> <div class="green">2</div> <div class="blue">3</div></div>
In CSS Flexbox, why are there no justify-items and justify-self properties?
Methods for Aligning Flex Items along the Main Axis
As stated in the question:
To align flex items along the main axis there is one property:
justify-content
To align flex items along the cross axis there are three properties:
align-content
,align-items
andalign-self
.
The question then asks:
Why are there no
justify-items
andjustify-self
properties?
One answer may be: Because they're not necessary.
The flexbox specification provides two methods for aligning flex items along the main axis:
- The
justify-content
keyword property, and auto
margins
justify-content
The justify-content
property aligns flex items along the main axis of the flex container.
It is applied to the flex container but only affects flex items.
There are five alignment options:
flex-start
~ Flex items are packed toward the start of the line.flex-end
~ Flex items are packed toward the end of the line.center
~ Flex items are packed toward the center of the line.space-between
~ Flex items are evenly spaced, with the first item aligned to one edge of the container and the last item aligned to the opposite edge. The edges used by the first and last items depends onflex-direction
and writing mode (ltr
orrtl
).space-around
~ Same asspace-between
except with half-size spaces on both ends.
Auto Margins
With auto
margins, flex items can be centered, spaced away or packed into sub-groups.
Unlike justify-content
, which is applied to the flex container, auto
margins go on flex items.
They work by consuming all free space in the specified direction.
Align group of flex items to the right, but first item to the left
Scenario from the question:
making a group of flex items align-right (
justify-content: flex-end
)
but have the first item align left (justify-self: flex-start
)Consider a header section with a group of nav items and a logo. With
justify-self
the logo could be aligned left while the nav items stay
far right, and the whole thing adjusts smoothly ("flexes") to
different screen sizes.
Other useful scenarios:
Place a flex item in the corner
Scenario from the question:
- placing a flex item in a corner
.box { align-self: flex-end; justify-self: flex-end; }
Center a flex item vertically and horizontally
margin: auto
is an alternative to justify-content: center
and align-items: center
.
Instead of this code on the flex container:
.container {
justify-content: center;
align-items: center;
}
You can use this on the flex item:
.box56 {
margin: auto;
}
This alternative is useful when centering a flex item that overflows the container.
Center a flex item, and center a second flex item between the first and the edge
A flex container aligns flex items by distributing free space.
Hence, in order to create equal balance, so that a middle item can be centered in the container with a single item alongside, a counterbalance must be introduced.
In the examples below, invisible third flex items (boxes 61 & 68) are introduced to balance out the "real" items (box 63 & 66).
Of course, this method is nothing great in terms of semantics.
Alternatively, you can use a pseudo-element instead of an actual DOM element. Or you can use absolute positioning. All three methods are covered here: Center and bottom-align flex items
NOTE: The examples above will only work – in terms of true centering – when the outermost items are equal height/width. When flex items are different lengths, see next example.
Center a flex item when adjacent items vary in size
Scenario from the question:
in a row of three flex items, affix the middle item to the center of the container (
justify-content: center
) and align the adjacent
items to the container edges (justify-self: flex-start
and
justify-self: flex-end
).Note that values
space-around
andspace-between
onjustify-content
property will not keep the middle item centered in relation to the container if the adjacent items have different widths (see demo).
As noted, unless all flex items are of equal width or height (depending on flex-direction
), the middle item cannot be truly centered. This problem makes a strong case for a justify-self
property (designed to handle the task, of course).
#container { display: flex; justify-content: space-between; background-color: lightyellow;}.box { height: 50px; width: 75px; background-color: springgreen;}.box1 { width: 100px;}.box3 { width: 200px;}#center { text-align: center; margin-bottom: 5px;}#center > span { background-color: aqua; padding: 2px;}
<div id="center"> <span>TRUE CENTER</span></div>
<div id="container"> <div class="box box1"></div> <div class="box box2"></div> <div class="box box3"></div></div>
<p>The middle box will be truly centered only if adjacent boxes are equal width.</p>
Related Topics
How Often Is the Default Font Size in the Browser Not 16Px
Css/Webkit: Background Images for Table Row
What Does an * (Star) Mean in Front of a CSS Declaration
Cypress Testing Pseudo CSS Class :Before
CSS - Apply Opacity to Element But Not to Text Within the Element
Rails Images and Assets Not Being Loaded Properly
How to Center Text Inside an Svg Path
Css3 Hover/Tap Doesn't Work in Mobile Browsers
A:Visited Doesn't Work in Mozilla Firefox
Add a State Property to an Inline Style in React
Cross-Browser 'Cursor:Pointer'
Imitate Photoshop Blend Effects Like Multiply, Overlay etc
Css: Circle with Four Colors and Only One Div
ASP.NET MVC 5 - Stylebundle Cdnfallbackexpression Questions
Overriding Bootstrap Variables in Rails with Bootstrap-Sass Gem