How to use ­ and the CSS "hyphens" property together? - html

I'm using the hyphens property of CSS: https://developer.mozilla.org/en-US/docs/Web/CSS/hyphens Mozillas documentation says:
Suggested line break opportunities, as covered in Suggesting line break opportunities, should be preferred over automatically selecting break points whenever possible.
I thought that means the browser places hyphens as needed unless there is something like a ­. If that's the case the ­ will be prioritised.
But I have this code:
.box {
width: 130px;
border: 1px solid red;
margin-bottom: 5px;
}
.box > a {
text-transform: uppercase;
font-size: 12px;
-moz-hyphens: auto;
-webkit-hyphens: auto;
-ms-hyphens: auto;
hyphens: auto;
}
<div class="box">
subdermat­oglyphic
</div>
<div class="box">
subdermatoglyphic
</div>
Now I would assume the word breaks after "subdermat". But it doesn't. It breaks after "subdermato". At least in Firefox 33. This result may be different in other browsers. I know that this is "experimental technology" but maybe I'm missing something. Is something wrong with my implementation?

There is nothing wrong with your code from the HTML and CSS perspective. Whether the (preferred) hyphenation is correct is of course a different issue.
But Firefox does not actually implement the logic that the MDN page describes. The page just echoes an old version of the CSS3 Text draft. The current editor’s draft puts things even much stronger (and rather questionably), for hyphens: auto (the default): “Automatic hyphenation opportunities within a word must be ignored if the word contains a conditional hyphen (­ or U+00AD), in favor of the conditional hyphen(s). However, if, even after breaking at such opportunities, a portion of that word is is still too long to fit on one line, an automatic hyphenation opportunity may be used.”
What Firefox actually does, as far as we can judge from its behavior, is that it treats ­ as suggesting a hyphenation opportunity, equal to the opportunities it has determined on the basis of its hyphenation algorithms, if used (this depends on the declared language and on installed support to various languages in the browser).
This means that when used together with automatic hyphenation, ­ is not (currently) useful in suggesting preferred hyphenation points (i.e. points to be preferred over others that might have been determined by a browser’s hyphenator). However, it is useful for suggesting hyphenation points that would not otherwise be used.
If you actually wanted to have “subdermatoglyphic” hyphenated so that hyphenation is possible between “t” and “o” but not between “o” and “g” (where most authorities allow hyphenation), you could write subdermat­<span style="white-space: nowrap">og</span>lyphic. But it’s probably not worth it.

Related

CSS: hyphens: auto doesn't work for some words

Can anyone explain why the following snippet won't correctly hyphenate the word "Sustainability"? I tested this in Google Chrome, FireFox and Safari, none of them hyphenates the word, but all of them correctly hyphenate the word "hyphenated".
My observations so far:
If the word is not capitalized, hyphenation starts working
If I change the lang attribute from en to de (german), it also starts working, although the word is an english word
:root {
font-size: 20px;
font-family: system-ui;
padding: 2rem;
}
body {
margin: 0;
}
p {
border: 1px solid;
width: 100px;
hyphens: auto;
}
<html lang="en">
<body>
<p>The word Sustainability can't be hyphenated, apparently</p>
<p>Only if written without a capital "S", it starts working: sustainability 🤔</p>
</body>
</html>
It's defined in the specs: https://www.w3.org/TR/css-text-3/#hyphenation
"The UA may use language-tailored heuristics to exclude certain words from automatic hyphenation. For example, a UA might try to avoid hyphenation in proper nouns by excluding words matching certain capitalization and punctuation patterns. Such heuristics are not defined by this specification. (Note that such heuristics will need to vary by language: English and German, for example, have very different capitalization conventions.)"
This must be an intended behavior due to language rules. At this point, there aren't many hyphenation control mechanisms and browsers are free to decide how to do the hyphenation when hyphens: auto.
As a workaround, you could use soft wrap character like U+00AD or &shy HTML entity.

