Tag Archives: items

Thumbnail

Everything You Need To Know About Alignment In Flexbox




Everything You Need To Know About Alignment In Flexbox

Rachel Andrew



In the first article of this series, I explained what happens when you declare display: flex on an element. This time we will take a look at the alignment properties, and how these work with Flexbox. If you have ever been confused about when to align and when to justify, I hope this article will make things clearer!

History Of Flexbox Alignment

For the entire history of CSS Layout, being able to properly align things on both axes seemed like it might truly be the hardest problem in web design. So the ability to properly align items and groups of items was for many of us the most exciting thing about Flexbox when it first started to show up in browsers. Alignment became as simple as two lines of CSS:

See the Pen Smashing Flexbox Series 2: center an item by Rachel Andrew (@rachelandrew) on CodePen.

The alignment properties that you might think of as the flexbox alignment properties are now fully defined in the Box Alignment Specification. This specification details how alignment works across the various layout contexts. This means that we can use the same alignment properties in CSS Grid as we use in Flexbox — and in future in other layout contexts, too. Therefore, any new alignment capability for flexbox will be detailed in the Box Alignment specification and not in a future level of Flexbox.

The Properties

Many people tell me that they struggle to remember whether to use properties which start with align- or those which start with justify- in flexbox. The thing to remember is that:

  • justify- performs main axis alignment. Alignment in the same direction as your flex-direction
  • align- performs cross-axis alignment. Alignment across the direction defined by flex-direction.

Thinking in terms of main axis and cross axis, rather than horizontal and vertical really helps here. It doesn’t matter which way the axis is physically.

Main Axis Alignment With justify-content

We will start with the main axis alignment. On the main axis, we align using the justify-content property. This property deals with all of our flex items as a group, and controls how space is distributed between them.

The initial value of justify-content is flex-start. This is why, when you declare display: flex all your flex items line up against the start of the flex line. If you have a flex-direction of row and are in a left to right language such as English, then the items will start on the left.


The items are all lined up in a row starting on the left


The items line up to the start (Large preview)

Note that the justify-content property can only do something if there is spare space to distribute. Therefore if you have a set of flex items which take up all of the space on the main axis, using justify-content will not change anything.


The container is filled with the items


There is no space to distribute (Large preview)

If we give justify-content a value of flex-end then all of the items will move to the end of the line. The spare space is now placed at the beginning.


The items are displayed in a row starting at the end of the container — on the right


The items line up at the end (Large preview)

We can do other things with that space. We could ask for it to be distributed between our flex items, by using justify-content: space-between. In this case, the first and last item will be flush with the ends of the container and all of the space shared equally between the items.


Items lined up left and right with equal space between them


The spare space is shared out between the items (Large preview)

We can ask that the space to be distributed around our flex items, using justify-content: space-around. In this case, the available space is shared out and placed on each side of the item.


Items spaced out with even amounts of space on each side


The items have space either side of them (Large preview)

A newer value of justify-content can be found in the Box Alignment specification; it doesn’t appear in the Flexbox spec. This value is space-evenly. In this case, the items will be evenly distributed in the container, and the extra space will be shared out between and either side of the items.


Items with equal amounts of space between and on each end


The items are spaced evenly (Large preview)

You can play with all of the values in the demo:

See the Pen Smashing Flexbox Series 2: justify-content with flex-direction: row by Rachel Andrew (@rachelandrew) on CodePen.

These values work in the same way if your flex-direction is column. You may not have extra space to distribute in a column however unless you add a height or block-size to the flex container as in this next demo.

See the Pen Smashing Flexbox Series 2: justify-content with flex-direction: column by Rachel Andrew (@rachelandrew) on CodePen.

Cross Axis Alignment with align-content

If you have added flex-wrap: wrap to your flex container, and have multiple flex lines then you can use align-content to align your flex lines on the cross axis. However, this will require that you have additional space on the cross axis. In the below demo, my cross axis is running in the block direction as a column, and I have set the height of the flex container to 60vh. As this is more than is needed to display my flex items I have spare space vertically in the container.

I can then use align-content with any of the values:

