I'm trying to get hyphens working on text that has <span> elements inside for highlighting. This seems to break the hyphen algorithm. Is there any way to fix the behaviour so that hyphens are placed the same as without <span> elements?
I'm not asking about a workaround like
The Code (sandbox: https://codepen.io/anon/pen/ayzxpM):
.limit {
max-width: 50px;
hyphens: auto;
font-size: 20px;
background-color: #eee;
}
span {
color: red;
}
<div class="limit">
<p>
Appletreefruitthing
</p>
<p>
Apple<span>tree</span>fruitthing
</p>
</div>
Using the lang attribute
Adding the lang attribute as Vadim Ovchinnikov suggested (<div class="limit" lang="en">) can lead better results on some platform/browser combinations. On Firefox 54, Windows 10 this is the result:
But even that seems buggy. The hyphen should be black in my opinon and the hyphen algorithm seems to miss the chance to make a line break between "fruit" and "tree", also completly ignoring the max-width that is set for the container.
Actually, it does work with spans, in a number of browsers. You just used a word that is not recognized. Here's an example with a normal English word, that works in IE (should also work in Edge) and FF on Win7:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1">
<title>Demo</title>
<style>
div {
max-width: 50px;
-webkit-hyphens: auto;
-moz-hyphens: auto;
-ms-hyphens: auto;
hyphens: auto;
font-size: 20px;
background-color: #eee;
}
span {
color: red;
}
</style>
</head>
<body>
<div>
<p>Incomprehensibilities</p>
<p>Incom<span>pre</span>hensibilities</p>
</div>
</body>
</html>
It does not work in Chrome on Win, because that currently (June 2018) still does not support hyphens at all. It also does not work in any iOS browser. So you will have to use soft hyphens after all. But as you stated that you were curious about the mechanism, I thought it worthwhile to still post this answer.
Chrome has only partial support for hyphens property (only Mac and Android platforms), so you can't make it work on Windows.
I don't see any difference between span presence and absence in Firefox, IE and Edge (all on Windows) for this code.
To make it work there you'll need set lang for container and add vendor prefixes (for -ms-hyphens IE/Edge and -webkit-hyphens for Safari). Demo:
.limit {
max-width: 50px;
font-size: 20px;
/* Safari */
-webkit-hyphens: auto;
/* IE, Edge */
-ms-hyphens: auto;
hyphens: auto;
background-color: #eee;
}
span {
color: red;
}
<div class="limit" lang="en">
<p>
Appletreefruitthing
</p>
<p>
Apple<span>tree</span>fruitthing
</p>
</div>
To work in all browsers you may shouldn't use CSS hyphens property, just insert manually where you want hyphens.
.limit {
max-width: 50px;
font-size: 20px;
background-color: #eee;
}
span {
color: red;
}
<div class="limit">
<p>
Appletreefruitthing
</p>
<p>
Apple<span>tree</span>fruitthing
</p>
</div>
hyphens: manual
togteher with
might work
see documentation here
https://css-tricks.com/almanac/properties/h/hyphenate/
this code on codepen seems to work
<div class="limit">
<p>
Appletreefruitthing
</p>
<p>
Apple<span>tree</span>fruitthing
</p>
</div>
CSS
.limit {
hyphens: manual;
}
Related
I recently switched from overflow-wrap to hyphens for breaking text between lines. However, I have encountered a case that seemingly fails to hyphenate any words before a certain substring. I am at a loss as to why this could be.
Observe the gif below, the full string to be displayed is /people/type:astronauts/name-gregory-chamitoff/profile however when the width is less than about 210px none of the words in the substring /people/type:astronauts/name- are ever hyphenated and pushed to the next line. But, longer that 210px the hyphenation works fine. It's almost like it's treating this substring as a continuous word.
.test {
font-size: 20px;
width: 210px;
/* adding this works but defeats the use of hyphens
overflow-wrap: break-word;
*/
hyphens: auto;
overflow: hidden;
background-color: white;
}
html {
background-color: black;
}
<div class="test">/people/type:astronauts/name-gregory-chamitoff/profile</div>
The only thing I have found that fixes this is to use something like that below as a catch-all. This is great however, it does not prioritize hyphenating over breaking of the words. I am looking for other solutions than this that makes hyphens work for all or most strings, or even this one case!
.test {
overflow-wrap: break-word;
word-wrap: break-word;
word-break: break-all;
word-break: break-word;
hyphens: auto;
}
As #Salman A has pointed out, quite a lot of characters (e.g like slashes or colons, undescores etc.) are not recognized as proper word/syllable joints. Strings like "chamitoff/profile" will be treated as one long compound word "chamitoffprofile".
When it comes to URL like strings, you don't want to overflow – you'd still be better off with something like word-break: break-word;
Speaking of css hyphens property: its capabilities are still 'limited' (at least in 2021).
E.g. Chrome has introduced support for this feature in version 88 (according to caniuse).
Here's a resizable snippet:
*{
box-sizing:border-box;
}
body{
font-family: 'Segoe UI';
font-size: calc(1.75vw + 1.75vh / 2);
padding: 10px;
}
.resizable{
width: 20ch;
height: 10em;
hyphens: auto;
resize:both;
overflow:auto;
padding-right:1em;
border: 1px solid #ccc
}
.resizable p{
hyphens: auto;
}
.break-words{
hyphens: none;
word-break: break-word;
}
<h2>Example</h2>
<div class="resizable">
<p>people/type:astronauts/name-gregory-chamitoff/profile <br /><strong>Original</strong></p>
<p>peopletype:astronautsname-gregory-chamitoffprofile <br /><strong>Dash replaced by hyphens</strong></p>
<p>peopletype_astronautsname_gregory_chamitoff_profile <br /><strong>Dash replaced by underscores</strong></p>
<p>peopletype astronautsname-gregory-chamitoffprofile <br /><strong>Dash and colons replaced by hyphens</strong></p>
<p>peopletype astronauts name gregory chamitoff profile <br /><strong>Dash replaced by spaces</strong></p>
<p class="break-words">people/type:astronauts/name-gregory-chamitoff/profile <br /><strong>Dash replaced by spaces</strong></p>
</div>
<h2>URLs</h2>
<div class="resizable">
<p>https://www.maybeweshouldhaveoptedfor ashorterdomain.com/contact/specialinterest?product_id=1234567878 <br /><strong>URL – "hyphenated"</strong></p>
<p class="break-words">https://www.maybeweshouldhaveoptedfor ashorterdomain.com/contact/specialinterest?product_id=1234567878 <br /><strong>URL – word-break</strong></p>
<p class="break-words">contact#maybeweshouldhaveoptedfor ashorterdomain.com <br /><strong>Email example</strong></p>
</div>
Unless browsers/css-implementations widely support improved hyphenation concepts like hyphenate-limit-chars (... formerly existent) or hyphenation exception rules you should really curb your enthusiasm.
Conclusion
(2021 – hopefully we'll see improvements the next years)
You still have to choose between an imperfect 'brute-force' method like word-break – at least preventing undesired overflows
and an inelaborate (... to be very polite) css based hyphenation property/feature that's still missing any mandatory fine grained controls.
I am not sure if it is what are you looking for:
.test {
hyphens: auto;
color:white;
}
html {
background-color: black;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body >
<div class="test">/people/type:­astronauts/­name-gregory-chamitoff/profile here i have another words</div>
</body>
</html>
When I add a margin to .child in the following code IE8 ignores it. In modern browsers the same code is working as expected. What is causing this?
<html lang=“de“ xml:lang=“de“ xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv=“Content-Type“ content=“text/html“; charset=“iso-8859-1“ />
<title></title>
<style>
.parent {
margin: 5px;
border: 10px solid blue;
position: relative;
}
.child {
margin: 10px;
border: 10px solid red;
padding: 4px;
}
</style>
</head>
<body>
<div class="parent">
<p class="child" style="width:80%; position:relative; left:10px; top:10px; background-color:yellow;">I'm the CHILD!
<span id="textOutput"></span>
</p>
</div>
</body>
</html>
The problem is that you have not supplied a doctype which means that IE8 does not know what rendering mode to use and is therefore defaulting to quirks mode. Quirks mode is essential an old, non-standard layout engine used back when the web was young:
There are now three modes used by the layout engines in web browsers: quirks mode, almost standards mode, and full standards mode. In quirks mode, layout emulates nonstandard behavior in Navigator 4 and Internet Explorer 5. This is essential in order to support websites that were built before the widespread adoption of web standards. In full standards mode, the behavior is (hopefully) the behavior described by the HTML and CSS specifications. In almost standards mode, there are only a very small number of quirks implemented.
Quirks Mode and Standards Mode (https://developer.mozilla.org/en-US/docs/Quirks_Mode_and_Standards_Mode)
Browsers handle a lack of doctype in different ways and you should always ensure that you specify one at the beginning of you HTML to ensure consistent rendering of your page. At time of writing I would recommend the HTML5 doctype as it is short, clear and supported as far back as IE6.
<!DOCTYPE html>
<html lang="de" xml:lang="de" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title></title>
<style>
.parent {
margin: 5px;
border: 10px solid blue;
position: relative;
}
.child {
margin: 10px;
border: 10px solid red;
padding: 4px;
}
</style>
</head>
<body>
<div class="parent">
<p class="child" style="width:80%; position:relative; left:10px; top:10px; background-color:yellow;">I'm the CHILD!
<span id="textOutput"></span>
</p>
</div>
</body>
</html>
It should also be noted that you need to use normal quotation marks not curly quotes for your attribute values and need a closing html tag.
I am attempting to use CSS Hyphens. They work in IE 11 and Safari but does not work in Firefox properly and I am unsure why. Here is an example:
.container{
width: 16.6667%;
background:#ccc;
}
h3{
font-size: 0.95rem;
font-weight: 600;
-moz-hyphens: auto;
-webkit-hyphens: auto;
-ms-hyphens: auto;
hyphens: auto;
}
<div class="container">
<h3>DIAGNOSEVERFAHREN</h3>
</div>
When you run the snippet in Firefox the word DIAGNOSEVERFAHREN overflows the container and does not break. In Safari and IE it breaks like I expect. Why doesn't this work in Firefox?
Edit
As noted by Marat Tanalin's answer one must include the lang attribute for the hyphens to work correctly. I have this as my <html> tag:
<html class="no-js" lang="de">
Make sure the element or some of its parents has an appropriate lang attribute. It is crucial for CSS hyphens to work.
In general, at least the HTML element should have the attribute:
<html lang="en">
For uppercasing characters, use CSS instead of hardcoded uppercased text in HTML:
.example {text-transform: uppercase; }
Uppercased german text is not hyphenated in Firefox 37 and older due to the bug 1105644 fixed in Firefox 38.
For some strange reason it seems to be because the word is in capital letters. I assume it has something to do with Firefox not thinking that it is a word when it searches the hyphenation dictionary.
I couldn't find any bug reports on it but #MaratTanalin thinks that it has been fixed in Firefox v38.
p {
width: 55px;
border: 1px solid black;
-moz-hyphens: auto;
hyphens: auto;
}
<div>
<h4>English</h4>
<p lang="en" class="auto">DIAGNOSEVERFAHREN</p>
<p lang="en" class="auto">Diagnoseverfahren</p>
<p lang="en" class="auto">diagnoseverfahren</p>
</div>
<div>
<h4>German</h4>
<p lang="de" class="auto">DIAGNOSEVERFAHREN</p>
<p lang="de" class="auto">Diagnoseverfahren</p>
</div>
Edit: It affects all capitalized and uppercase words. Apparently this is by design in Firefox and it won't be fixed anytime soon. Only German language supports the feature of hyphenating capitalized (not uppercase) words.
https://bugzilla.mozilla.org/show_bug.cgi?id=656879
I got this type of issue on ios safari , there are multiple hyphens on that page few of those were not working while remaining works . but i am not supposed to use text-transform:uppercase, so increased the font size to 1px and it worked for me.
Inorder to demonstrate the concept of hyphenation, you need to give the lang attribute is set to en on the parent element.
word-break: break-word working fine in all the other browser including Internet Explorer.
But as soon as you add it into a <SELECT></SELECT> element.
Here is a sample that works in all browsers except IE.
<!DOCTYPE html>
<html>
<head>
<style>
p.test, select
{
width:100px;
border:1px solid #000000;
-ms-word-break: break-all; /* wraps the text in the selector so it prints properly*/
word-break: break-all;
/* Non standard for webkit */
word-break: break-word;
-webkit-hyphens: auto;
-moz-hyphens: auto;
-ms-hyphens: auto;
hyphens: auto;
white-space: pre-wrap;
border: 1px dotted red;
}
</style>
</head>
<body>
<p class="test"> This paragraph contains a very long word: thisisaveryveryveryveryveryverylongword. The long word will break and wrap to the next line.</p>
<select class="test">
<option>testshr1</option>
<option>tb details</option>
<option>This paragraph contains a very long word: thisisaveryveryveryveryveryverylongword.</option>
<option>test</option>
</select>
</body>
</html>
This is a feature in IE: it simply renders each option element on one line. Looking at the situation in Developer Tools, you can see that your settings are recognized (and inherited, when applicable, from select to option). But the rendering of a select element is special, and does not do line breaks.
The conclusion is that you should not create such problems. The select element is meant to be used for relatively short options, and the IE behavior is quite understandable. Either shorten the option texts considerably, or use a different control, like a set of radio buttons.
try following code
<style>
select option{
width:100px;
word-break: break-all;
}
</style>
Try using this:
word-wrap: break-word
I have a CSS similar to the one below.
.ui-icon {
font-size: 6em;
height: 180px;
width: 180px;
}
.ui-icon .ui-icon-label {
padding-top: 15%;
}
The top padding doesn't display the text in IE9 (i.e. ui-icon-label).
HTML is also given below.
<div class="ui-icon-color ui-icon">
<div id="icon-1">
<i class="icon-cog"></i>
</div>
<div class="ui-icon-label">My Label</div>
</div>
But the same code works well in Chrome and Firefox. IE9 displays the ui-icon-label till the padding is 13.4%. Till the value, when I increase it gradually the text moves downwards a bit. Above that value it suddenly disappears. But For me 15% looks the best position to place the label. I went through different solutions provided in the suggest like 'clear:both' or using the W3C validator. But they didn't help.
FYI, the icon-cog class comes from font-awesome.
Have you considered using a IE9 targeted stylesheet with media queries to solve that issue?
<!--[if IE 9]>
<link rel="stylesheet" type="text/css" href="ie9.css" />
<![endif]-->
// In the CSS:
#media (max-width: ???px) {
.ui-icon .ui-icon-label {
padding-top: 30%;
}
}