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.
Related
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 ­ HTML entity.
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(" ");
}
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">
subdermatoglyphic
</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.
This question is geared towards CSS3, I've been looking at a few boilerplate templates and guides and most of them declare a whole lot of attributes before even going into what you want to edit.
Why is this so? Does declaring all of the usable attributes make the
browser load faster or something?
What are the benefits? Why not just use CSS3 "as is" (like just declaring what's being used in the HTML section)?
And if the underlying attribute changes in further editions, wouldn't
it mean you would have to constantly keep a check on deprecated
attributes and keep declaring and changing attributes every once in a while?
HTML5Boilerplate contains a version of normalize.css. Rather than just reset everything to 0 (i.e. margins, padding etc) it has the minimum set of changes to ensure things have the same settings in all browsers. In their own words:
“Normalize.css is a customisable CSS file that makes browsers render
all elements more consistently and in line with modern standards. We
researched the differences between default browser styles in order to
precisely target only the styles that need normalizing.”
An example of a style used here is:
/*
* 1. Correct text resizing oddly in IE6/7 when body font-size is set using em units
* 2. Prevent iOS text size adjust on device orientation change, without disabling user zoom: h5bp.com/g
*/
html {
font-size: 100%;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
This fixes some weirdness in older IE, as well as on iOS. This is the sort of thing that you'll likely have a problem with, read loads, find a solution and add in eventually yourself. By using this set of defaults you can avoid a lot of weirdness.
As well as bugs, it includes things you'd likely want anyway:
nav ul,
nav ol {
list-style: none;
list-style-image: none;
margin: 0;
padding: 0;
}
Using a ul in a nav is a common pattern, and you usually don't want bullet points there. This sorts that for you.
In all, I'd recommend using your own custom version of their code – it will save you a lot of annoyance!
Also if you want to add CSS3 functionality you can add it to ie5 with javascript(not to say this doesn't come with its cons) with html5shiv or html5shim .
Also lets examine the definition of the acronym CSS. Cascading Style Sheets. You may declare styles in order of fall back. i. e.
body {
style-1: new browsers (this renders yay!)
style-2: semi-new browsers (don't understand style-1 I will ignore ahh style2)
style-3: ie5(me want to crash soon or BOD you. but me not get either 1 or 2 they smart but i think i can work on style 3)
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
​ 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​/​Workshops</h1>
Breaking with HTML: character-based solution
<h1>Seminars/Workshops</h1>