How to make do a centred title style where the line-breaks arranges the longest line at the bottom

Viewed 184

I have a project where some pages have titles with a large font size. The title is dynamic and can be both one or 3-4 lines. For aesthetical reasons, I would love the title to be both centered and arrange the lines so that the longest (broadest) line goes to the bottom and the shortest goes to the top. Like the shape of a pyramid.

I don't know if this is possible in pure CSS or how I should get around this?

Any suggestions? :-)

enter image description here

3 Answers

How about shape-outside? We can limit the text boundaries with two triangle shapes, one on the left and another on the right

Do note: despite of the boundaries centering the text doesn't yield the desired result, but on the contrary, justifying the text is not ideal either - the last line is not centered

div{
  text-align:justify;
  font-size:20px;
  padding:15px;
  background:rgba(200,200,100,0.5);
}

left-shape {
  shape-outside: polygon(0 0, 100% 0, 0 50%);
  width: 250px;
  height: 500px;
  float:left;
}

right-shape {
  shape-outside: polygon(100% 0, 0% 0, 100% 50%);
  width: 250px;
  height: 500px;
  float:right;

}
<left-shape></left-shape> <right-shape></right-shape>

<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>

Possible javascript solution

If you can't find CSS solutions, here's a "somewhat solution" using javascript. It may not be the best approach and may have problems if the screen width decreases because we split the two strings using a breakpoint at the end. So this solution might work for you if you have enough spacing for the title, but you might want to consider using whitespace: nowrap; with this solution.

Try changing the offset to find the best result for yourself.

// Get title element by ID:
var title = document.getElementById('title');

// Get content of the title:
var content = title.innerText;

// Where you want the text to be splitted from,
// 2 = middle, 3 = one third;
var offset = 2.5;

// Divide content by previously set amount:
var divided = Math.floor(content.length / offset);

// This gives the number of characters
// in the top part of the title
var count = content.indexOf(' ', divided);

// First part of the string,
// goes from start to "count" amount
var x = content.substring(0, count);

// Second part of the string, after count amount:
var y = content.substring(count);

// Place text back to the title,
// Using <br> might cause issues on mobile,
// but it's a rough idea what could be done.
title.innerHTML = x + "<br>" + y;
#title{
  text-align: center;
}
<h1 id="title">This is an example of the line break I want</h1>

I am no JQuery-wonder, but I have made this solution that fulfills my expectations for the alignment I requested. If your eyes hurt from this snippet, please give some suggestions for optimization. I already know that this won't work after resizing flexible elements.

I would of course prefer a solution made from pure CSS, so if you are listing W3C, the case text-align: pyramid; or even text-align: simon; (wink) is now officially requested.

$('#title').each(function(){

    var words = $(this).text().split(/\s+/);
    var total = words.length;
    var originalWidth = $(this).css("width");
    var maxWidth = $(this).width();
    var tempText = $(this);
    var string = "";
    var currentLineString = "";

    $(this).empty();
    tempText.css("width", "auto");

    for (i = 0; i < total; i++){

        var newString = words[total-i-1] + " " + currentLineString;
        tempText.text(newString);

        if (tempText.width() >= maxWidth) {
            tempText.text(currentLineString);
            maxWidth = tempText.width();
            string = currentLineString + "<br>" + string;
            currentLineString = "";
            i--;
        } else {
            currentLineString = newString;
        }
    }
    string = currentLineString + "<br>" + string;
                
    tempText.css("width", originalWidth);
    $(this).html(string);
});
Related