4

I'm developing a website (Wordpress, HTML, CSS, jQuery) with contents written in portuguese. There are a lot of words with hyphen, which are broken in half if they appear at the end of the line. Here's an example:

Batata frita pála-
pála, é uma tara de
sabor.

Is there a way I can detect if a word is hyphenated and not break it in half if it is at the end of the line? The ideal would be for the whole word to just go to the next line, but if not possible, I'm open to suggestions. Something like this:

Batata frita
pála-pála, é uma
uma tara de sabor.

More important to me than knowing the solution is to understand it. Thanks in advance.

EDIT

The website is developed on a CMS platform, the contents are inserted by the client and are dynamic. I can't expect the client to use non-breaking hyphens (HTML ‑) by himself.

Cthulhu
  • 5,095
  • 7
  • 46
  • 58

6 Answers6

8

Replace all of your hyphens with Non-Breaking Hyphens. It's the same as the non-breaking space ( ) only it's a hyphen.

Madara's Ghost
  • 172,118
  • 50
  • 264
  • 308
  • 1
    Unfortunatelly, the contents are the clients' responsibility and I can't expect them to do that. Thanks for your answer though. – Cthulhu Jul 16 '12 at 14:51
  • 1
    Well, PHP knows how to do it. Right? – Itay Moav -Malimovka Jul 16 '12 at 14:53
  • 1
    @Cthulhu: You can do it for them silently with PHP. A simply `str_replace()`. – Madara's Ghost Jul 16 '12 at 14:57
  • @Cthulhu - the correct hyphen character is part of the content, so it is their responsibility; the choice of breaking or non-breaking hyphen will vary word-from-word. If the client wanted to make sure that all their `á` characters were correct, they wouldn't expect you to fix their spelling, would they? But yes, if necessary, PHP can do the replacement. – Spudley Jul 16 '12 at 14:59
  • @Spudley: Though it's much easier to type a regular hyphen than a non-breaking one. `-` instead of `‑`. So you'd be very naive if you'd think a normal user would use non-breaking ones. – Madara's Ghost Jul 16 '12 at 15:01
  • @Truth - you're right of course, but the user could be given the tools to do it themselves: maybe a custom button on their CMS WYSIWYG editor. The problem remains of whether to simply replace all hyphens, in which case a PHP solution is fine, or if it needs to be specific to each word, in which case the user can't expect an automated solution to work very well. – Spudley Jul 16 '12 at 15:20
  • 1
    @Spudley: I think the general approach in this case would be: If the word itself contains a hyphen (`pre-order`) it shouldn't be broken, a normal hyphen (not in a word; `Sitename - Some title`) should be broken, in which case the spaces will break it normally. So I guess we're safe here. – Madara's Ghost Jul 16 '12 at 15:23
5

If you're talking about the browser's own wrapping of text/HTML content (as opposed to regular expression splitting), I can think of two ways to do this:

  • use a non-breaking hyphen (HTML ‑) instead of a regular one
  • add <span style="white-space: nowrap"> around sections you don't want to wrap
wrschneider
  • 17,913
  • 16
  • 96
  • 176
  • 3
    Caution: `white-space: nowrap;` will also prevent line wraps at spaces. So the `span` would have to be around just the one single hyphenated word. – pixelistik Jul 16 '12 at 15:02
1

As others have suggested, you need to replace the regular hyphens with non-breaking ones.

This can be automated to be done by the CMS.

For Wordpress, you can add a content filter to the functions.php of your theme:

function non_breaking_hyphens($content){
    return str_replace('-', '&#8209;', $content);
}

add_filter('the_content', 'non_breaking_hyphens');

This will apply the desired search-replace on the post body, before it is sent to the browser.

pixelistik
  • 7,541
  • 3
  • 32
  • 42
0

There are several possibilities:

<nobr>pála-pála</nobr>
<span class=nobr>pála-pála</span>
pála&#8209;pála

all with pros and cons (see http://www.cs.tut.fi/~jkorpela/html/nobr.html).

Whichever approach you choose, you can try to automate the process server-side or client-side. As this is more or less presentational, I think it could well be done with client-side JavaScript. I’d suggest adopting a strategy similar to that of Firefox: long hyphenated compounds can be divided (it usually improves formatting), but if there are, say, less than 4 characters on either side of the hyphen, prevent division.

Jukka K. Korpela
  • 195,524
  • 37
  • 270
  • 390
  • That's a good resource, I didn't knew ``. However, the "less than 4 characters on either side" strategy is not a good option, since portuguese language can have quite long (or short) hyphenated words. – Cthulhu Jul 17 '12 at 09:58
  • 1
    @Cthulhu, the point is that if you have “xy-supercalifragilistic” or “supercalifragilistic-xy”, then breaking after a hyphen does not help formatting much. But if either part of hyphenated compound is 4 characters or longer, like “supercalifragilistic-expialidocious”, then breaking will probably help against excessively varying line length. The limit need not be 4; it could be 3, or 5, or more. – Jukka K. Korpela Jul 17 '12 at 10:14
0

regarding the update in the question:

I see three possible solution, but no easy one :)

  1. parse the content with regex, if a substring is within >....<, use str_replace or wrap in <nobr> => error prone and complicated
  2. build a DOMDocument with the content, walk the DOM and treat every textNode with your choice of non-breaking solution. => may be costly in server resources
  3. Client side: most WYSIWYG that I have seen have APIs for extensions. Either add a button that inserts a non-breaking-hyphen or add an onKeyUp listener that replaces - with &#8209;
cypherabe
  • 2,562
  • 1
  • 20
  • 35
0

If you are facing this challenge because you're checking your website out in an iOS mobile browser you have to put in place much more forceful code. Apple iPhone, for example, will reflow text but also hyphenate at its discretion. So, do this to eliminate the issue altogether:

.yourclass{
    -moz-hyphens: none;
    -ms-hyphens: none;
    -webkit-hyphens: none;
    hyphens: none;
}
L X
  • 21
  • 1