Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

html5 or css 'smart text flow' to evenly distribute a sentence or paragraph over equally wide lines?

Suppose I have a dynamic HTML element (a span or div or whatever) with a sentence or paragraph of text inside, like this:

two lines

Now if I make the sentence slightly longer, it might need an extra line, like this:

three lines wrong

Note how the last word is on a separate line. So the first two lines are full occupied. In the sense that they take up the entire available with in this element. And the third line contains only one word and remains mostly empty.

I find this rather disturbing, and I wonder if there is a trick to distribute the free space more evenly amongst all lines. I mean like this: (note that this is the exact same sentence)

three lines right

It should re-flow automatically depending on font and browser view size, and width of the element, which may depend on screen resolution.

Is there some clever HTML5 or CSS3 way to achieve this?

Upon searching and looking in topics similar to this question, I did find the text-align: justify property which I am familiar with but isn't really what I'm looking for.
text-align: justify tends to extend all lines to the full with of the containing element by increasing the whitespace between words.

Instead, what I'm really looking for is something that redistributes the words so that all lines are narrower i.e. not take up all horizontal element space. In a way that results in all lines being equally wide (or approximating this as close as possible).

So I mean NOT like this: (which is what text-align:justify does)

text-align justify

Compare this to the previous example above.

like image 681
RocketNuts Avatar asked May 20 '20 22:05

RocketNuts


People also ask

How do you evenly space elements in HTML?

Use justify-content: space-between to evenly distributes child elements horizontally.

What is paragraph alignment in HTML?

The HTML <p> align Attribute is used to specify the alignment of paragraph text content. Syntax: <p align="left | right | center | justify"> Attribute Values: left: It sets the text left-align.

How do you make a paragraph on the same line in CSS?

If you want to limit the text length to one line, you can clip the line, display an ellipsis or a custom string. All these can be done with the CSS text-overflow property, which determines how the overflowed content must be signalled to the user.

How do you space out elements CSS evenly?

The "space-evenly" value for the justify-content property distributes the space between items evenly. It is similar to space-around but provides equal instead of half-sized space on the edges. Can be used in both CSS flexbox & grid.


2 Answers

I know you asked for a CSS solution but I don't think there is one yet. Below is my JS solution for the meantime.

        function createBetterLineBreaks(el) {
            var originalWidth = el.offsetWidth;
            var originalHeight = el.offsetHeight;
            for (let i = originalWidth - 1; i >= 0; i--) {
                el.style.width = `${i}px`;
                if (el.offsetHeight > originalHeight) {
                    el.style.width = `${i + 1}px`;
                    break;
                }
            }
        }
        // hover effects
        document.querySelector('.box').addEventListener('mouseenter', function () {
            createBetterLineBreaks(document.querySelector('.box .text'));
        });
        document.querySelector('.box').addEventListener('mouseleave', function () {
            document.querySelector('.box .text').style.width = 'unset';
        });
        .box {
            width: 300px;
            font-size: 30px;
            border: 1px solid black;
            border-radius: 5px;
            padding: 20px;
            display: flex;
            align-items: center;
            justify-content: center;
        }
    <div class="box"><span class="text">hover this box to distribute the text more evenly</span></div>
like image 120
Sev Avatar answered Nov 07 '22 13:11

Sev


You're looking for the CSS Text Module 4 property text-wrap: balance. It has been proposed but unfortunately not yet implemented, so in the meantime, use this jQuery polyfill balance-text.

balanceText();
.box {
  width: 300px;
  font-size: 30px;
  border: 1px solid black;
  border-radius: 5px;
  padding: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.balance-text {
  text-wrap: balance;
}
<script src="//cdn.jsdelivr.net/npm/[email protected]/balancetext.min.js"></script>
<div class="box"><span class="text balance-text">The words in this sentence cause it to require three lines.</span></div>
like image 5
Spectric Avatar answered Nov 07 '22 12:11

Spectric