I'm working on the latest version of my plugin, Textarea Line Counter (http://mostthingsweb.com/?p=84). To make it even more accurate, I want to identify regions of text that wrap because they are too large to fit on the line (like a sequence of repeated characters).
I'm assuming that browsers only wrap text at spaces. Are there any other characters that lines can be wrapped at? Thank you,
Looks like it depends on the browser, my Opera wraps also on e.g. + % ? $ / ( [ { } \ ° ! ¿
Safari/Chrome on ¿ ? too
(guess there are lots more)
Nice idea for a plugin. Fighting the accuracy issues is going to be a challenge.
There's not a universal catch all for the way textarea is going to handle a string (other than line breaks at spaces), or using word-wrap.
IE produced a break with . , () {} ?, but not with / * = +
In this example, textarea seems to have that "special" feeling like a td
Based on all your advice, I have created a solution. It is rather large, and in fact I think I will make it into a separate plugin, as well as including it in my Textarea Line Counter. It works like this:
Create a div to act as a container, and set the font to something monospaced (i.e. every character is the same width)
Create a span within the container, and place a single letter.
Take the width measurement of the span (which will be the width of the letter, once margins, padding, and some other CSS attributes are cloned)
Create another div within the container and clone its CSS attributes. Set it's width to be two times the width of the letter found in step 3, and record its height.
To test if a character will cause a wrap, set the text of the div to: A[some character]A. [some character] is a character you are trying to test.
Test the height of the div. If it is larger than the height found in step 4, the text has wrapped.
I'm looking forward to releasing this plugin. Thank you again for all your advice.
some browsers will break inside words if the word is longer than the col width,
otherwise they break on spaces.
I notice some browsers set this by default- you can, too in most bowsers with:
textarea{word-wrap: break-word}
you can be sure it is not set by using textarea{word-wrap: normal}
Related
I wrote a very simple jquery plugin that clamps lines of an element to a set number of lines. Basically all it does is take the font size, the line height, and an argument passed to the function for max-lines, then it sets a maxheight and css-overflow to hidden.
To be clear, this clamps the actual element with the text, not a containing element.
I am wondering the best way to add an ellipsis to the last shown space. Should I actually truncate the text, then add an ellipsis via regex? If so, whats the best way to truncate characters that aren't shown?
Any help would be appreciated.
There are already many questions about hyphenating words, but I couldn't find a question about hyphenate only when one word that is by it's own too long for one whole sentence.
example:
I like this to be intact (not trying to put the word "verlichtingssysteem" in the upper line with hyphenates)
So I don't want this:
But I want to have a word that doesn't fit the whole line/div/page is hyphenated. Otherwise I can't see the text in full as you can see below. (it cuts off the last 3 characters)
All the solutions I have seen before on other questions does hyphenate on both last 2 examples instead of only the last example.
So it needs only to hyphenate when a word by it's own width doesn't fit the whole div/page, so when you have two words it just needs to place the word on the next line instead of hyphenating.
I only have this word fall off screen problem on mobile. But an (soft) hyphenate messes up on other devices that have a bigger width as you can see on picture 2. So I only need it for one word that by it's own to big on one line.
I don't think I am the only one who has this desire?
you can use
It only breaks a word when it would overlap the content width.
use it like thistextisgettinglong = thistextisgettinglong
see this fiddle: http://jsfiddle.net/2r70mhnw/1/
you probably have to set the width of the container to 100%, that's all!
http://en.wikipedia.org/wiki/Soft_hyphen
In computing and typesetting, a soft hyphen (ISO 8859: 0xAD, Unicode U+00AD soft hyphen, HTML: ) or syllable hyphen (EBCDIC: 0xCA), abbreviated SHY, is a code point reserved in some coded character sets for the purpose of breaking words across lines by inserting visible hyphens.
In some cases using
/* using those two for compatibility reasons with old browsers */
overflow-wrap: break-word;
word-wrap: break-word;
could be a valid solution. Beside its probably not a good solution for text content, I found it really useful to use e.g. in navigations or titles.
It breaks only single words if this particular word does not fit into the line. While it does not add "-" and does no real hyphenation, though.
So I have a "cursor" object created like so:
var cursor=document.createElement('span');
cursor.id="currentCursor";
cursor.innerHTML="|";
cursor.style.fontWeight="bold";
cursor.style.position = 'absolute';
cursor.style.marginLeft="-1px";
Then I add it to the page where someone clicks with this:
var selection = window.getSelection();
var currentRange = selection.getRangeAt(0);
currentRange.insertNode(cursor);
The problem I'm running into is in certain places (mainly end of lines) if the cursor object is added it creates a line break before the object. Using insertNode to move it to another area removes the line break. Also if I set the display to "none", wait for a few seconds and then set it back to "inline" the line break is removed.
This seems like maybe a browser bug in adding absolute elements, but I was wondering if someone had a workaround. I've tried setting the width to 0px but it has no effect.
Update
So if I change the cursor to
cursor.style.position = 'static';
It doesn't have random line breaks. However this causes space to be created around the element. Any way to not allow elements to create space around them?
Update 2
Added a fiddle to show the problem:
http://jsfiddle.net/Mctittles/pSg2D/1/
Original code is a bit large but I slimmed it down to highlight this problem.
If you click at the end of the smiley face and then type it causes line 33 to trigger creating a new text node. After typing a couple letters you'll see the cursor object is forced to the next line. Clicking somewhere else to move it makes the lines merge again.
If you un-comment lines 38 and 40 you'll see what I was talking about with making it initially display:none and changing it later. This time it doesn't cause a line break.
I took out some cross-browser code for fiddler, so this might only work in Chrome
However [position:static] causes space to be created around the element.
No, it doesn’t cause it – there is no actual space created “around it”, it’s just the display width of a character plus spacing in the used font, and that gives the span element itself a width that is more than the | character itself. But when you position the element absolutely, you don’t notice that, because it is taken out of the flow, so it doesn’t push the following characters to the right.
My workaround proposal: Don’t put | into the span as innerHTML, but leave it empty – and then implement the line by giving the element a border-left:1px solid. Remove position:absolute, so that it defaults to static.
Then you might probably not like the height your cursor is getting with that – but that can be fixed as well, by setting display to inline-block, and giving it a height as well.
Here, see how you like ’dem apples: http://jsfiddle.net/pSg2D/9/
You should use CSS instead. Using z-index and maybe even float would (atleast should) fix this.
Edit: Always make sure no other styles make it break line!
I have implemented a jQuery pluggin to correct the width of <input/> elements depending on how much text they have, as shown:
$.fn.correctWidth = function () {
var tempSpan = $('<span>')
.html(this.val())
.css('font-size', this.css('font-size'))
.insertBefore(this);
this.width(tempSpan.width());
tempSpan.remove();
return this;
};
The problem is that, sometimes, the <span> element's width is much larger than the actual text width.
It seems that this occasional problem is because the detected width includes the whitespace between the end of the text and the end of the line.
How can I make sure that the whitespace is not included? Is there an alternative approach?
Try to change
this.width(tempSpan.width());
To
this.width(tempSpan.innerWidth());
You better set also the same font-family(the width of font usually differs).
Furthermore you should use
$('<pre style="display:inline;"/>')
...instead of the span.
Repeated whitespaces will be ignored in a span, but not in a text-input(and not inside pre)
Let's say I have the string "Hello". This string is obviously five characters in length, but what is its length in pixels? Is there an easy way to determine this length in JavaScript? I have thought of a solution where an extra div would have to be displayed to the user, but this way seems hacky and complicated.
In the bigger picture, I am trying to determine how many spaces would be necessary to fill that length of the string. As you can probably tell from above, I think the best option would be to simply measure the length of the string and a single space character from the user's perspective and calculate how many spaces should replace the text based off of that. This is going to be displayed in an HTML input text, by the way.
Thanks.
You can determine the number of pixels the container of the string. You can do this by creating a hidden element in the DOM, setting the inner HTML to the string and then asking for the width.
I don't think their is a good, easy way to do that, except computing the length of a container. The width depends on the font-size, the font, the letter-spacing, it will be different depending on the browser etc...
I've used this to determine the text length in pixels (jQuery syntax):
var txtLen = $(<selector>).text().length * $(<selector>).css('font-size').slice(0,-2);
where selector is whatever you use to target the specific element. Adjust where needed (if the font-size is not set in px).
For example:
var txtLen = $('table td').text().length * $('table td').css('font-size').slice(0,-2);
Real-life use of this was when I needed to determine whether to show the tooltip on a td with a fixed width - if td is wider than its contents, there is no need to show the tooltip.
Things stated in Robin's answer still apply.