See the Pen Smashing Flexbox Series 2: align-content with flex-direction: row by Rachel Andrew (@rachelandrew) on CodePen.

If my flex-direction were column then align-content would work as in the following example.

See the Pen Smashing Flexbox Series 2: align-content with flex-direction: column by Rachel Andrew (@rachelandrew) on CodePen.

As with justify-content, we are working with the lines as a group and distributing the spare space.

The place-content Shorthand

In the Box Alignment, we find the shorthand place-content; using this property means you can set justify-content and align-content at once. The first value is for align-content, the second for justify-content. If you only set one value then both values are set to that value, therefore:

.container 
    place-content: space-between stretch;

Is the same as:

.container 
    align-content: space-between; 
    justify-content: stretch;

If we used:

.container 
    place-content: space-between;

This would be the same as:

.container 
    align-content: space-between; 
    justify-content: space-between;

Cross Axis Alignment With align-items

We now know that we can align our set of flex items or our flex lines as a group. However, there is another way we might wish to align our items and that is to align items in relationship to each other on the cross axis. Your flex container has a height. That height might be defined by the height of the tallest item as in this image.


The container height is tall enough to contain the items, the third item has more content


The container height is defined by the third item (Large preview)

It might instead be defined by adding a height to the flex container:


The container height is taller than needed to display the items


THe height is defined by a size on the flex container (Large preview)

The reason that flex items appear to stretch to the size of the tallest item is that the initial value of align-items is stretch. The items stretch on the cross access to become the size of the flex container in that direction.

Note that where align-items is concerned, if you have a multi-line flex container, each line acts like a new flex container. The tallest item in that line would define the size of all items in that line.

In addition to the initial value of stretch, you can give align-items a value of flex-start, in which case they align to the start of the container and no longer stretch to the height.


The items are aligned to the start


The items aligned to the start of the cross axis (Large preview)

The value flex-end moves them to the end of the container on the cross axis.


Items aligned to the end of the cross axis


The items aligned to the end of the cross axis (Large preview)

If you use a value of center the items all centre against each other:


The items are centered


Centering the items on the cross axis (Large preview)

We can also do baseline alignment. This ensures that the baselines of text line up, as opposed to aligning the boxes around the content.


The items are aligned so their baselines match


Aligning the baselines (Large preview)

You can try these values out in the demo:

See the Pen Smashing Flexbox Series 2: align-items by Rachel Andrew (@rachelandrew) on CodePen.

Individual Alignment With align-self

The align-items property means that you can set the alignment of all of the items at once. What this really does is set all of the align-self values on the individual flex items as a group. You can also use the align-self property on any individual flex item to align it inside the flex line and against the other flex items.

In the following example, I have used align-items on the container to set the alignment for the group to center, but also used align-self on the first and last items to change their alignment value.

See the Pen Smashing Flexbox Series 2: align-self by Rachel Andrew (@rachelandrew) on CodePen.

Why Is There No justify-self?

A common question is why it is not possible to align one item or a group of the items on the main axis. Why is there no -self property for main axis alignment in Flexbox? If you think about justify-content and align-content as being about space distribution, the reason for their being no self-alignment becomes more obvious. We are dealing with the flex items as a group, and distributing available space in some way — either at the start or end of the group or between the items.

If might be also helpful to think about how justify-content and align-content work in CSS Grid Layout. In Grid, these properties are used to distribute spare space in the grid container between grid tracks. Once again, we take the tracks as a group, and these properties give us a way to distribute any extra space between them. As we are acting on a group in both Grid and Flexbox, we can’t target an item on its own and do something different with it. However, there is a way to achieve the kind of layout that you are asking for when you ask for a self property on the main axis, and that is to use auto margins.

Using Auto Margins On The Main Axis

If you have ever centered a block in CSS (such as the wrapper for your main page content by setting a margin left and right of auto), then you already have some experience of how auto margins behave. A margin set to auto will try to become as big as it can in the direction it has been set in. In the case of using margins to center a block, we set the left and right both to auto; they each try and take up as much space as possible and so push our block into the center.

