Limit displayed length of string on web page - javascript

I'm looking for a technique (javascript, CSS, whatever ???) that will let me control the amount of a string that is displayed. The string is the result of a search (and therefore not initially known). A simple Character count approach is trivial, but not acceptable, as it needs to handle proportional fonts. In otherwords if I want to limit to say 70 pixels then the examples below show different character counts (9 and 15) both measuring the same:-
Welcome M...
Hi Iain if I've ...
If you look at Yahoo search results they are able to limit the length of title strings and add ellipsis on the end of long strings to indicate more.
(try site:loot.com wireless+keyboard+and+mouse to see an example of Yahoo achieving this)
Any Ideas?

Perhaps the CSS property overflow: hidden; can help you, in conjuntion with width.

Using a span with fixed width, overflow-x:hidden and white-space:nowrap would be a start.
To get the elipsis in a cross browser scenario will be difficult. IE has text-overflow:elipsis but that is non-standard. This is emulated with -o-text-overflow in Opera. However mozilla doesn't have this. The yahoo Javascript APIs handle this.

Yahoo does this server-side, the truncation and elipsis ('...') is returned in the HTML. Presumably this is done on a character count, and if thats not an option for you then server-side is out.
Other than overflow: hidden I'm not sure CSS can help you here. You could measure the width of the containing element using Javascript, and truncate the text based on that. This could be used in conjunctin with overflow:hidden; so the text elements don't just resize all of a sudden, but you may have to extract the text and add a temporary element onto the page somewhere to do the measurement. Depending on the number of elements to truncate this might not work very well.
Another slightly hacky option is to measure the width of an element containing the letter 'W', then do a character count and truncate if (char_count * width_of_w) > desired_width.
You can use text-wrap: none; to stop text wrapping onto new lines, although this is a CSS3 property and last I checked was only supported by IE (imagine my shock when I found that one out!).

For a cross-browser pure-CSS solution, take a look at Hedger Wang's text-overflow:ellipsis prototype, here:
http://www.hedgerwow.com/360/dhtml/text_overflow/demo2.php

In CSS: .class-name{
width: 5em;
white-space: nowrap;
text-overflow: ellipsis; }
Hope it can help you.

Related

How to remove text that is overflown from element in Jquery

So I am working on a web app, and this is my layout. The divs use
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
This visually is fine, and is also fine in a JSFiddle. But with the ability to make very long names has issues in the web app. This issue comes from the fact that it isn't technically removing the overflown text. It (as you would think with the word "hidden") hides it. How would you go about detecting overflown text in the ".Name" element and removing it? I would like to keep the same look and rules. Just the text that is hidden is removed.
LINK - https://jsfiddle.net/t29ffzan/12/
The issue is that not all letters take up the same amount of space as each other. For instance I and M where M (guessing) is ~ 3x as big as I. See this explanation.
However, you can guess and get close but there's still no guarantee.
$('.Name').each(function() {
let text = $(this).text();
let width = $(this).parent('.Box').outerWidth();
let fontSize = 18 - ( 18 * 0.35 ); // Hardcoded from CSS
let count = width/fontSize;
text = text.substr(0, count);
$(this).text(text);
});
This fiddle is a working example of the above and uses the font-size in the CSS and removes ~ 35% to allow for more characters but depending on the actual letters uses the results may vary widely.
You could use a fixed width font as all the characters should take up the same amount of space. However, results still aren't going to be perfect.
Your best bet is the limit the character count when the name is created instead of having to go back and try and parse it after the fact.
For anyone that comes to this post, max-width: 40ch; worked best for me.

Get how many lines in a text, based on the view width not carriage return or line feed (\r\n)

