DEV Community

loading...
Cover image for Never make your text container a flexbox container

Never make your text container a flexbox container

afif profile image Temani Afif Updated on ・3 min read

Flexbox is great. Unfortunately, many developers use it in a wrong way. To be more precise, they use it automatically everywhere even when it should not be used.

Let's take the following example

<p class="box">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque semper augue ac leo tincidunt euismod.</p>
Enter fullscreen mode Exit fullscreen mode
.box {
  width: 300px;
  height: 300px;
}
Enter fullscreen mode Exit fullscreen mode

Now, you are given the common task to center the content of the box horizontally and vertically. Well a trivial task:

let's use flexbox!

.box {
  width: 300px;
  height: 300px;
  display: flex;
  align-items: center;
  justify-content: center;
}
Enter fullscreen mode Exit fullscreen mode

It's done, the content is centred and the result looks perfect, isn't it?

No, what you have done is a mistake

To understand why it's wrong let's modify our content slightly by introducing a link in our content

<p class="box">Lorem ipsum dolor sit amet, <a href="#">consectetur adipiscing</a> elit. Quisque semper augue ac leo tincidunt euismod.</p>
Enter fullscreen mode Exit fullscreen mode

Now run the code and see the result:

link inside flexbox

WTF

Don't worry, what you see is not a bug but it's indeed the logical result of the flexbox algorithm (non-intuitive but logical). To understand this behavior let's take a look into the specification:

Loosely speaking, the flex items of a flex container are boxes representing its in-flow contents.

Each in-flow child of a flex container becomes a flex item, and each contiguous sequence of child text runs is wrapped in an anonymous block container flex item.

In our first case, we only have one sequence of text and this one will get wrapperd into an anonymous block to become a flex item. There is no strange result in this case since the whole text is wrapped together.

No link text

In the second case, things are different. We have an in-flow child (our link <a>) and on each side of it we have a sequence of text so we end having 3 blocks: the link + 2 anonymous blocks for the text

Link text

Now it becomes more clear. We have 3 boxes perfectly centred using flexbox following a row direction (the default one) but the result is clearly not what we want at all.

The fix in such situation is easy: We simply add an extra wrapper around the text

<p class="box"><span>Lorem ipsum dolor sit amet, <a href="#">consectetur adipiscing</a> elit. Quisque semper augue ac leo tincidunt euismod.</span></p>
Enter fullscreen mode Exit fullscreen mode

Or we consider an outer container.

<div class="box"><p>Lorem ipsum dolor sit amet, <a href="#">consectetur adipiscing</a> elit. Quisque semper augue ac leo tincidunt euismod.</p></div>
Enter fullscreen mode Exit fullscreen mode

The goal of this post is not to fix this particular situation. It's more to highlight some unwanted result that may occur when badly using flexbox. The above is one basic example among a lot you will probably face and the fix may not be always trivial.

The real issue is not finding the fix. The real issue is to see the issue which may only happen for some particular content (like in the above when adding a link). You may write a lot of CSS and you notice the issue very late when changing the content slightly then you are good to redo many of your code.

This said you should always remember this gold rule:

Flex[box] is for boxes and not for texts so never make your text container a flexbox container.

Discussion (52)

pic
Editor guide
Collapse
typo3freelancer profile image
Simon Köhler • Edited

Yes, such a typical beginners thing that you need an extra div or something. I guess many even senior devs had to struggle in the beginning with flex, haha. When i started making sites, there was <font color="white"> and <table bgcolor="gray"> the fanciest stuff available ;-)

Collapse
akellbl4 profile image
Pavel Mineev

That was pretty crazy times.

Collapse
andreidascalu profile image
Andrei Dascalu

Just to nitpick.
You can't make your lowest level container a flexbox but your title is misleading to that. It's OK to make your text container a flexbox container as long as it's continuous text. A link it's not text (duh) so if you break your text with additional elements you get what you pay for.

Collapse
afif profile image
Temani Afif Author

It's OK to make your text container a flexbox container as long as it's continuous text. --> but there is a trap here. Consider the case where you don't know the exact content. You are pulling data from a database and in 90% of the cases it's plain text and one day you pull some text having a <strong> tag and boom, it's broken :)

Collapse
andreidascalu profile image
Andrei Dascalu