Auto margins work very nicely in Flexbox to align single items or groups of items on the main axis. In the next example, I am achieving a common design pattern. I have a navigation bar using Flexbox, the items are displayed as a row and are using the initial value of justify-content: start. I would like the final item to be displayed separated from the others at the end of the flex line — assuming there is enough space on the line to do so.

I target that item and give it a margin-left of auto. This then means that the margin tries to get as much space as possible to the left of the item, which means the item gets pushed all the way over to the right.

See the Pen Smashing Flexbox Series 2: alignment with auto margins by Rachel Andrew (@rachelandrew) on CodePen.

If you use auto margins on the main axis then justify-content will cease to have any effect, as the auto margins will have taken up all of the space that would otherwise be assigned using justify-content.

Fallback Alignment

Each alignment method details a fallback alignment, this is what will happen if the alignment you have requested can’t be achieved. For example, if you only have one item in a flex container and ask for justify-content: space-between, what should happen? The answer is that the fallback alignment of flex-start is used and your single item will align to the start of the flex container. In the case of justify-content: space-around, a fallback alignment of center is used.

In the current specification you can’t change what the fallback alignment is, so if you would prefer that the fallback for space-between was center rather than flex-start, there isn’t a way to do that. There is a note in the spec which says that future levels may enable this.

Safe And Unsafe Alignment

A more recent addition to the Box Alignment specification is the concept of safe and unsafe alignment using the safe and unsafe keywords.

With the following code, the final item is too wide for the container and with unsafe alignment and the flex container on the left-hand side of the page, the item becomes cut off as the overflow is outside the page boundary.

.container   
    display: flex;
    flex-direction: column;
    width: 100px;
    align-items: unsafe center;


.item:last-child 
    width: 200px;

The overflowing item is centered and partly cut off


Unsafe alignment will give you the alignment you asked for but may cause data loss (Large preview)

A safe alignment would prevent the data loss occurring, by relocating the overflow to the other side.

.container   
    display: flex;
    flex-direction: column;
    width: 100px;
    align-items: safe center;


.item:last-child 
    width: 200px;

The overflowing item overflows to the right


Safe alignment tries to prevent data loss (Large preview)

These keywords have limited browser support right now, however, they demonstrate the additional control being brought to Flexbox via the Box Alignment specification.

See the Pen Smashing Flexbox Series 2: safe or unsafe alignment by Rachel Andrew (@rachelandrew) on CodePen.

In Summary

The alignment properties started as a list in Flexbox, but are now in their own specification and apply to other layout contexts. A few key facts will help you to remember how to use them in Flexbox:

  • justify- the main axis and align- the cross axis;
  • To use align-content and justify-content you need spare space to play with;
  • The align-content and justify-content properties deal with the items as a group, sharing out space. Therefore, you can’t target an individual item and so there is no -self alignment for these properties;
  • If you do want to align one item, or split a group on the main axis, use auto margins to do so;
  • The align-items property sets all of the align-self values as a group. Use align-self on the flex child to set the value for an individual item.
Smashing Editorial
(il)


See original:

Everything You Need To Know About Alignment In Flexbox

Thumbnail

What Happens When You Create A Flexbox Flex Container?




What Happens When You Create A Flexbox Flex Container?

Rachel Andrew



In a short series of articles, I’m going to spend some time in detailed unpacking of Flexbox — in the same way I have done in the past with grid. We’ll have a look at the things Flexbox was designed for, what it really does well, and why we might not choose it as a layout method. In this article, we will take a detailed look at what actually happens when you add display: flex to your stylesheet.

A Flex Container, Please!

In order to use Flexbox, you need an element that will be the flex container. In your CSS, you use display: flex:

See the Pen Smashing Flexbox Series 1: display: flex; by Rachel Andrew (@rachelandrew) on CodePen.

Let us spend a little while thinking about what display: flex really means. In the Display Module Level 3, each value of display is described as actually being a combination of two things: an inner display model, and an outer display model. When we add display: flex, we are really defining display: block flex. The outer display type of our flex container is block; it acts like a block level element in normal flow. The inner display type is flex, so items directly inside our container will participate in flex layout.