I am implementing a comment system in my website and I need to hide the text after exceeding 5 lines in a view width of 300px and show "Read more", I've tried doing so with string length but every character has a different width, for example 500 characters of "#" (at sign) in a view width of 300px will have more lines than 500 characters of "." (dot) in a view width of 300px and also the user might use a lot of carriage return, after a lot of headache I thought is was impossible, then I've went to YouTube to see if they solved this problem, and obviously they did!
So my question is how it possible? just guide me in the right direction and I'll do my research.
NOTE 1: 300px view width is just an example and can change.
NOTE 2: I am using PHP if that matters.
NOTE 3: I think JavaScript solutions can be fooled by users, but I am not sure.
NOTE 4: The only solution I can think of is using a reference for each character width based on the font in use, and use that to figure out how many lines they are in a specific view width, But isn't that too much work since there is a huge number of supported characters?
Thank you.
You can't reliably calculate how many lines there will be. It depends on too many factors, like the font, the browser and even the operating system.
Just use css to hide everything after x lines. I put together a quick example:
This class hides everything but the first 5 lines.
.truncated {
font-size: 1em;
line-height: 1.2em;
max-height: 6em;
overflow: hidden;
}
Then just add a button that removes that class using javascript.
https://jsfiddle.net/rmwu4sL1/

"Splitting" long words

I'm making a responsive website for a client using twitter bootstrap, which is responsive by default. However when the words get too long in a <h1> it doesn't fit the mobile sized browser.
What I would like to do is change "thisisaverylongword" into "thisisa-verylongword" with the final part on a new line.
Is there a simple way to do this, maybe with javascript? I'm thinking some condition like "if $word is wider than $body then" or something similar. Any tips will be very useful, gold star if the same code works for any word.
You could use the (experimental) CSS property hyphens:
h1 {
-webkit-hyphens: manual;
-moz-hyphens: manual;
-ms-hyphens: manual;
hyphens: manual;
}
and specify the line break by using special unicode characters:
U+2010 (HYPHEN)
The "hard" hyphen character indicates a visible line break opportunity. Even if the line is not actually broken at that point, the hyphen is still rendered.
U+00AD (SHY)
An invisible, "soft" hyphen. This character is not rendered visibly; instead, it suggests a place where the browser might choose to break the word if necessary. In HTML, you can use ­ to insert a soft hyphen.
Browser compatibilty
MDN reference
EDIT
As mentioned by #hustlerinc it might be needed to set word-break: break-all to make it work.
I've written a jQuery plugin that might fit this purpose quite well. Check out ellipsis.js. Using the following configuration should work:
$('h1').ellipsis({visible: 10, more: '…', separator: '', atFront: false})
I guess the advantage of doing it this way is that the users still may display the whole header on tap if they want to.
You can apparently achieve something like this with a bit of CSS, check out the text-overflow property. Perhaps that's the ticket for this case. No JS needed. :)
Can't you set the CSS property word-break to hyphenate?
example here
I think that you must do it by yourself.
With the function "split", you split your string into a table of words. Then, you can check all the words into a for.

Stop text from over running it container

Ive got a container of into which a message gets echoed, the message its self has no fixed size, as its user generated, what can happen though is that if a string of text that is too long is submitted it can over flow its container an break the design..
Is there a way (hopefully with just css, although js is ok) to make the box crop the text and leave it with a ... then i can place a link to the text on another page.
You can obviously stop this happening by using overflow:hidden, but i would like a more elegenat approach rather than just cutting it straight off. I seem to remeber reading about somthing like this with css3, but for the life of me cant figure out what it was called.
Ive made a jsfiddle of the problem here - http://jsfiddle.net/6Fk7B/
CSS property text-overflow:ellipsis, though browser support varies
https://developer.mozilla.org/en-US/docs/Web/CSS/text-overflow
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
That should do it for you. All need to be included.
You may also want to include the following browser prefixes:
-ms-text-overflow: ellipsis;
-o-text-overflow: ellipsis;
It won't be perfect in all browsers, but it should be good for most:
http://caniuse.com/#feat=text-overflow
You might want to tryout http://www.mobify.com/blog/multiline-ellipsis-in-pure-css/
The actual code is here http://codepen.io/romanrudenko/pen/ymHFh
Honestly it's tricky to put ellipsis for a paragraph but pretty straight-forward for single line text.
Is this a reasonable starting point for you?
Fiddle: http://jsfiddle.net/QkugN/
Basically you add all the content to the div and hide it using the normal method of overflow:hidden. You also add a tab that, upon hover, displays the rest of the content. If you use absolute positioning for the mouseover state the content will momentarily be removed from the flow and be allowed to overlay any surrounding content. It might not be a complete solution as it stands but it is a pure CSS direction you could explore.
The bit that's doing the business is the General Sibling selector "~" (tilde). Support for it is pretty solid with modern browsers.
Using JavaScript you could achieve this using substring. jQuery isn't necessary, but it makes it a tad easier.
var myText = $('.myBox').text(),
maxLength = 250,
more = '...';
if (myText.length > maxLength) {
myText = myText.substring(0, 250);
$('.myBox p').text(myText + more);
}
See my example example: http://jsfiddle.net/clrux/6Fk7B/14/