overflow-wrap: break-word vs. word-break: break-word

What is the difference between overflow-wrap: break-word and word-break: break-word?
As you see from the following example, there is no visual difference between option-1 and option-2. (You need to uncomment either one.)
body {
width: 300px;
}
.dont-break-out {
/* Option 1 */
/* overflow-wrap: break-word; */
/* Option 2 */
/* word-break: break-word; */
}
<p class="dont-break-out" lang="en-US">For more information, please visit: http://csstricks.com/thisisanonexistentandreallylongurltoaddtoanytextinfactwhyareyoustillreadingit.</p>
<p class="dont-break-out" lang="en-US">According to Wikipedia, The longest word in any of the major English language dictionary is pneumonoultramicroscopicsilicovolcanoconiosis, a word that refers to a lung disease contracted from the inhalation of very fine silica particles, specifically from a volcano; medically, it is the same as silicosis.</p>
Not dupes:
Difference between overflow-wrap and word-break? - The accepted answer is just few small quotes from MDN and there are no examples. To be honest, I'm not sure that the person who posted it really understands the difference himself.
Do `overflow-wrap: break-word` and `word-break: break-word` ever behave differently? - Again, no example, and so it is very hard to understand what is really assumed.
Please, could you provide an example to show a difference between them?
And yes, I know that word-wrap is an alias to overflow-wrap. My question is not about it.
edit
An interesting remark by Louis Lazaris on CSS Tricks:
overflow-wrap and word-break behave very similarly and can be used to solve similar problems. A basic summary of the difference, as explained in the CSS specification is:
overflow-wrap is generally used to avoid problems with long strings causing broken layouts due to text flowing outside a container.
word-break specifies soft wrap opportunities between letters commonly associated with languages like Chinese, Japanese, and Korean (CJK).
After describing examples of how word-break can be used in CJK content, the spec says: "To enable additional break opportunities only in the case of overflow, see overflow-wrap".
From this, we can surmise that word-break is best used with non-English content that requires specific word-breaking rules, and that might be interspersed with English content, while overflow-wrap should be used to avoid broken layouts due to long strings, regardless of the language used.
But Louis haven't provided any examples. I performed the same test as above with the following text from the work-break page by MDN:
Honorificabilitudinitatibus califragilisticexpialidocious Taumatawhakatangihangakoauauotamateaturipukakapikimaungahoronukupokaiwhenuakitanatahu 次の単語グレートブリテンおよび北アイルランド連合王国で本当に大きな言葉
... and there is still no difference between overflow-wrap: break-word and word-break: break-word.
The difference lies in the way min content intrinsic sizes are calculated. Soft wrap opportunities introduced by the break are taken into account for word-break:break-word but not for overflow-wrap:break-word. So for an example of the difference between them, we need to choose something that sizes according the min content intrinsic size, such as a float:
body {
width:160px;
}
p {
float:left;
border:1px solid;
}
.overflow-wrap {
overflow-wrap: break-word;
}
.word-break {
word-break: break-word;
}
<p>A popular long word in Engish is
<i class="overflow-wrap">antidisestablishmentarianism</i>,
although longer more contrived words exist</p>
<p>A popular long word in Engish is
<i class="word-break">antidisestablishmentarianism</i>,
although longer more contrived words exist</p>
word-break:break-word has the same effect as overflow-wrap:anywhere.
Looks like overflow-wrap provides more opportunities for the text to wrap.
I modified your code to show both cases, one after the other, for easier comparison.
Edit: good catch on the missing { - after fixing that I agree there appears to be no difference.
I'll leave this answer here as it is still a good code sample for testing alternatives.
body {
width: 300px;
}
.break-1 {
overflow-wrap: break-word;
}
.break-2 {
word-break: break-word;
}
<p class="break-1" lang="en-US">For more information, please visit: http://csstricks.com/thisisanonexistentandreallylongurltoaddtoanytextinfactwhyareyoustillreadingit.</p>
<p class="break-2" lang="en-US">For more information, please visit: http://csstricks.com/thisisanonexistentandreallylongurltoaddtoanytextinfactwhyareyoustillreadingit.</p>
<p class="break-1" lang="en-US">According to Wikipedia, The longest word in any of the major English language dictionary is pneumonoultramicroscopicsilicovolcanoconiosis, a word that refers to a lung disease contracted from the inhalation of very fine silica particles, specifically from a volcano; medically, it is the same as silicosis.</p>
<p class="break-2" lang="en-US">According to Wikipedia, The longest word in any of the major English language dictionary is pneumonoultramicroscopicsilicovolcanoconiosis, a word that refers to a lung disease contracted from the inhalation of very fine silica particles, specifically from a volcano; medically, it is the same as silicosis.</p>
<p class="break-1">Honorificabilitudinitatibus califragilisticexpialidocious Taumatawhakatangihangakoauauotamateaturipukakapikimaungahoronukupokaiwhenuakitanatahu 次の単語グレートブリテンおよび北アイルランド連合王国で本当に大きな言葉</p>
<p class="break-2">Honorificabilitudinitatibus califragilisticexpialidocious Taumatawhakatangihangakoauauotamateaturipukakapikimaungahoronukupokaiwhenuakitanatahu 次の単語グレートブリテンおよび北アイルランド連合王国で本当に大きな言葉</p>
OK, it seems I have found the answer, but I'm not really sure.
As per a comment at GitHub, it seems that overflow-wrap: break-word is now catches all cases of word-break: break-word, and so the latter one is redundant except if used for a backward compatibility.
Note that the behavior of this feature—allowing breaks anywhere if the word cannot fit its container (per word-wrap/overflow-wrap: break-word) and also having these break opportunities affect the min-content size—is now specified for word-wrap/overflow-wrap: break-word. See #2682
This means that once implementations catch up, there is no use case requiring word-break: break-word to be added (since overflow-wrap: break-word now has this behavior), and the only reason to add this second syntax would be if it's needed for Web-compat.

How to break word into two parts and put them under each other [duplicate]

I'm using word-break: break-all; and want to know how I can have the browser automatically insert the hyphens, as demonstrated in an MDN example.
div {
width: 80px;
height: 80px;
display: block;
overflow: hidden;
border: 1px solid red;
word-break: break-all;
hyphens: auto;
-ms-hyphens: auto;
-moz-hyphens: auto;
}
<div>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</div>
Such that the text would look like this:
aaaaaaaa-
aaaaaaaa-
aaaaaaaa-
aaaaaaaa
I created a JSFiddle too.
This needs to work in IE9/IE10, but it'd be nice if it'd work in Firefox and Chrome as well.
The word-break property and hyphenation are two completely different things. The first one, originally intended for East Asian languages mainly, does bad things to languages like English: it arbitr arily cuts w ords at some poi nts without ind icating that a word has been broke n.
So you should decide whether you have an expression where a line break can be inserted by a browser at any point or whether you want hyphenation.
For hyphenation, the CSS code as such is OK, though many people would advice putting the standard property setting hyphens: auto last, after prefixed properties. But it requires that the language of the text be declared in HTML markup, using e.g. <div lang=en>. Moreover, browser support is still limited: IE 9 does not support such hyphenation, and the support in IE 10 covers a relatively small set of languages (including English of course).
For automatic hyphenation on IE 9, you would need to use either server-side programmed hyphenation or, simpler, client-side hyphenation with tools like Hyphenator.js.
The -ms-hyphens property only works in IE10+. It's not possible in IE9 or below.
See the browser compatibility chart at the bottom of the reference link you provided.
It doesn't work in Chrome yet: WebKit Hyphenation
Hyphens are inserted if the browser supports & language includes a hyphenation dictionary.
But your
aaaaaaaaaaaaaaaaaa
isn't in a dictionary.
Therefore you have to insert soft hyphens ­ to your satisfaction like in https://jsfiddle.net/LJYj3/5/
Here's more food for thought: https://stackoverflow.com/a/856322/1696030
I was not able to find any css solution for this, so fix it with js.
const addWordBreaks = (str, maxLength = 10) => {
const words = str.split(" ");
const newWords = [];
words.forEach(function(word) {
if (word.length > maxLength) {
const firstWord = word.substr(0,maxLength);
const endWord = word.substr(maxLength, word.length-1);
newWords.push(firstWord +"- \n");
newWords.push(endWord)
} else {
newWords.push(word)
}
});
return newWords.join(" ");
}

Is it possible to enable auto-hyphenation in HTML/CSS?

My client has requested to enable auto-hyphenation on this page: http://carlosdinizart.com/biography/ , and I realized I've never actually seen it done on a web-page.
Is it possible to set up auto-hyphenation in an HTML document with just HTML/CSS? If not - what are the options?
CSS3 provides some support for this. Source: http://drublic.de/blog/css3-auto-hyphenation-for-text-elements/
You can check the w3c documentation here: http://www.w3.org/TR/2011/WD-css3-text-20110901/#hyphenation
CSS3 adds six properties to the list of useful thing. These are:
The most important one is hyphens.
You can add dictionary-files with hyphenate-resource so the browser has a better chance to render your text with the right hyphenation.
hyphenate-before sets a minimum number of characters before the hyphenation.
hyphenate-after does the same as hyphenate-before but for characters after the hyphenation.
hyphenate-lines defines about how many lines a hyphenated word is written at a maximum.
with hyphenate-character you can specify which HTML-entity should be used, e.g. \2010.
The main property of this stack is hyphens. It accepts one of three values: none, manual or auto. The default one is manual, where you can set hyphens via ­. auto it the better one for continuous text while words get split if possible and available. And none does not hyphenate at all even if there is a character set for a possible line break in a certain word.
Update:
Browser support information here: http://caniuse.com/css-hyphens
An option is to insert soft hyphens into the text in places where it may be broken. The soft hyphen is represented by the entity ­ in HTML. You may find libraries/tools that can prepare text automatically with ­s in the right places, otherwise you'll have to do it manually.
To deal with one page that has fixed width for text, the practical move would be to add a couple of SOFT HYPHEN characters (U+00AD), using the entity reference ­ if you find it more comfortable than entering the (invisible) character itself. You can rather quickly find out which words need to be hyphenated to produce a good result.
In a more complex case (several pages, flexible width), use a preprocessor, or server-side code, or client-side code that adds soft hyphens. The client-side approach is simplest and can be applied independently of server-side technologies and authoring tools. Beware that automatic hyphenation may go wrong and needs some help: the language(s) of the text need to be indicated in markup (or otherwise, depending on the library used).
At the minimum, you could just put the attributes lang=en class=hyphenate into the <body> tag and the following code in the head part:
<script
src="http://hyphenator.googlecode.com/svn/tags/Version%204.0.0/Hyphenator.js">
</script>
<script>Hyphenator.run();</script>
Demo: http://bytelevelbooks.com/code/javascript/hyphenation.html (flexible-width text, with just maximum width set, so you can test it varying the browser window width).
At present my css for <p> is
p {
font-style: normal;
padding: 0;
margin-top: 0;
margin-left: 0px ;
margin-right: .5em ;
margin-bottom: 0;
text-indent: 1em;
text-align: justify;
-webkit-hyphens: auto;
-moz-hyphens: auto;
-ms-hyphens: auto;
-o-hyphens: auto;
word-break:break-word;
hyphens: auto;
}
This doesn't work for Chrome 39 on Mac. Known not to work on Opera.
Works for Firefox, iOS Safari.
This is NOT foolproof: Narrow columns (under 6 words) are ugly, but overall it makes the layout look far more like properly set type.

What is the best way to break HTML text on slashes (/)?

I have an HTML table 360px wide, which works great. The challenge is that sometimes a url appears http://this/is/a/really-really-really-really-really/long/url in the text. This causes the table to expand horizontally and a scroll bar appears on the bottom.
I don't think overflow:hidden will work because half of the text would be hidden.
What is the best way to force breaking the line on slashes (/) and dashes (-) in CSS (hopefully)?
It should work with IE7+, Chrome, Firefox and Safari.
Working in Rails 3 and jQuery.
tl;dr; (edited Apr 2022)
Use <wbr> word-break-opportunity element before each /. See first link in further reading below.
Details (original from 2014)
While the css word-wrap: break-word; does work, its implementation is different across browsers.
If you have control of the content and want exact breakpoints, you can insert
a <wbr> word break (supported in all major browsers except IE8 CanIUse.com);
​ zero-width space (U+200B) - ugly in IE<=6
­ soft hyphen - though of course this adds a hyphen when breaking which is not always what is desired.
I have a large corporate user base who still have to use IE8, so when I hit this problem I used the C# someString.Replace("/", "/​") in the server-side code.
Gotcha: If you insert a zero-width space in an email address, when a user copies and pastes into their email client, the space gets copied too and the email will fail with no way for a user to see why (the space is zero width ...)
References
Stack Overflow
http://www.quirksmode.org/oddsandends/wbr.html - with examples
Further Reading
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr#example
https://developer.mozilla.org/en-US/docs/Web/CSS/word-break
https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-wrap
https://kenneth.io/blog/2012/03/04/word-wrapping-hypernation-using-css/ (March 2012)
https://css-tricks.com/almanac/properties/w/word-break/ (Sep 2012)
https://css-tricks.com/almanac/properties/h/hyphenate/ (Sep 2011)
You can use word-wrap : break-word; like so:
div {
width : 50px;
border : 1px solid #000;
word-wrap : break-word;
}
<div>http://www.aaa.com/bbb/ccc/ddd/eee/fff/ggg</div>
I tested this in: I.E. 6/7/8, Firefox 7, Opera 11, Safari 5, Chrome 15
Here is a jsfiddle: https://jsfiddle.net/p4SxG/
If you don’t really care where the breaks happen, the simplest method is to add the style overflow-wrap: break-word;. This will allow long words to break without affecting the breaking of other words.
But if you want to break at specific characters, such as the slash character, you can’t do that with CSS, you have to do it in HTML. If you have access to the HTML code you can choose any of these solutions:
<wbr> word break opportunity tag
​ zero width space
&ZeroWidthSpace; zero width space
But you don’t always have access to the HTML code. Some web applications won’t allow you to enter code into certain fields; for example, WordPress will filter out any code you enter into a post title. In these situations you may be able to insert a zero-width-space character directly. One way to do this is to use Character Viewer (Mac) or Character Map (Windows), although of course they are a bit tricky to use when it comes to spaces because spaces are invisible. In the case of Character Viewer, when you search for arrow, lots of matches appear, but when you search for zero width space, it appears that no characters were found. But if you click where the blue square is in the second image below, you’ll discover that the character was found, it’s just invisible.
A snippet to demonstrate that these various methods all work:
h1 {
width: 15rem;
border: 1px solid black;
}
.b {
overflow-wrap: break-word;
}
A title which is too long
<h1>Seminars/Workshops</h1>
Breaking with CSS
<h1 class="b">Seminars/Workshops</h1>
Breaking with HTML: code-based solutions
<h1>Seminars<wbr>/<wbr>Workshops</h1>
<h1>Seminars​/​Workshops</h1>
<h1>Seminars&ZeroWidthSpace;/&ZeroWidthSpace;Workshops</h1>
Breaking with HTML: character-based solution
<h1>Seminars​/​Workshops</h1>