This is something you might never have really thought about but probably understand anyway. The flex container acts like any other block on your page. If you have a paragraph following by a flex container, both of these things behave as we have become accustomed to block elements behaving.

We can also define our container with a value of inline-flex which is like using display: inline flex, i.e. a flex container that acts like an inline level element, with children that participate in flex layout. The children of our inline flex container behave in the same way that children of our block flex container behave; the difference is how the container itself behaves in the overall layout.

See the Pen Smashing Flexbox Series 1: display: inline-flex; by Rachel Andrew (@rachelandrew) on CodePen.

This concept of elements having an outer display type, which defines how they behave as a box on the page (plus an inner display type) dictating how their children behave is quite useful. You can apply this thinking to any box in CSS. How does this element act? How do the children of this element act? The answers relate to their outer and inner display models.

Rows Or Columns?

Once we have defined our flex container, some initial values come into play. Without our adding any extra properties, the flex items display as a row. This happens because the initial value of the flex-direction property is row. If you don’t set it, you get a row.

The flex-direction property is how we set the direction of the main axis. Other values for flex-direction are:

  • column
  • row-reverse
  • column-reverse

With our items in a row, the items are placed with the first item at the start edge of the inline dimension and display in the order that they appear in the source. In the specification, this edge is described as main-start:


main-start is at the beginning of the row


main-start is at the start of the inline dimension (Large preview)

If we use the value column, the items begin to lay out from the start edge of the block dimension and therefore form a column.


Items laid out as a column, main-start is at the top


main-start is the start of the block dimension (Large preview)

When we use row-reverse, the location of main-start and main-end are switched; therefore, the items lay themselves out one after the other ending up in reverse order.


Items start at the end of the row


main-start is at the end of the inline dimension (Large preview)

The value column-reverse does the same thing. It’s important to remember that these values don’t “switch the order of items” although this is what we see happening, they change the place where the flow of items starts: by switching where main-start is. So our items do display in reverse order, but that is because they start laying out at the other end of the container.

It is also important to remember that when this happens, the effect is purely visual. We are asking the items to display themselves starting at the end edge; they are still flowing in the same order and this is the order that your screen reader uses and also the order they can be tabbed through. You should never use row-reverse when what you really want to do is change the order of the items. Make that change in your document source.

The Two Axes Of Flexbox

We have already exposed an important feature of flexbox: the ability to switch the main axis from row to column. This axis switching is why I think that often it is easier to understand things like alignment in Grid Layout first. With Grid, working in two dimensions, you can align on both axes in pretty much the same way. Flexbox is a little trickier because different things happen depending on whether you are working with the main axis, or the cross axis.

We have already encountered the main axis, i.e. the axis that you define as the value of flex-direction. The cross axis is the other dimension. If you have set flex-direction: row, your main axis is along the row, and your cross axis is down the columns. With flex-direction: column, the main axis is down the column and your cross axis along the rows. It is here where we need to explore another important feature of Flexbox, and that is the fact that it is not tied to the physical dimensions of the screen. We don’t talk about a row running from left to right, or a column from top to bottom, because that is not always the case.

Writing Modes

When I described row and column above, I mentioned the block and inline dimensions. This article is written in English, which is a horizontal writing mode. This means that when you ask Flexbox to give you a row, you get a horizontal display of your flex items. In this case, main-start is on the left — the place in which sentences start in English.

If I were working in a right-to-left language such as Arabic, then the start edge would be on the right:

See the Pen Smashing Flexbox Series 1: row with rtl text by Rachel Andrew (@rachelandrew) on CodePen.

The initial values of flexbox mean that if all I do is create a flex container, my items would start on the right and be displayed moving towards the left. The start edge in the inline direction is the place where sentences start in the writing mode you are using.

If you happen to be in a vertical writing mode and ask for a row, your row will run vertically, because that is the way in which rows of text run in a vertical language. You can try this by adding the writing-mode property to your flex container and setting it to the value vertical-lr. Now, when you set flex-direction to row, you get a vertical column of items.

See the Pen Smashing Flexbox Series 1: row with a vertical writing mode by Rachel Andrew (@rachelandrew) on CodePen.