Well, yes, definitely. It's OK for text, which means that if you can't guarantee it is just that then you need to take measures depending on the end goal. One way could be like you said, to handle it for presentation only.

Although if you don't know what data you will receive I'd argue that you need to sanitize it to match your expectations and practices: eg if I don't expect html tags then I will sanitize the output (or better yet the input so that the dB content matches in the first place). If I do want to support tags then the presentation needs to be aware and be setup accordingly.

Thread Thread
afif profile image
Temani Afif Author

Even if you expect html and you want to have html the issue will still remain. How many developer are aware about how the output will be if the text will contain a link? how many beginners will even think that if I add a link to the above the result will look like I detailed? only few and this is what I am pointing here.

You may be aware about everything and you know perfectly your data but if you don't know flexbox very well you will get that surprise one day. I am trying to avoid you that surprice by explaining some quirks around flexbox that no one will explain to you until you face them ;)

Thread Thread
andreidascalu profile image
Andrei Dascalu

That is exactly what I'm saying. If you don't have guarantees it's just text then it's not just text and you don't treat it like just text (eg use a wrapper like you said or whatever fits the use case).
If you do expect just text then you implement the necessary safeguards and treat it like just text (case in which it's OK to just use the box setup).

Collapse
qm3ster profile image
Mihail Malo

It semantically doesn't make sense to make a container for some text / text document / html markup a flexbox. It doesn't matter whether you can or cannot get away with it in a given situation (no links, no idiomatic, no bring to attention, no headers, no lists, no code, no tables, no citations...)
Document-type html is expected to live in a "Normal Flow" container (not flexbox or grid)

Collapse
afif profile image
Temani Afif Author

This is the main point of this post because I see everyone using flexbox everywhere so I hightlighted one issue to convince them to stop doing this.

Collapse
nikolab profile image
Nikola Betica • Edited

Actually, nothing wrong with flex here. Your block of text should be wrapped in p tag.

Collapse
afif profile image
Temani Afif Author

not everyone will do this and even in such case many developer may apply the flexbox properties to the p element.

Collapse
qm3ster profile image
Mihail Malo

It was wrapped in a <p> tag. The problem is they made the p tag itself display: flex.

Thread Thread
afif profile image
Temani Afif Author

@qm3ster the initial code was using a div and I changed it to p but it doens't make a difference the type of the container. The main issue is the same and we should not have display:flex on text conainer.

Collapse
nikolab profile image
Nikola Betica

I know, just offering a correct solution :)

Collapse
wintercounter profile image
Victor Vincent

I'm usually using a flex reset. Usually you need flex more times than block, so at the end it's easier to set block/inline where needed. Not to mention that using flex actually can have better render performance in some cases.

Collapse
afif profile image
Temani Afif Author

setting flex everywhere by default is worse than what I described in this post ...

Collapse
wintercounter profile image
Victor Vincent • Edited

Works well for me, it helps me avoid many side-effects and cross-browser compatibility issues. Using the other way I ended up applying flex to 80% of my elements, which is really annoying.

Thread Thread
afif profile image
Temani Afif Author

Works well for me --> until now ;)

Thread Thread
wintercounter profile image
Victor Vincent

No, worked well for the last 3 years for all my projects. Familiar with React Native's View component? It's basically the same methodology.

Collapse
mamlukishay profile image
Ishay Mamluk

Interesting idea 🔥

Collapse
wintercounter profile image
Victor Vincent

It has a major drawback. Using reset the classic way like div, article, section, etc {...} It'll conflict with 3rd party libs. I'm doing this in a React environment where no HTML elements are used in JSX, instead there's a unified component for all that's markup and style, so I can simply set a default for these components. I believe if the web would be introduced today or it'd allow braking changes, flex would be the default.

Collapse
lapstjup profile image
Lakshya Thakur

Thanks for the insights. What should be the case where we have a parent flex container and in inner children one is a div and another is span. Think it like a card and it’s caption. Parent will have flex-direction:column. Is this use-case okay ?

Collapse
afif profile image
Temani Afif Author

yes it's should be ok because you are already describing two boxes (a div and span) and your text will be inside the span. If it's a div + some text then you may face some strange issues until you wrap the text inside its own box

Collapse
adithyarafk profile image
AdithyaR-afk

CSS drives me crazy