Is it okay to rely on javascript for menu layout?

I have a website template where I do not know the number of menu items or the size of the menu items that will be required. The js below works exactly the way I want it to, however this is the most js I've every written. Are there any disadvantages or potential problems with this method that I'm not aware of because I'm a js beginner? I'm currently manually setting the padding for each site. Thank you!
var width_of_text = 0;
var number_of_li = 0;
// measure the width of each <li> and add it to the total with, increment li counter
$('li').each(function() {
width_of_text += $(this).width();
number_of_li++;
});
// calculate the space between <li>'s so the space is equal
var padding = Math.floor((900 - width_of_text)/(number_of_li - 1));
// add the padding the all but the first <li>
$('li').each(function(index) {
if (index !== 0)
{
$(this).css("padding-left", padding);
}
});
You can do this hackily in CSS, using display: inline-block, and text-align: justify
<ul>
<li>thing</li>
<li>thing2</li>
<li>thing3</li>
<li>thing4</li>
<li class="hack"></li>
</ul>
And then:
ul { text-align: justify }
li { display: inline-block }
li.hack { width: 100% } /* force the justified text to wrap */
Demo
​
Yes, there are disadvantages of using JS for formatting.
It is strongly recommended to avoid using JS for formatting and positioning, use CSS whenever possible.
Javascript is interpreted and run very differently from browser to browser, from OS to OS, from OS/browser version to version.
CSS rendering is a native browser engine function and its rendering priority is higher than that of JS.
CSS rendering is much more speedy than JS.
Etc.
What you are doing now I would never suggest doing. IMHO, this is a very wrong approach. JS is absolutely definetely misused in this case. You have to use CSS for this task, and I would suggest posting a question about how to use CSS correctly for this task.
I would suggest having a default spacing between them in a way that would not push them out of their container. The extra javascript to enable them to space equally should be an enhancement only.
I think the answer to your question is, if it works, then it works (and will continue to work), but that doesn't mean that this is the best way to handle it. If you *care about the best way, then investigate how to improve your approach using mostly (or even exclusively) CSS. If you're just looking to get the job done, and it's working, then you're good to go.
Depending on your site visitors, there will be around 3% who visit you with JS disabled. And you want the site to work for them to. Maybe not the unnessecary parts of the site but you want the critical parts to work. Navigation is one of the most important parts of a website.
Make sure the navigation works without JS (doesn't have to be as fancy as with JS) and then you could make some improvements with JS.
You don't need JavaScript as long as you can rely on a CSS algorithm that adapt width to its content: the table layout algorithm :)
See http://jsfiddle.net/r9yrM/1/ from my previous answer for examples.
Don't forget to have a minimum padding on each "cell", text stuck to a border isn't very readable (and ugly). You'll also probably want text-align: center on cells (last CSS rule).
With JS, you could decide of a maximum number of tabs (or a minimum "reasonable" width) and above (below) that number, add a class on the parent that will trigger each tab to render as float: left and block and not table-cell anymore. Then it'll occupy 2 or more lines (like the extension Tab Mix Plus on Firefox)
Note: there're at least 2 algorithms for table: with and without table-layout: fixed, depending on freedom left to the browser when adapting.
Note on your jQuery code above: "each li except the first" can be expressed by $('li + li') (the first one isn't preceded by a li)

Categories

Resources