0

How can I make the p-element in my example below adjust its width based on the text inside without changing the normal break behavior (with CSS only - if possible)?
It seems like it's ignoring the wrapping - it's way too wide:
Example
In red I marked the space that I want to be gone - it should only go to the end of the longest line and then add those 10px margin before the border.

.message {
  width: 170px;
}

.message p {
  padding: 10px;
  border: solid;
}
<div class="message">
  <a>
    <p>
      Trylalalala- and Lololololol
    </p>
  </a>
</div>

EDIT
As this question has been marked as duplicate a duplicate I can not answer it anymore - but I'd like to mention which one of the answers from similar questions worked in my case:
My favorite with the least amount of code:
https://stackoverflow.com/a/32012946/4120196

.message {
  width: 170px;
}

.message p {
  padding: 10px;
  border: solid;
  width: -moz-min-content;
  width: -webkit-min-content;
  width: min-content;
}
<div class="message">
  <a>
    <p>
      Trylalalala- and Lololololol
    </p>
  </a>
</div>

One downside in this particular example: It forces another line-break making it 3 lines of text (as mentioned in a comment - it causes a line-break after every word):
3-lines

The accepted answer also worked - even without causing an additional line-break - but since I'm not using jQuery I went with the one above.

$.fn.fixWidth = function () {
    $(this).each(function () {
        var el = $(this);
        // This function gets the length of some text
        // by adding a span to the container then getting it's length.
        var getLength = function (txt) {
            var span = new $("<span />");
            if (txt == ' ')
                span.html('&nbsp;');
            else
                span.text(txt);
            el.append(span);
            var len = span.width();
            span.remove();
            return len;
        };
        var words = el.text().split(' ');
        var lengthOfSpace = getLength(' ');
        var lengthOfLine = 0;
        var maxElementWidth = el.width();
        var maxLineLengthSoFar = 0;
        for (var i = 0; i < words.length; i++) {
            // Duplicate spaces will create empty entries.
            if (words[i] == '')
                continue;
            // Get the length of the current word
            var curWord = getLength(words[i]);
            // Determine if adding this word to the current line will make it break
            if ((lengthOfLine + (i == 0 ? 0 : lengthOfSpace) + curWord) > maxElementWidth) {
                // If it will, see if the line we've built is the longest so far
                if (lengthOfLine > maxLineLengthSoFar) {
                    maxLineLengthSoFar = lengthOfLine;
                    lengthOfLine = 0;
                }
            }
            else // No break yet, keep building the line
                lengthOfLine += (i == 0 ? 0 : lengthOfSpace) + curWord;
        }
        // If there are no line breaks maxLineLengthSoFar will be 0 still. 
        // In this case we don't actually need to set the width as the container 
        // will already be as small as possible.
        if (maxLineLengthSoFar != 0)
            el.css({ width: maxLineLengthSoFar + "px" });
    });
};

$(function () {
    $(".message p").fixWidth();
});
  .message {
    width: 170px;
  }
  .message p {
    padding: 10px;
    border: solid;
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="message">
  <a>
    <p>
      Trylalalala- and Lololololol
    </p>
  </a>
</div>
Cold_Class
  • 3,214
  • 4
  • 39
  • 82
  • you cannot do this – Temani Afif Jan 24 '23 at 20:42
  • With JS and not using CSS. The CSS solution you mentioned is not a solution because it will force all the possible line breaks: https://jsfiddle.net/8Lj2n01s/ .. PS: don't add answers inside a question. A question need to remain a question – Temani Afif Jan 25 '23 at 00:05
  • @TemaniAfif The CSS was a valid solution for my specific case - also as I mentioned in my edit - if I were able to post it as an answer I would have. – Cold_Class Jan 25 '23 at 11:33
  • you don't have to provide any answer (especially withing the question). The purpose of duplicate is to have all the answers in the same place and avoid adding the same answer again. Please don't edit your question again otherwise it will get locked by moderators – Temani Afif Jan 25 '23 at 13:55

1 Answers1

0

There is a handy css property called word-break that suits your need. Setting word-break to break-all tells the browser it can break a word at any character.

Other options are:

  • normal: Will break a sentence at the end of a word to prevent overflow, but won't break a word.

  • keep-all: Won't break sentences or words.

  • break-all: Will break a word at any character to prevent overflow.

  • break-word: Prioritizes breaking sentences over words, but will break words if need to be (i.e. if a word is wider than the available space.

  • initial: Sets the word-break to its default value.

  • inherit: Sets the word-break to the value of the parent.

Example solution:

<style>
  .message {
    width: 170px;
    border: solid;
  }
  .message p {
    margin: 10px;
    word-break: keep-all;
  }
</style>
<div class="message">
  <a>
    <p>
      Trylalalala- and Lolololololsssssssssssssssssssssssssssssssssssssssssssssssssssssssss
    </p>
  </a>
</div>
Johalternate
  • 364
  • 3
  • 6
  • Thanks, but this changes the wrapping :( - I want it to keep breaking after "and". And when I try break-word, I have the initial problem again. – Cold_Class Jan 24 '23 at 17:28
  • 1
    There is no pure CSS solution for this problem but you can check out this article for alternatives. https://css-tricks.com/fitting-text-to-a-container/ Also, keep in mind that it is customary that when you edit your question you make an edit note appending new information/details. Check this example. https://stackoverflow.com/questions/11037831/filename-timestamp-in-windows-cmd-batch-script-getting-truncated – Johalternate Jan 24 '23 at 18:01