Collapse
Sloan, the sloth mascot
Comment deleted
Collapse
oenonono profile image
Junk

Yeah. You can think of the default display type for letters, words, and phrases as inline (but those are
layout-implementation-detail boxes being rendered, not explicit elements), just like the default display type for anchor elements is inline.

When you make an element a flexbox container, that has an explicit impact on the layout. Namely, all direct descendants are rendered as blocks, according to the flexbox algorithms and configured properties.

So each phrase and the anchor element become blocks in a flexbox row and that's exactly how it's supposed to work.

Collapse
shtep profile image
jim shtepa

total beginner here, thank you Temani for this material and good explanation. I am grateful that there are places such as this platform and people like you who could have lived their life keeping all the knowledge yet they share their knowledge at the cost of their time and effort instead. thank you, man!

Collapse
afif profile image
Temani Afif Author

You're welcome. Appreciate your message :)

Collapse
thomastamour profile image
𝐓𝐡𝐨𝐦𝐚𝐬 𝐒𝐭-𝐀𝐦𝐨𝐮𝐫

Just found out about float: right to align content today (-_-')
Where I always added flex to the parent container. So with float right / center text / margin-left:auto margin-right:auto I guess where all good without flexbox to center items on the y-axis 💡🤙

Collapse
katylava profile image
katy lavallee

Wait what? This is how we did things before flexbox and it was a nightmare.

Collapse
thomastamour profile image
𝐓𝐡𝐨𝐦𝐚𝐬 𝐒𝐭-𝐀𝐦𝐨𝐮𝐫

I think my comment may've came as misleading; Just pointing out few code one-liner centering solutions for single element.

I just can't bare the idea of having overload of errthang "weird flex...but okay" situations where your html is a bloat of nested divs.

Still thanks for the feedback ((:

Collapse
mamlukishay profile image
Ishay Mamluk • Edited

Good luck with that ;)
That’s exactly the kind of stuff flex allows you to get away with in an elegant, and most important, a robust way

Collapse
ximoromero5 profile image
Ximo Romero Esteve

flex-direction: column;

I think that could be a possible solution :)

Collapse
afif profile image
Temani Afif Author

no, it will also give you a strange result and the 3 boxes will be above each other ;)

Collapse
aspiiire profile image
Aspiiire

Thanks for this article really useful 🙂

Collapse
racketywater7 profile image
Haseeb Udeen

Roger that

Collapse
dowenb profile image
Benjamin Dowen • Edited

Yes! Thank you. I've made this mistake, got confused... And now I understand.

Collapse
vaibhavr2107 profile image
Vaibhav Ramawat

Why would you make paragraph as a flex .let it be just use a div than normal p in it. That should work fine.

Collapse
afif profile image
Temani Afif Author

Say this to all the beginners working with flexbox. I never make a paragraph flexbox and I wrote this post to insist on the fact that you should not do it because many will do it

PS: p or div doesn't make a difference and the same issue will occur for any element containing text

Collapse
vaibhavr2107 profile image
Vaibhav Ramawat

Yeah Right

Collapse
jpchreim profile image
Jean Pierre Chreim

Thanks man, that will definitely help me in the future 👌💪

Collapse
laychinhan profile image
Hermanet Lay

Why not?
Just wrap the inline elements inside a tag.
Voila, it is centered.

Collapse
afif profile image
Temani Afif Author

This is what I already said :) I also said that this post is not focused on this particular case which is one example to hightlight the missuse of flexbox.

Collapse
mehaksaini11 profile image
Mehak Saini

very helpfull!!! I've always struggled with flexbox

Collapse
mattheslington profile image
Matt Heslington • Edited

You should never put text directly inside a div tag.

Collapse
afif profile image
Temani Afif Author

there is nothing wrong adding text inside a div if you don't aim to have any particular semantic. Besides that, this post is not focused on semantic, even if I use p the issue will remain the same if we try to apply the flex properties to p

Collapse
theafr86 profile image
Andrew Robida

I do everything I can to never put text in a div unless it's for a custom button or link. All important info I stick in a h1-6 or p, aside,

Collapse
chakudi profile image
Vaishali JS

You have nicely pointed it out.
It's certainly a thing to keep in mind as there is high possibility of occurance of this mistake.

Some comments have been hidden by the post's author - find out more