Chrome/Edge and Firefox wrap long hyperlinks differently. Why? - css

I have noticed that Chrome/Edge and Firefox wrap long hyperlinks differently. Firefox breaks them on the slash / character, whereas Chrome/Edge doesn't consider the slash / character special.
Is there some description about this behavior? That is:
Why is it different?
Which one is really correct?
div {
background: silver;
font-family: 'Courier New';
font-size: 16px;
max-width: 18ch; width: min-content;
}
a.bare {
overflow-wrap: break-word;
}
<div>
<p>see <a href="..." class="bare">
http://site.web/section/paaaaaaaaaaaaaaaaaaaaage.html</a></p>
</div>
overflow-wrap: break-word:
Firefox:
Chrome and Edge:
overflow-wrap: initial /* normal */:
Firefox:
Chrome and Edge:

What you're looking for is the line-break property. It specifies what characters are allowed to have line-breaks and which do not, but it's not precise. To summarize it gives some specific rules for certain characters in certain languages, but it does not specify the situation that you have asked about. It doesn't specify anything about the slash character. So since the CSS standard doesn't specify what is right, neither of these implementations are wrong.
The default value for the line-break property is auto which does the following:
The UA determines the set of line-breaking restrictions to use, and it may vary the restrictions based on the length of the line; e.g., use a less restrictive set of line-break rules for short lines.
There is another standard, the unicode line breaking algorithm, which is far more specific and it includes a little thing which says that slashes should provide a line breaking opportunity after them for the exact situation you have inquired about. URLs being as frequent as they are on the web, it makes sense to be able to do line breaks in them at slashes, and so it's in that standard.
According to the firefox source code as best as I could find, it says it follows that unicode standard, but that's not what it appears to be doing according to your example, instead the slash in firefox seems to provide a line breaking opportunity before it. Maybe someone with more in depth knowledge of the firefox source code could explain why it does that?
I'm not sure about the chrome line breaking algorithm because it's a lot more difficult to search the source code, but I imagine the developers decided that the '/' character doesn't deserve a line break under those circumstances based on the broad definition of 'auto' in the css spec.

break-word: If the exceeds the width of the line, then the word is forced to splite and wrap.
You can refer to this doc for some explanations of the value of the overflow-wrap property, and I think the results shown in Edge/Chrome are correct.
In your example, the text is treated as a single word, so when setting the attribure value to normal or initial, it will not be forced to splite. You can add a few spaces to the text and you will find out this.

Related

Dealing with Korean text breaking words

I am building a website where I am displaying korean text. The client (US local) is being very unhappy because the text is breaking in the middle of words. As example of this, here is an image: Red background text being one word.
I have tried to use
word-break: keep-all;
but it isn't supported in Chrome/Safari.
What am I able to do? I have searched the web for hours and got nothing. Is this something that is expected in cjk sites or is there a solution that I haven't found.
It is a responsive site, so I can't put in hard breaks, or fake it.
demo: http://codepen.io/cibgraphics/pen/tqzfG
Why not use jquery plugin - https://github.com/mytory/jquery-word-break-keep-all
This plugin is for it. IE has CSS property word-break: keep-all; but other browser has not.
The SPACE character generally allows a line break. This is not affected by the word-break property. To disallow a line break, use NO-BREAK SPACE instead of SPACE, e.g. 십 니까. Alternatively, wrap a sequence of characters that should not be broken in a span element and set white-space: nowrap on it.
Use the CSS rule word-break: keep-all. It's now supported in all browsers but Microsoft Edge (a change since 2014 when the accepted answer above was posted).
You can try a mixed solution in which you use CSS and JS in order to simulate words and then move them to a new line if the width is not enough.
The test I did uses a CSS class with display inline-block and then wraps each Korean word into spans.
CSS
.korean-word {
display: inline-block;
}
The use a JS/jQuery code like this:
var p = $(".hero__description");
var text = p.text();
var nospace = /(\S+)/g;
var p1 = text.replace(nospace, "<span class='korean-word'>$1</span>");
p.html(p1);
The code simply takes in a text, looks at things which are NOT spaces and then puts those things into span HTML elements. This way you force a word to go to new line.
Add both line-break:strict and word-break:keep-all into your CSS. This helps solve the problem for me.

