I have a rather long text inside an intrinsically sized div
. For visual reasons I’d like the div
to break at a given point but only when no “natural” line break would occur “before” this point:
I could achieve this by adding a <br>
, placing the text into multiple div
s etc. but I found no way to ignore this break, when the div
shrinks below the point where it would naturally break “before” that preferred break point:
Is there any technique to achieve this with pure CSS & HTML?
Example code
Here’s an example with the “static” line break via <br>
which shows the line break at the correct position when the div
is very wide but does not work as required when the div shrinks (second screenshot above):
.parent {
display: flex;
font-family: Inter;
font-size: 18px;
}
.content {
background: yellow;
padding: 8px;
}
<div class="parent">
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non orci in nunc venenatis luctus et eget mauris.<br>Pellentesque nec ante dignissim, malesuada tortor ac, rhoncus ante.
</div>
</div>
Codepen Playground
Additional note
I’m specifically looking for a solution which does not require any fixed sizing like max-width
div, media queries etc. b/c they would all be bound to the used font, font-size, browser zoom level etc. and could break e.g. when the user overrides the font(size) in his browser settings etc.
More examples
I’m adding more examples showing what I want & what I don’t want because there seems to be some confusion about my actual requirement.
In this example, I replaced the “.” at the point, where I’d like to add the break, with a “,” because I hope this makes my intention a bit more clear.
Current conclusion
I think that what I want is technically not possible with vanilla HTML & CSS at the moment and I have not heard of any upcoming proposal yet which would provide the needed tech.
I’ll probably stick to adding a fixed max-width
which is a bit hacky but should work in most cases.
8
I’m afraid, the closest thing to get with CSS-only would be to replace the <br>
line-break with a span element enclosing the desired dynamically breaking text content.
.parent {
display: flex;
font-family: Inter;
font-size: 18px;
}
.content {
background: yellow;
padding: 8px;
}
.resize {
resize: both;
overflow: auto;
outline: 1px solid #ccc;
}
/* prefer one-line layout */
.dynamicLine {
display: inline-block;
}
.content-wide {
font-size: 1.25vw;
}
/* prevent single line for very wide width */
@media (min-width:90ch) {
.dynamicLine {
display: block
}
}
<h3>Resize me</h3>
<div class="resize">
<div class="parent">
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non orci in nunc venenatis luctus et eget mauris. <span class="dynamicLine">Pellentesque nec ante dignissim, <span style="color:red; font-weight:700; font-style:italic;">malesuada</span> tortor ac, rhoncus ante.</span>
</div>
</div>
</div>
<h3>Prevent single line</h3>
<div class="content content-wide">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non orci in nunc venenatis luctus et eget mauris. <span class="dynamicLine">Pellentesque nec ante dignissim, <span style="color:red; font-weight:700; font-style:italic;">malesuada</span> tortor ac, rhoncus ante.</span>
</div>
How it works
- the last “line” is wrapped in a
<span>
element - with
display:inline-block
applied to it - therefore, this “pseudo-paragraph” is drawn to the previous line – provided there is enough space
- otherwise, this element is rendered starting on a new line
If you can’t easily wrap your content you need some JavaScript to analyze line-wrapping results (e.g by comparing element heights)
To prevent a single line layout, you may add a media query specifying the breakpoint width by ch
units like so
/* prevent single line for very wide width */
@media (min-width:90ch) {
.dynamicLine {
display: block
}
}
This approach is slightly more flexible than using em or pixels as the ch
unit is based on the zero
digit’s width – so we get a breakpoint at approximately >90 character. However, you still need an idea what would be a suitable breakpoint.
2
You could use a regular <br>
tag and hide it, when the viewport size gets smaller.
.conditional-br {
display: block;
}
@media screen and (max-width: 60em) {
display: none;
}
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non orci in nunc veneatis luctus et eget mauris.<br class="conditional-br">
Pellentesque nec ante dignissim, malesuada torror ac, rhoncus ante.
</p>
Maybe you have to try out for yourself which breakpoint fits best.
1
Something like this?
.parent {
display: flex;
font-family: Inter, sans-serif;
font-size: 18px;
}
.content {
background: yellow;
padding: 8px;
word-break: break-word; /* Ensures long words break if needed */
overflow-wrap: anywhere; /* Allows breaking opportunities */
}
<div class="parent">
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse non orci in nunc venenatis luctus et eget mauris.Pellentesque nec ante dignissim, malesuada tortor ac, rhoncus ante.
</div>
</div>
1