A first look at flexbox — a listing of published blog posts.
Building a static website: part 10
17-NOV-2025
Table of Contents
- Displaying a list of currently published blog posts
- An introduction to flexbox
- 2.1 Executive summary
- 2.2 CSS flexbox property summary
- 2.3 Container and container items
- 2.4 Flex direction
- 2.5 Justifying content within a flex container
- 2.6 Wrapping (or otherwise) of flex items
- 2.7 Flexbox resizing behaviour
- 2.8 Aligning content and items within a flex container
- 2.9 Changing the display order of flexbox items
- Implementing the blog post published list using flexbox
- Implementing the table of contents
- Conclusions and design decisions
In the previous blog post, I looked at more details about choosing and implementing fonts. I had then intended to make this blog post about adding a table of contents, to look at helping navigation within these lengthy posts. I have done that, but the main focus of this article is completely different. Instead, with an increasing number of blog posts in this series, I want to explore using the flexbox technique to implement a list of those published blog posts.
1. Displaying a list of currently published blog posts
With the published blog posts in this series continuing to grow, I wanted to put together some kind of index page that would list these and a better looking format than I have been using previously. Up to now, I have been displaying these in a straightforward HTML table. In addition, I wanted to use this exercise as a way to get back into understanding the flexbox CSS technique, which I believe would be a good way to go about implementing such a list, based on some prior experience. As usual, I will be documenting my thoughts on this as I go along, along with discussing any problems that I might encounter.
In order to achieve this, I will present the following during this post:
- Explain what I am attempting to achieve and how I would like it to look.
- Introduce the core concepts of the flexbox technique.
- Explain the specifics of how I'm using CSS flexbox to implement the blog post listing.
Note, as I continue to add more posts, that list will be updated and so will its associated CSS file, so it will evolve to some extent and should provide some basis for similar pages that will perform a similar purpose for other blog posts and articles when they are eventually published on this website.
1.1 What should the published list contain?
A good place to start is to consider what I actually want to display in the list, which will then suggest how it might be arranged. Currently, I see the important information that I want to display as follows:
- The "header image" associated with a blog post. This is intended to be the image that appears at the top of most blog post entries, which is designed to try and illustrate what that post is about. In the cases where such an image doesn't exist, I can still create something to go with that blog post that I can use in the published list.
- The main title of the blog post.
- A description of what the blog post contains.
- The blog post author. That's quite likely to always be me, but I thought I might as well stick to a typical approach used by many websites.
- The published and (if relevant) updated date.
1.2 Diagrammatic mockup of published blog post list
I have created a mockup of how this could look, based on the first two published blog posts, which gives a pretty good idea of how it could look. The following points are important:
- The specific size of the image, versus the descriptive text does not necessarily reflect how things will look eventually, because that isn't vitally important.
- In the design, both the image and the blog post heading would have a link to the blog post itself.
- The font size of the text is reduced in comparison with that on the main blog post, which seems reasonable, otherwise everything would take up too much space.
- Images are likely to vary in their aspect ratio and I want to leave that same aspect ratio in the thumbnail image. This can be seen in the two images I've used in the mockup.
- At some future point, there might be a link from the author name to a short bio or list of articles published by that author, but this won't be the case in the first draft.
- I wanted to give some subtle visual separation between each item on the list, so I've done that with a light grey line.
- I want to align the top of the image and the text to be the same.
- When considering what to do as either a browser window is made narrower, or the list is displayed on a narrow screen, such as a mobile device, the text should resize, likely retaining the same font size.
- I haven't yet made a final decision on how to deal with the image, which could stay the same, shrink, or disappear completely on narrow screens, or some combination of the above.
Having considered what I'm trying to achieve, I can now move on to looking at the basics of CSS flexbox.
2. An introduction to flexbox
As always, there are plenty of resources out there to give a much more detailed guide, or tutorial than I am going to attempt, but I wanted to give some kind of flavour of what it's all about, before moving onto my particular requirements. That will help me have some level of understanding of the subject.
2.1 Executive summary
CSS flexbox can be briefly summarised with the following features:
- It is an advanced layout method, which can complement CSS Float and shares some features with CSS Grid.
- It is considered a "one-dimensional" approach to layout (items are arranged in rows or columns).
- The main concept is to control the alignment and distribution of HTML elements within a "container" element.
- The container can control the child elements width and height the best fill the available space.
- Items can be arranged in both horizontal and vertical directions.
- There is the concept of a "main axis" (horizontal by default) and "cross axis" (vertical by default).
- Items can be displayed in a different order than they are specified in HTML.
- The layout is writing mode sensitive — which means it can adapt to such things as right to left languages. That's not something that I'm likely to need.
- The wrapping or otherwise of the various elements can be controlled in a number of ways.
I intend to explore some of the main concepts in later sections, but first I think it's worth looking at the CSS that allows us to control flexbox behaviour. In particular, it's worth understanding what the default behaviour is.
2.2 CSS flexbox property summary
The following is a summary of the main properties associated with CSS flexbox, with their possible values (with the default highlighted).
| Property | Values (Default Highlighted) |
|---|---|
| display | flex, inline-flex |
| flex-direction | row, row-reverse, column, column-reverse |
| flex-wrap | nowrap, wrap, wrap-reverse |
| justify-content | flex-start, flex-end, center, space-between, space-around, space-evenly |
| align-content | flex-start, flex-end, center, stretch, space-between, space-around |
| align-items | flex-start, flex-end, center, stretch, baseline |
| order | 0 |
| flex-shrink | 1 |
| flex-grow | 0 |
| flex-basis | auto |
2.3 Container and container items
Fundamentally, we can see CSS flexbox as being a layout method that allows a number of HTML elements to be controlled within a "container". Diagrammatically, we can think of this as follows. We have a "container" HTML element (shown by the blue ground its and in this case, three items within that container. The container controls much of how the items are displayed within it.
In order to turn on the behaviour of the items within the container, we use the display: flex CSS property. Doing so turns on a number of behaviours, which I will explore a bit more.
The following illustrates the behaviour of a flexbox container and associated items, largely left with the default behaviour of flexbox enabled.
This first paragraph contains more text than the other items.
Item 2
Item 3
In particular, we can see that:
- The default direction is row-based. This equates from left to right for the default writing direction.
- The container items are lined up next to each other from the start of the row.
- Because the first item takes up more vertical space than the others, the container grows vertically to accommodate this.
- The size of the second paragraph (containing the text "Item 2") also stretches vertically to fill the full height of the container. This is because the default for the
align-itemshas a default value of "stretch". I had been initially confused by this behaviour, so I think it's worth pointing out. - The third paragraph (containing the text "Item 3") uses the
align-self: flex-end, such that it takes up just the space required for the text it contains. I've used this as an example of how CSS can alter the default behaviour.
Expand to see the CSS used for the above.
.flex_container1
{
display: flex;
background: #729fcf;
margin-block-end: 20px;
}
.flex_container1 p
{
margin-block-end: 0;
}
.flex_container1 p:first-child
{
background: #cccc00;
width: 150px;
}
.flex_container1 p:nth-child(2)
{
background: #808019;
}
.flex_container1 p:last-child
{
background: #e6e64c;
align-self: flex-end;
}
2.4 Flex direction
Flexbox is associated with the flex-direction property. Whereas for (normal writing mode), items arrange themselves from left to right, we can change that behaviour by setting a different value. In the example below, the flex container items are now arranged as a column. Note that at first it might look slightly confusing, but we can see that the three items are stacked on top of one another, but because "Item 3" still has the align-self: flex-end, this demonstrates that the end of the flex container is now the right hand end.
This first paragraph contains more text than the other items.
Item 2
Item 3
The main CSS to achieve this is as follows. Note that I have given the flex container a width of 300 pixels, which should help to illustrate the arrangement as a column visually a bit better. I have also removed the fixed width of the first paragraph of text.
.flex_direction_column
{
display: flex;
flex-direction: column;
width: 300px;
...
...
}
There are also possible values of: "row-reverse" and "column-reverse", which I won't demonstrate here.
2.5 Justifying content within a flex container
As can be seen from a previous section, when we have a number of items within the container, by default, these items are justified to the start of the flex container (which will be the left-hand side for the default writing mode). However, we can alter this in a number of ways, by using the justify-content property. As a reminder, we can have the following values for this property: "flex-start (the default), flex-end, center, space-between, space-around, space-evenly". I don't think it's worth trying to demonstrate all of them, but let's look at a couple.
Justify-content: flex-end
This justifies the content to the other end of the flex container, which in this case is the right hand side.
This first paragraph contains more text than the other items.
Item 2
Item 3
This uses very similar CSS to the earlier example, but we now have:
.justify_end
{
display: flex;
justify-content: flex-end;
...
...
}
Justify-content: space-around
Finally, I will consider one more case, just for something a bit different. This arranges the items with space around them.
This first paragraph contains more text than the other items.
Item 2
Item 3
Unsurprisingly, the meat of the CSS for that is as follows:
.justify_space_around
{
display: flex;
justify-content: space-around;
...
...
}
2.6 Wrapping (or otherwise) of flex items
The general idea of flexbox is to make smart decisions about how a number of items will be displayed within a container. That decision making includes dealing with a situation where there are more items that can fit inside the container. This can happen if the container is restricted in size for some reason. What happens in this case is controlled by the flex-wrap property, which is default it to not wrapping.
Flex-wrap: nowrap
As I mentioned above, this is the default and we can see that demonstrated below. Because the container is effectively constrained in size by CSS, the five images cannot fit within it, but as wrapping is not allowed, it means the last image goes off the edge.
The following CSS is used to control this:
.no_wrap
{
display: flex;
flex-wrap: nowrap; /* This is the default value. */
...
...
}
Flex-wrap: wrap
In the case below, we use CSS to allow wrapping of the items, which on the screen that is wide enough, will show the final image appearing on the start of another line. Note that on a mobile device, this may look somewhat different, due to the screen possibly being a much narrower one.
The following CSS controls this behaviour:
.wrap
{
display: flex;
flex-wrap: wrap;
...
...
}
The justify-content property interacts with flex-wrap, so that if you are centring your items within the container, if they wrap, the item or items in the second and subsequent rows will also be centred. We can see this in action below:
The following CSS makes that happen:
.wrap_centre
{
display: flex;
flex-wrap: wrap;
justify-content: center;
...
...
}
2.7 Flexbox resizing behaviour
I just wanted to mention something more about the way that flexbox behaves as you resize the container. This of course might happen if you make a window wider or narrower, causing the container to change size. Earlier, I looked at how items can end up wrapping round (or not).
However, some of this behaviour depends on whether the item has a particular fixed size or not. In the case of an image, such as we used in the wrapping examples, they do have an intrinsic size and they will wrap (if the CSS is set to do so), once the container becomes too small.
In the case of something like paragraphs of text, the size will be flexible and so as you change the size of the window, it will squeeze or expand the text, but leave the image at the same size. The following example shows some of this behaviour, but also demonstrates how such behaviour can sometimes inadvertently be affected by other CSS, elsewhere in the file.
I mention this, because I spent a long time trying to understand why the example was not behaving the way I expected and so I wanted to include this as a reminder, alongside why it's happening and at least one method of getting round it.
If you start with a wide browser window and then make it narrower, you should see the following behaviour:
- The image on the left hand side ('1') will start to resize and if you can make the window and narrow enough, it will eventually disappear.
- The second image from the left ('2') remains at the same size.
- The paragraph of text will also resize, wrapping the text within it as it does so.
- The image on the right hand side ('5') remains the same size and if you make the window narrow enough, it will start to overflow the container.
I will discuss more of the details after the example.
A short paragraph of text.
The relevant HTML is:
<div class="flex_squeeze"> <p><img src="images/image_square1_lod.svg" alt="Square SVG image 1"></p> <img src="images/image_square2_lod.svg" alt="Square SVG image 2"> <p>A short paragraph of text.</p> <p><img src="images/image_square5_lod.svg" alt="Square SVG image 5"></p> </div>
For the behavioural explanation, note that two of the images are surrounded by paragraph tags.
The accompanying CSS is:
.flex_squeeze
{
display: flex;
background: #729fcf;
margin-block-end: 20px;
}
.flex_squeeze p:nth-child(3)
{
background: #808019;
}
.flex_squeeze p:last-child img
{
max-inline-size: initial;
}
We should also remember that, earlier in the CSS file, we have the following definition, that I have been using for some time in this blog post series:
article img
{
max-inline-size: 100%;
}
As far as I've understood, flexbox by default will attempt to resize items that it considers "flexible". It doesn't do so for items that are not flexible, which means they have an intrinsic size. In addition, when an item falls below a certain size, it is no longer displayed. This default behaviour can be altered by the relevant CSS of course.
Why I became confused was that images not surrounded by paragraph tags would remain the same size, but, initially despite everything I tried, images surrounded by paragraph tags will resize, as seen in the example above. I confess I was banging my head against a brick wall, until I finally realised that the max-inline-size: 100% definition I pointed out, means that such images are rendered flexible from the perspective of flexbox, because the image will be resized to 100% of its parent (paragraph) element, hence such images are resized!
I'm sure plenty of people would realise what was going on more quickly, but I wanted to use this example to demonstrate unintended consequences can occur in CSS. In addition, I also wanted to show at least one way of counteracting the effect, in this case by using max-inline-size: initial; for the image inside the final paragraph. Note that it is also possible to use flex-shrink: 0 directly on the last paragraph, which in this case would look like:
.flex_squeeze p:last-child
{
flex-shrink: 0;
}
It is also worth pointing out that because of the paragraph tags (or the lack of them) round the various images, that also affects the behaviour to some extent, because I also have earlier CSS definitions that add a degree of margin to the bottom of paragraphs, so the second image from the left isn't aligned with the rest of the items. In this case, I'm not worried about that, because it's all about demonstrating certain behaviour, so I can understand it myself.
Flex-shrink, flex-grow, flex-basis, flex
There are also a number of properties that allow control over how various items can shrink and grow as we altered the size of the container. These are listed above in the heading (note that flex is a shorthand property that allows the other values to be set at the same time). I have briefly mentioned the behaviour of flex-shrink.
I don't intend to talk about these properties in any further detail, at least not for the moment, because I believe I've currently covered most of what I need for my own purposes.
2.8 Aligning content and items within a flex container
The flexbox CSS model also allows control over the distribution of flex container items on the cross axis (which is vertically under default circumstances). These are the align-content and align-items properties. They are used in slightly different circumstances:
- The
align-contentproperty is used where we want to control items that are wrapping within our flexbox container and the height of the container is not entirely filled up by all the items. It is reminiscent of thejustify-contentproperty, taking many of the same values (such as "flex-start" and "space-around"). - The
align-itemsproperty is used to control the vertical alignment of items within a container, that once again has a height which is greater than one or more of the items within that container.
Align-content property
The following diagram illustrates the basic behaviour of some of the main values for the align-content CSS property. Hopefully, these should be self-explanatory.
Align-items property
The following diagram illustrates the basic baby of some of the main values for the align-items CSS property. Again, most of the values should be self-explanatory, but it might be worth quickly explaining "baseline". As far as I understand, this works by taking the baseline of the first HTML element inside each container, then uses this to a line those items. The grey line is intended to illustrate where that baseline is.
2.9 Changing the display order of flexbox items
I'm just going to note that it is possible to use the order CSS property to change the order in which flexbox items are actually displayed on the screen, such that this is different to the order in which they appear in the HTML. I'm not going to go into any more detail, because right now I don't see it as being relevant to what I need to do, but I can return to this if I feel it's necessary. There is also the argument that it's not a good idea to change the order, because it can confuse screen readers. However, I think it could be useful where it could allow adaptation of the HTML to differing circumstances, such as desktop versus mobile browsers.
4. Implementing the blog post published list using flexbox
I have now taken a good introductory look at flexbox in the earlier sections. Now it is time to consider how to use some of those techniques to try implementing the main focus of this blog post, which is a list of currently published blog posts in this particular series.
A summary of the design decisions that I made are:
- As we are talking about a list of published blog posts, it makes sense to use an unordered list is the basic underlying structure.
- Each list element (
<li>) acts as the flexbox container. - The flexbox container has two child items: one of them is the image and the other is the text (including the header and other text).
- The image is given a fixed size (width). It therefore retains that size as the screen is made (or is) wider or narrower.
- Below a certain size, the image is no longer displayed, which is designed to suit narrow screens.
The result of all this is shown below.
Building a static website (part 1)
The first part of a series of blog posts in which I go through the various steps and design decisions I am using to build a static website. Each subsequent post will add further to the site design.
David – 01-AUG-2025, updated 13-AUG-2025
Building a static website (part 2: Introduction to images)
Building a static website from scratch using text files, bash scripts and free tools. In this blog post, I start looking at the subject of displaying images within webpages.
David – 07-AUG-2025
The HTML for this example is:
<ul class="article_list"> <li><a href="building_a_static_website_01.html"><img src="images/bp01_main_image.svg" alt="Main illustrative blog post header image."></a> <div class="summary"> <h3><a href="building_a_static_website_01.html">Building a static website (part 1)</a></h3> <p>The first part of a series of blog posts in which I go through the various steps and design decisions I am using to build a static website. Each subsequent post will add further to the site design.</p> <p>David – <span class="nowrap">01-AUG-2025</span>, updated <span class="nowrap">13-AUG-2025</span></p> </div> </li> <li><a href="building_a_static_website_02.html"><img src="images/bp02_main_image.svg" alt="Main illustrative blog post header image."></a> <div class="summary"> <h3><a href="building_a_static_website_02.html">Building a static website (part 2: Introduction to images)</a></h3> <p>Building a static website from scratch using text files, bash scripts and free tools. In this blog post, I start looking at the subject of displaying images within webpages.</p> <p>David – <span class="nowrap">07-AUG-2025</span></p> </div> </li> </ul>
The CSS to implement this is shown below. Note that there is commentary in that CSS, so I hopefully won't need to say anything extra.
Expand to see the CSS.
ul.article_list
{
/* Do not display unordered list bullets */
list-style-type: none;
/* Make sure the list lines up on the left-hand side. */
padding-inline-start: 0;
}
.article_list a:link
{
text-decoration: none;
}
.article_list li
{
/* Each list element is a flexbox container. */
display: flex;
/* This provides the visual separation between the rows. */
border-block-end: 1px solid lightgrey;
/* Put some space between one row in the next (i.e. after the grey border). */
margin-block-end: 10px;
}
.article_list li:last-child
{
/* No extra space for the last list element. */
margin-block-end: 0;
}
.article_list li img
{
/* Give a specific width to the image. Means flexbox will not resize it. */
width: 150px;
/* Counteracts the "max-inline-size: 100%;" definition earlier in the CSS file. */
max-inline-size: none;
}
/* Do not display the image on screen is narrower than 450 pixels. */
@media (max-width: 450px)
{
.article_list li img
{
display: none;
}
}
.summary
{
/* Add space between the image and the text. */
margin-inline-start: 10px;
font-size: 0.8rem;
}
.summary h3
{
margin-block-end: 10px;
font-size: 1.6rem;
}
.summary p
{
margin-block-end: 15px;
}
3. Implementing the table of contents
As I have mentioned more than once in this article, I've intended to implement a table of contents, because this is something that will often suit articles or blog posts of this kind of length. Although the main focus of this particular article turned out to be CSS flexbox, I thought I would still look at putting together a basic table of contents. I am likely to return to this in a future post.
As it happens, to make things more straightforward for myself, I have implemented a variation of something I have already used myself for many years, in technical documents that I wrote for my previous employer. For the current requirements, I have added the use of <details> to make its collapsible, which is a quick way to avoid taking up a load of space, which is particularly important for mobile devices. Before looking at the details, a few basic points:
- I have used numbers to represent the main and secondary headings, so we have something like "1." for the first level heading and "1.1" for the secondary heading.
- The main structure of the table of contents is an ordered list, which helps to reflect both the listing of contents semantically and makes things a bit easier, because we can display the main heading number directly from the list.
- I use my own bash and sed scripts to generate the HTML for the table of contents.
The HTML generated for the table of contents using this article is as follows. Hopefully, it should be straightforward to understand what's happening.
<details>
<summary>Table of Contents</summary>
<ol start="1" class="contents_tab">
<li><a href="#c_1">Displaying a list of currently published blog posts</a>
<ul>
<li>1.1 <a href="#c_1.1">What should the published list contain?</a></li>
<li>1.2 <a href="#c_1.2">Diagrammatic mockup of published blog post list</a></li>
</ul></li>
<li><a href="#c_2">An introduction to flexbox</a>
<ul>
<li>2.1 <a href="#c_2.1">Executive summary</a></li>
<li>2.2 <a href="#c_2.2">CSS flexbox property summary</a></li>
<li>2.3 <a href="#c_2.3">Container and container items</a></li>
<li>2.4 <a href="#c_2.4">Flex direction</a></li>
<li>2.5 <a href="#c_2.5">Justifying content within a flex container</a></li>
<li>2.6 <a href="#c_2.6">Wrapping (or otherwise) of flex items</a></li>
<li>2.7 <a href="#c_2.7">Flexbox resizing behaviour</a></li>
<li>2.8 <a href="#c_2.8">Aligning content and items within a flex container</a></li>
<li>2.9 <a href="#c_2.9">Changing the display order of flexbox items</a></li>
</ul></li>
<li><a href="#c_4">Implementing the blog post published list using flexbox</a></li>
<li><a href="#c_3">Implementing the table of contents</a></li>
<li><a href="#c_4">Conclusions and design decisions</a></li>
</ol>
</details>
The CSS currently associated with this is:
ol.contents_tab ul li
{
list-style-type: none;
}
ol.contents_tab ul
{
margin-block-end: 0;
}
ol.contents_tab
{
margin-block-end: 0;
}
ol.contents_tab a:visited { text-decoration: none; }
ol.contents_tab a:active { text-decoration: none; }
The reader can see how all this looks by returning to near the top of the page, under the article published date.
I don't think I need to say much more about this right now, because it will do for the moment.
4. Conclusions and design decisions
Having looked at the CSS flexbox technique, I have been able to use it in this case to implement a list of my currently published blog posts, so that represents the basic design decision for this particular article. As far as conclusions are concerned, it is clear that the flexbox technique is something that I will be using elsewhere, but I will consider that further as appropriate circumstances come up.
I have also implemented a basic table of contents for this article and I can continue to use that for future articles, although I intend to return to this subject.
As far as the next blog post is concerned, my intention is to take a look at the CSS Grid technique, since this is a closely related approach to CSS layout.