CSS or what? Forcing the text split into multiple lines

Forcing the text split into multiple lines when it reaches the maximum width of the #div.
How can I do this? because, if I try to output data with 200 characters without spacing, I get the following:
Result 1 (no spacing):
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
Result 2 (have one space):
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa (space)
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
Expected result:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
Do I need to use the following?
result+=str.substring(0,200) "\n";
or it is a CSS styling?
Applying word-break: break-all; will make the text wrap at whatever character whenever it exceeds it's parent's width, without the need of a space or other type breakpoint.
As already stated in the accepted answer use the following:
word-break:break-all;
The W3 specification that talks about these seem to suggest that
word-break: break-all is for requiring a particular behaviour with CJK
(Chinese, Japanese, and Korean) text, whereas word-wrap: break-word is
the more general, non-CJK-aware, behaviour.
(credit: AakashM: see post)
Word-Break Property options (W3Schools):
normal Default value. Break words according to their usual rules
break-all Lines may break between any two letters
keep-all Breaks are prohibited between pairs of letters
initial Sets this property to its default value. Read about initial
inherit Inherits this property from its parent element. Read about
Working Example:
Word-Break W3Schools
make a smaller div and use CSS text-align: justify and word-break:break-all;
Is this what you want?
use div and set the width of a div
In CSS File
.respose container:{
width:200
}
And then in the html file add
<p div="response container">
if(string.length>limit)
{`return string.substring(0,limit)+'...';`
}
else
{`return string;`
}
</p>
The word-break property can be used to control the text flow. The following value would fix your issue:
word-break: break-all
More info can be found here: https://developer.mozilla.org/en-US/docs/Web/CSS/word-break
The updated answer should be:
overflow-wrap:break-word;
It will break a word that by itself would not be able to fit on its own line, but leave all other words as they are (see overflow-wrap here).
You could also use:
overflow-wrap:anywhere; but this will allow line breaks after any word in an effort to reduce the width of an element. See the difference described below from MDN:
[break-word is] The same as the anywhere value, with normally unbreakable words allowed to be broken at arbitrary points if there are no otherwise acceptable break points in the line, but soft wrap opportunities introduced by the word break are NOT considered when calculating min-content intrinsic sizes.
Also, anywhere is not supported by Internet Explore, Safari, and some mobile browsers while break-word is supported on all major browsers (see [here][2]).
word-break: break-word; should no longer be used because it is deprecated in favor of the overflow-wrap:break-word;. Now, the word-break property is intended to be used when you want to break words regardless of whether they could fit on their own line (i.e. the OP's first example with word-break: break-all.
In contrast to word-break, overflow-wrap will only create a break if an entire word cannot be placed on its own line without overflowing.
(From overflow-wrap also linked above )

Is there a CSS workaround for Firefox' bug: inline-block + first-letter with changed size

It's better to see a bug for yourself in Firefox: http://jsfiddle.net/kizu/btdVd/
The picture, showing the bug:
And the bug filled in 2007 on bugzilla.
The bug appears when you're adding ::first-letter pseudo-element with display: inline-block, and then change the font-size of this first-letter.
More letters in a word after the first: more extra space added (or subtracted — if the font-size is lesser than block's).
Adding float: left to the first-letter inverts the bug: with bigger font-size the width of inline-block shrinks.
So, the question: is there any CSS-only workaround for this bug? It's somewhat killing me.
I've found that triggering reflow on the whole page (or any block with a problem) fixes the problem, so I've found a way to trigger it on every such block with one-time CSS animation: http://jsfiddle.net/kizu/btdVd/23/
Still, while this fix have no downsides in rendering, it have some other ones:
it would work only for Fx5+ (that supports animations);
it still flashes the original bug for a few ms, so it's maybe somewhat blinky.
So, it's not an ideal solution, but would somewhat help when Fx4- would be outdated. Of course, you can trigger such fix onload with JS, but it's not that nice.
I don't think there's a good solution.
I have come up with a flaky solution for you though:
.test:first-letter {
font-size: 2em;
letter-spacing: -0.225em;
}
Add the letter-spacing style to the :first-letter selector in your Fiddle, and you'll find the blocks go back to roughly the right size.
Explanation:
Basically, the bug is being caused by the whole block taking its size from the font specified in the first-letter.
What I'm doing here with the letter-spacing is trying to adjust the size of this font, without affecting it's physical appearance. Adjusting the letter spacing in this way in normal text would result in the letters overlapping each other by .225 of a character width on either side.
I was initially hoping that a value of -0.25 would be sufficient -- ie a quarter of a character on each side would reduce the width of each character by half, which would be what we want because the first letter is font-size:2em, so it's twice as big.
However, the calculation isn't quite as clean as that, because the first and last characters in the string would only be overlapped on one side each, and because the first letter does in fact want to be double width, even if the rest of the characters don't.
All of this means that the exact letter-spacing value required to counter-act the bug will vary depending on how long the text, as well as the font sizes of the original text and the first letter. This is why I had to experiment a bit with the value of the letter spacing to get it working, and also explains why I couldn't get quite a perfect fit on all the text rows in your Fiddle. I would have needed a slightly different value for each block.
The value of -0.225 seems to be about the closest I can get to it being right for all your examples, but in practice you'll need to adjust it to suit your site.
Don't forget also that this is a Firefox bug, and therefore you'll need to write it in as a browser-specific hack of some sort. And be careful to keep an eye on the Firefox bug report you linked; when it does get fixed, you'll need to work out a way to keep your hack in place for users of old versions, but remove it for users with the fix.
[EDIT]
The only other working solution I've come up with is simply not to use the features which trigger the bug. ie drop the :first-letter selector, and use a separate <span> for the first letter of your text if you want to style it differently.
This is the obvious answer really, and would of course solve the problem (and would also mean that your styled first letter works in older browsers), but it would not be ideal from a semantic perspective, and more importantly doesn't actually answer the question, which is why I didn't offer it as a solution in my original answer.
I have been trying to find alternative work around for the bug as well, but the options are limited, and nothing I've tried has given as good results as my initial suggestion.
I tried a hack of making the :first-letter invisible, and using :before to display the big leading capital letter. However, this didn't work for me. I didn't linger on it too long so you may be able to get it working, but there is a problem with it in that you'd have to define the leading letter in your CSS, which wouldn't be ideal.
Another possible solution is to use the CSS font-stretch: condensed; property on the :first-letter. This would reduce the width of the first letter back to 1em, and thus resolve the width issue of the rest of the text. The down sides of this, however, are that firstly it would make the leading letter look squashed, which is probably not what you want, and secondly this style only works for fonts which support the condensed property. It turns out that this isn't well supported by the standard fonts, so may not be workable for you.
In the end, the original letter-spacing solution is still the only way I've found to really work around the bug.
This bug still exists, but some of the fixes don't work anymore. Even after triggering a reflow with an animation, the inline-block returned to the same size for me. I couldn't use the letter-spacing trick because I am already using it on the first letter, that is what is causing the problem for me. I solved the problem by adding this to the CSS for the affected selector:
-moz-padding-end: *number of pixels to compensate*;
At the moment, moz-padding-end seems to be specific to Firefox, and it can add or remove width to the end of the inline-block. Because this is a Firefox specific bug, that did the trick for me.
I know this thread is quite old now, but apparently this bug has not been fixed yet.
Using animation does work but there is a noticeable FOUT (Flash Of Unstyled Text). I was able to work around the problem by wrapping the first-letter in a span. This does work around both the sizing issue and the FOUT, it does add extra elements to the markup, so it depends on the needs of your site/application if this is the best fit.
.test {
background: rgba(0,0,0,0.15); /* For visualisation */
display: inline-block;
}
.test:first-letter {
font-size: 2em;
}
.test2:first-letter {
float: left;
}
.test3:first-letter {
font-size: .5em;
}
<h1>Inline-block with bigger first-letter</h1>
<span class="test">Broken</span>
<br><br>
<span class="test"><span>F</span>ixed</span>
<h1>+ floating to first-letter</h1>
<span class="test test2">Broken</span>
<br><br>
<span class="test test2"><span>F</span>ixed</span>
<h1>small size for first-letter</h1>
<span class="test test3">Broken</span>
<br><br>
<span class="test test3"><span>F</span>ixed</span>
<h1>small size, floating first-letter</h1>
<span class="test test2 test3">Broken</span>
<br><br>
<span class="test test2 test3"><span>F</span>ixed</span>
As of 2023, this is still happening in Firefox.
This is my solution using SASS, but you can see how to make it bare CSS:
txt-brand {
display:inline-block;
}
///Firefox only ///
#-moz-document url-prefix() {
margin-right: .1em;
white-space: nowrap;
&::after {
content: '\00a0';
}
}
}
.txt-brand::first-letter {
letter-spacing: -.11em;
}