So a row can run horizontally, with a main-start of the left or the right, and also run vertically with main-start at the top. It’s still a flex-direction of row even if our horizontal text accustomed minds find it hard to think of a row running vertically!

To cause the items to lay themselves out in the block dimension, we set the value of flex-direction to column or column-reverse. In English (or in Arabic), we then see the items displaying one on top of the other down the page, starting at the top of the container.

In a Vertical Writing Mode, the Block dimension runs across the page, as this is the direction blocks are laid out in those writing modes. If you ask for a column in vertical-lr, your blocks will run left to right vertically:

See the Pen Smashing Flexbox Series 1: column in vertical-lr writing mode by Rachel Andrew (@rachelandrew) on CodePen.

However, no matter in which direction the blocks are displayed, if you are working with a column then you are working in the block dimension.

Understanding the fact that a row or a column can run in different physical directions is helpful in understanding some of the terminology being used for Grid and Flexbox. We don’t refer to ‘left and right’ or ‘top and bottom’ in Flexbox and Grid because we don’t make any assumption as to the writing mode of our document. All of CSS is becoming more writing mode aware; if you are interested in some other properties and values being implemented to make the rest of CSS behave in this same way, read my article on Logical Properties and Values.

As a summary, remember that:

  • flex-direction: row

    • main axis = inline dimension
    • main-start will be where sentences begin in that writing mode
    • cross axis = block dimension
  • flex-direction: column

    • main axis = block dimension
    • main-start will be where blocks start to lay out in that writing mode
    • cross axis = inline dimension

Initial Alignment

Some other things happen when we apply display: flex. Some initial alignment happens. In a future article in this series, we will take a good look at alignment; however, in our exploration of display: flex, we should look at the initial values that are applied.

Note: It is worth noting that while these alignment properties started life in the Flexbox specification, the Box Alignment specification will ultimately supersede those defined in the Flexbox specification, as explained in the Flexbox specification.

Main-Axis Alignment

The initial value of justify-content is set to flex-start. It is as if our CSS was:

.container 
    display: flex;
    justify-content: flex-start;

This is the reason that our flex items line up at the start edge of the flex container. It’s also the reason why when we set row-reverse they switch to the end edge because that edge then becomes the start of the main axis.

When you see an alignment property which begins with justify-, then it applies to the main axis in Flexbox. So justify-content performs main-axis alignment and aligns our items to the start.

The other possible values for justify-content are:

  • flex-end
  • center
  • space-around
  • space-between
  • space-evenly (added in Box Alignment)

These values deal with the distribution of available space in the flex container. This is why the items are moved around, or spaced out. If you add justify-content: space-between, then any available space is shared out between the items. However, this can only happen if there is free space to start with. If you had a tightly packed flex container (with no extra space after all the items had been laid out), then justify-content would do nothing at all.

You can see this if you switch your flex-direction to column. Without a height on the flex container there is no free space, so setting justify-content: space-between won’t achieve anything. If you add a height and make it so that the container is taller than is required to display the items, then the property has an effect:

See the Pen Smashing Flexbox Series 1: column with a height by Rachel Andrew (@rachelandrew) on CodePen.

Cross-Axis Alignment

Items are also aligned on the cross axis with a single line flex container; the alignment that we are performing is to align the boxes against each other in the line. In the next example, one of our boxes has more content in than all the others. Something is telling the other boxes to stretch to the same height. That something is the align-items property, which has an initial value of stretch:

See the Pen Smashing Guide to Layout: clearfix by Rachel Andrew (@rachelandrew) on CodePen.

When you see an alignment property which begins with align- and you are in flexbox, then you are dealing with cross-axis alignment, and align-items aligns the items within the flex line. The other possible values are:

  • flex-start
  • flex-end
  • center
  • baseline

If you do not want the boxes to all stretch to the height of the tallest, then setting align-self: flex-start will cause them all to align to the start edge of the cross axis.

See the Pen Smashing Flexbox Series 1: align-items: flex-start by Rachel Andrew (@rachelandrew) on CodePen.

Initial Values For The Flex Items

