CSS Positioning — I cannot be the only one who gets confused.

Positioning elements around the page is one of the things that should be simple but sometimes ends up taking more time than it should. I thought it would be a good idea to have some kind of summary here and hopefully save some time next time.

I’m going to talk about positioning elements with the position property itself, and using flexbox.

You can also use CSS grids to position elements but I like using the flexbox better, I think it works better when you are dealing with different screen sizes. There is a very good reference on the CSS grid here: A Complete Guide to Grid | CSS-Tricks (css-tricks.com)

I am including tables here for reference before I explain each one of the options:

1 - Using the Position Property:

There are different ways to position an element with this property (this property will be set on the element itself since this is not related to containers). This property can have one of the following values:

static (default, “wherever is fine with me”): It will put the element wherever it would normally be according to the normal flow of the page. This is the default value for all elements, so the only time you would need to actually say “position:static” would be to undo some inherited value from an earlier declaration.

relative (“I don’t like it here so much, how about I move 2 steps to the right?”): the position is relative to where it would normally be. To change that normal position with the relative property we use the properties left/right/top/bottom with it. Below are the elements with the default position of static.

If we set one of them to have position:relative and indicate how many pixels from the left and from the top it should be positioned at (from where it would normally be) we get:

You can also give a negative value to move the element in the opposite direction. Notice how the C here has been moved to be closer to the B than it would normally be.

The above (moving the C closer to B) could have also been done using the right property instead of the left one, and instead of -5 you would use 5.

fixed (“not here, I’d rather be in the middle of the viewport”): Here we also use left/right/top/bottom but the position is in relation to the viewport (browser window) and not to the position the element would have under the normal flow. The position will be maintained even with scrolling. See below for the difference between relative and fixed.

You are not limited to using just pixels to indicate the position:

absolute(“not here, a bit more to the right of my parent”): we give an absolute position RELATIVE to the NEAREST positioned (non-static) parent.

sticky (“don’t let me scroll out of view”): This works as a relative one until the element is going to scroll out of view. Then it will stick to whatever position is indicated. Check this out to see a working example: Tryit Editor v3.6 (w3schools.com)

2 — Positioning with a flex container:

If the positions of your elements follow a pattern (meaning you are not putting elements on the screen with no apparent flow) it may be easier to use flexbox to set them up. With a flex container (flexbox) you will have a container and set up properties as to how the items inside it should be displayed.

Display the items in a row:

Display the items in a column:

To have the numbers above displayed in the middle of the divs instead of at the start, use text-align:center; in the container > div css. (You are setting it in the div items, not the div container since this has to do with the text inside the divs and not the divs in the container)

If you are using flex-direction:row and you want the divs themselves centered you need to add justify-content:center to the container itself.

Other values for justify-content are flex-start (start of row) and flex-end (end of row). Also space-around to spread them out to take up the whole row.

Note that justify-content is for alignments in the horizontal line. If you also need to align the contents in the vertical line, use align-items (with center, flex-start, flex-end) in the container class.

If you have the items displayed in a row and you have more items than the row can show, you will have to scroll unless you set flex-wrap:wrap. This will move the objects to the next line (row) as needed. You can also set it to nowrap and then you may need to scroll to see everything.

We also have align-content in the container when we have multiple lines.

If you don’t have a fixed size for the items, you can also set align-content to stretch and the items will stretch to take up the whole height of the container.

There are other properties related to how items will show up in a container but I think they are not so widely used so I’m just mentioning them in case you want to search for examples of those. One of them is setting the order in which the item appears (being it different from where it is written in the code). There is an “order” property in the items for that. Another one is making one item be n times bigger than the others (flex-grow: 8 will make it 8 times bigger than the ones that have it set to 1). A div item can also set its align-self and it will override the align-items set on the container. You can also set the initial length of one of the items to something specific with flex-basis.

That was a lot, or at least it seems like a lot to me. I hope it helps clarify the options when displaying elements because for some reason this is always hard for me :-)

Software Dev, not working but learning. https://twitter.com/gmfuster , https://gmfuster.github.io/Bonico/#/