Styling the first letter of a particular word, etc

I'm trying to style a word with a big first letter and spacing for the other letters. My current solution is pretty ugly: see here (and a malfunctioning jsfiddle here).
Ideally, instead of something ugly like this: <dropcap>T</dropcap><span style="letter-spacing:.2em;">HERE</span><span style="margin-left:-.2em;"> is</span> nothing more unreasonable...
I could have something sensible like this: <dropcap>THERE</dropcap> is nothing more unreasonable...
Any ideas? Thanks.
You could just use the :first-letter pseudo-element.
The :first-letter pseudo-element is
mainly used for creating common
typographical effects like drop caps.
This pseudo-element represents the
first character of the first formatted
line of text in a block-level element,
an inline block, a table caption, a
table cell, or a list item.
It's supported in IE8+ and all modern browsers.
For example: http://jsfiddle.net/HTnBP/4/
For the other half of your question, try:
T<span>HERE</span>
div > span:first-child {
letter-spacing: .2em;
margin-right: -.2em
}
http://jsfiddle.net/HTnBP/5/
I don't really see the point in using a custom dropcap element. Unless you don't mind adding extra complexity to support IE8 and lower, or you simply don't care about those browsers.
Or maybe you can use this JS solution i found
http://webplatform.adobe.com/dropcap.js/

How important is it to leave out the last ';' inside a set of CSS rules?

I've had problems with Internet Explorer not applying the last property in a list of CSS properties. Is it necessary to leave out the last ; from a list of CSS properties? For example:
.style { width: 100px; height: 100px }
Or does it really not matter?
It doesn’t matter. Even Internet Explorer 6 will accept the redundant semi-colon at the end; your mistake must have been somewhere else.
Additional advice: Be absolutely sure you don't accidentally end a line with double semicolons, like
.aStyle {
background-color: #FFFFFF;;
color: #000000;
}
This can have the extremely unhappy effect of negating every single style that comes after it on the page. It is not at all like an additional semicolon at the end of a line of Javascript, which has no effect whatsoever except to add a character to the page weight.
You don't need to include the last semi-colon. Nor do you have to exclude it. It's optional.
From a maintenance point of view, I'd actually get into the habit of including after every property. Accidentally forgetting to put one one in when editing can cause some subtle errors.
I am not aware of any issue with IE causing issues with missing semi-colon's - either that was an awful long time ago or there was some other issue that maybe lead you to believe that was the problem ;)

Resources