Finally, the flex items themselves also have initial values, they are set to:

  • flex-grow: 0
  • flex-shrink: 1
  • flex-basis: auto

This means that our items will not grow by default to fill the available space on the main axis. If flex-grow were set to a positive value, this would cause the items to grow and take up any available space.

The items can shrink, however, as flex-shrink is set to the positive value of 1. This means that if we have a very narrow flex container, then the items will get as small as they can before any overflow happens. This is sensible behavior; in general, we want things to stay inside their boxes and not overflow if there is space to display them.

In order to get the best possible layout by default, flex-basis is set to auto. We will have a proper look at what that means in a future article in this series, however, most of the time you can think of auto as “big enough to fit the content”. What you will see happen, when you have flex items that fill the container, and one of those items has a larger amount of content than the others, the larger item will be given more space.

See the Pen Smashing Flexbox Series 1: initial values of flex items by Rachel Andrew (@rachelandrew) on CodePen.

This is Flexbox’s flexibility in action. With a flex-basis of auto and no sizing applied to the items, the flex items have a base size of the max-content size. This would be the size they would be if they stretched out and did no wrapping whatsoever. Then, space is taken away from each item in proportion, detailed in the following note in the flexbox specification.

“Note: The flex shrink factor is multiplied by the flex base size when distributing negative space. This distributes negative space in proportion to how much the item is able to shrink, so that e.g. a small item won’t shrink to zero before a larger item has been noticeably reduced.”

The larger item has less space taken away and so we get the final layout. You can compare the two screenshots below, both taken using the example above. However, in the first screenshot, the third box has a smaller amount of content, and therefore our columns have a more equal distribution of space.


The example with a larger item shows the item taking up more space


The items flex to give the larger item more room (Large preview)

Flexbox here is helping us to end up with a reasonable end result given no other input from the person writing the CSS. Rather than reduce the space evenly and end up with a very tall item with a couple words on each line, it assigns that item more space to lay itself out. Within this kind of behavior is the key to the real use cases for Flexbox. Flexbox is at its best when used to lay sets of things out — along one axis — in a flexible and content aware way. I’m touching on a little of the detail here, but we will take a proper look at these algorithms later in this series.

Summary

In this article, I’ve taken the initial values of Flexbox, in order to explain what actually happens when you say display: flex. It’s a surprising amount once you begin to unpack it, and contained within these few properties are many of the key features of flex layouts.

Flex layouts are flexible: they try to make good choices by default about your content — squishing and stretching to get the best readability. Flex layouts are writing mode aware: the directions of row and column relate to the writing mode being used. Flex layouts allow alignment of the items as a group on the main axis, by choosing how space is distributed. They allow alignment of items within their flex line, moving the items on the cross axis in relationship to each other. Importantly, flex layouts understand how big your content is, and try to make good basic decisions in order to display it. In future articles, we will explore these areas in more depth, and consider further exactly when and why we might choose to use Flexbox.

Smashing Editorial
(il)


More: 

What Happens When You Create A Flexbox Flex Container?

Thumbnail

The New Layout Standard For The Web: CSS Grid, Flexbox And Box Alignment

Layout on the web is hard. The reason it is so hard is that the layout methods we’ve relied on ever since using CSS for layout became possible were not really designed for complex layout. While we were able to achieve quite a lot in a fixed-width world with hacks such as faux columns, these methods fell apart with responsive design.
Thankfully, we have hope, in the form of flexbox — which many readers will already be using — CSS Grid Layout and the box alignment module.

This article:  

The New Layout Standard For The Web: CSS Grid, Flexbox And Box Alignment

Finally, CSS In JS! Meet CSSX

JavaScript is a wonderful language. It’s rich, it’s dynamic, and it’s so tightly coupled to the web nowadays. The concept of writing everything in JavaScript doesn’t sound so crazy anymore. First, we started writing our back end in JavaScript, and then Facebook introduced JSX, in which we mix HTML markup with JavaScript. Why not do the same for CSS in JS?
Imagine a web component distributed as a single .

Originally posted here – 

Finally, CSS In JS! Meet CSSX