Is it okay to rely on javascript for menu layout? - javascript

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)

Related

Responsive two column panel layout in priority order

I've been working on a way to display panels on a homepage, the page is responsive and would start off with all the panels being 100% wide and stacking and then at a certain breakpoint the panels would split into two columns.
My work in progress is here http://codepen.io/charge-valtech/pen/aIEGf
This works nicely with the panels flowing in priority order from left to right. However the problem is this page would need to be dynamic, so any of the panels could be "switched off". So if you got rid of the third panel, because of the way floats work the fourth panel tries to go over to the right, even though float: left has been specified.
Using clearing would keep it to the left, but then there would be a gap where the third panel was...
I hope this makes some sense and was just interested in how other people might approach the problem. I'm thinking JavaScript might be the way to go but wouldn't really know how to go about detecting if there's white space available.
Cheers
I thought I'd share my solution for this, since masonry was a bit overkill for this and didn't work as cleanly as I would've liked.
I have two classes in my css left-widget and right-widget, these are then set their widths and floats using a grid system, which essentially gives them float left and float right and 49.something% width.
By default I give all the widgets the left-widget class, and then with some jquery I do this:
$('.left-widget').each(function (index, value) {
var widgetPosition = $(this).position().left;
if (widgetPosition >= 30) {
$(this).removeClass('left-widget').addClass('right-widget');
}
});
$('.right-widget').each(function (index, value) {
var widgetPosition = $(this).position().left;
if (widgetPosition <= 30) {
$(this).removeClass('right-widget').addClass('left-widget');
}
});
This now does exactly what I wanted it to do, sticking the widgets to the right if they fit.
Use CSS media queries:
#media (max-width: 1000px) {
#box-js {display:none}
}
The CSS rule for #box-js will only be executed when the screen with is below 1000px.

How to ensure CSS :hover is applied to dynamically added element

I have a script that adds full images dynamically over thumbnails when you hover over them. I've also given the full images a CSS :hover style to make them expand to a larger width (where normally they are constrained to the dimensions of the thumbnail). This works fine if the image loads quickly or is cached, but if the full image takes a long time to load and you don't move the mouse while it's loading, then once it does appear it will usually stay at the thumbnail width (the non-:hover style) until you move the mouse again. I get this behavior in all browsers that I've tried it in. I'm wondering if this is a bug, and if there's a way to fix or work around it.
It may be worth noting that I've also tried to do the same thing in Javascript with .on('mouseenter'), and encountered the same problem.
Due to the nature of the issue, it can be hard to reproduce, especially if you have a fast connection. I chose a largish photo from Wikipedia to demonstrate, but to make it work you might have to change it to something especially large or from a slow domain. Also note that you may have to clear the cache for successive retries.
If you still can't reproduce, you can add an artificial delay to the fullimage.load before the call to anchor.show().
HTML:
<img id="image" src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/32/Cairo_International_Stadium.jpg/220px-Cairo_International_Stadium.jpg" />
CSS:
.kiyuras-image {
position: absolute;
top: 8px;
left: 8px;
max-width: 220px;
}
.kiyuras-image:hover {
max-width: 400px;
}
JS:
$(function () {
var fullimageurl = 'http://upload.wikimedia.org/wikipedia/commons/3/32/Cairo_International_Stadium.jpg';
var fullimage = $('<img/>')
.addClass('kiyuras-image')
.load(function () {
anchor.show();
});
var anchor = $('<a/>').hide().append(fullimage);
$('body').prepend(anchor);
$("#image").on('mouseenter', function () {
fullimage.attr('src',fullimageurl);
$(this).off('mouseenter');
});
});
JS Bin
Updated JS Bin with 1.5-second delay added (Hopefully makes issue clearer)
Again: Reproducing the issue involves clearing your cache of the large image, and then hovering over the original image to initial the loading of large image, then not moving your mouse while it's loading. Intended behavior is for the large image to properly take on the :hover pseudo-class when it eventually loads. Issue I see when it takes longer than ~0.75 secs to load is that it does not take on :hover until you jiggle the mouse a little.
Edit: See my comments on #LucaFagioli's answer for further details of my use case.
Edit, the sequel: I thought I already did this, but I just tried to reproduce the issue in Firefox and I couldn't. Perhaps this is a Chrome bug?
Most browsers update their hover states only when the cursor moves over an element by at least one pixel. When the cursor enters the thumbnail's img it gets hover applied and runs your mouseenter handler. If you keep your cursor still until the full-sized image loads, your old img (the thumbnail) will keep the hover state and the new one won't get it.
To get it working in these browsers, move the hover pseudo-class to a common parent element in the CSS; for example, enclose both imgs in a span.
If the selectors are correct, CSS will be applied to all elements, dynamic or otherwise. This includes all pseudo classes, and will change as attributes in the DOM change.
[Edit: while my explanation might be of interest, pozs' solution above is nicer, so I suggest using that if you can.]
The hover pseudo-class specification is quite relaxed concerning when it should be activated:
CSS does not define which elements may be in the above states,
or how the states are entered and left. Scripting may change
whether elements react to user events or not, and different
devices and UAs may have different ways of pointing to, or
activating elements.
In particular, it is not being activated when you update the visibility of the anchor element on load.
You can get around this fairly easily: copy the hover styles to a class, intercept the cursor moving over the element that it will eventually cover, and based on that add or remove your class from the element.
Demo: JS Bin (based on your delayed example).
Javascript:
$("#image")
.on('mouseenter', function () {
fullimage.attr('src',fullimageurl).toggleClass('mouseover', true);
$(this).off('mouseenter');
})
.mouseleave(function() {
fullimage.toggleClass('mouseover', false);
});
CSS:
.kiyuras-image:hover, .kiyuras-image.mouseover {
max-width: 400px;
}
TL;DR: You cannot rely on :hover applying to dynamically added elements underneath the cursor. However, there are workarounds available in both pure CSS and Javascript.
I'm upvoting both Jordan Gray and posz' answers, and I wish I could award them both the bounty. Jordan Gray addressed the issue re: the CSS specification in a somewhat conclusive way and offered (another) working fix that still allowed for :hover and other CSS effects like transitions, except on load. posz provided a solution that works even better and avoids Javascript for any of the hover events; I provide essentially the same solution here, but with a div instead of a span. I decided to award it to him, but I think Jordan's input was essential. I'm adding and accepting my own answer because I felt the need to elaborate more on all of this myself. (Edit: Changed, I accepted posz')
Jordan referenced the CSS2 spec; I will refer instead to CSS3. As far as I can tell, they don't differ on this point.
The pseudo-class in question is :hover, which refers to elements that the user has "designated with a pointing device." The exact definition of the behavior is deliberately left vague to allow for different kinds of interaction and media, which unfortunately means that the spec does not address questions like: "Should a new element that appears under the pointing device have this pseudo-class applied?" This is a hard question to answer. Which answer will align with user intent in a majority of cases? A dynamic change to a page the user is interacting with would normally be a result of ongoing user interaction or preparation for the same. Therefore, I would say yes, and most current browsers seem to agree. Normally, when you add an element under the cursor, :hover is immediately applied. You can see this here: The jsbin I originally posted. Note that if there's a delay in loading the larger image, you may have to refresh the page to get it to work, for reasons I'll go into.
Now, there's a similar case where the user activates the browser itself with the cursor held stationary over an element with a :hover rule; should it apply in that case? The mouse "hover" in this case was not a result of direct user interaction. But the pointing device is designating it, right? Besides, any movement of the mouse will certainly result in an unambiguous interaction. This is a harder question to answer, and browsers answer it in different ways. When you're activating them, Chrome and Firefox do not change :hover state until you move the mouse (Even if you activated them with a click!). Internet Explorer, on the other hand, updates :hover state as soon as it's activated. In fact, it updates it even when it's not active, as long as it's the first visible window under the mouse. You can see this yourself using the jsbin linked above.
Let's return to the first case, though, because that's where my current issue arises. In my case, the user hasn't moved the mouse for a significant length of time (over a second), and an element is added directly underneath the cursor. This could more easily be argued to be a case where user interaction is ambiguous, and where the pseudo-class should not be toggled. Personally, I think that it should still be applied. However, most browsers do not seem to agree with me. When you hover over the image for the first time and then do not move your mouse in this jsbin (Which is the one I posted in my question to demonstrate the issue, and, like the first one, has a straightforward :hover selector), the :hover class is not applied in current Chrome, Opera, and IE. (Safari also doesn't apply it, but interestingly, it does if you go on to press a key on the keyboard.) In Firefox, however, the :hover class is applied immediately. Since Chrome and Firefox were the only two I initially tested with, I thought this was a bug in Chrome. However, the spec is more or less completely silent on this point. Most implementations say nay; Firefox and I say aye.
Here are the relevant sections of the spec:
The :hover pseudo-class applies while the user designates an element with a pointing device, but does not necessarily activate it. For example, a visual user agent could apply this pseudo-class when the cursor (mouse pointer) hovers over a box generated by the element. User agents not that do not support interactive media do not have to support this pseudo-class. Some conforming user agents that support interactive media may not be able to support this pseudo-class (e.g., a pen device that does not detect hovering).
[...]
Selectors doesn't define if the parent of an element that is ‘:active’ or ‘:hover’ is also in that state.
[...]
Note: If the ‘:hover’ state applies to an element because its child is designated by a pointing device, then it's possible for ‘:hover’ to apply to an element that is not underneath the pointing device.
So! On to the workarounds! As several have zealously pointed out in this thread, Javascript and jQuery provide solutions for this as well, relying on the 'mouseover' and 'mouseenter' DOM events. I explored quite a few of those solutions myself, both before and after asking this question. However, these have their own issues, they have slightly different behavior, and they usually involve simply toggling a CSS class anyway. Besides, why use Javascript if it's not necessary?
I was interested in finding a solution that used :hover and nothing else, and this is it (jsbin). Instead of putting the :hover on the element being added, we instead put it on an existing element that contains that new element, and that takes up the same physical space; in this case, a div containing both the thumbnail and the new larger image (which, when not hovered, will be the same size as the div and thumbnail). This would seem to be fairly specific to my use case, but it could probably be accomplished in general using a positioned div with the same size as the new element.
Adding: After I finished composing this answer, pozs provided basically the same solution as above!
A compromise between this and one of the full-Javascript solutions is to have a one-time-use class that will effectively rely on Javascript/DOM hover events while adding the new element, and then remove all that and rely on :hover going forward. This is the solution Jordan Gray offered (Jsbin)
Both of these work in all the browsers I tried: Chrome, Firefox, Opera, Safari, and Internet Explorer.
From this part of your question: "This works fine if the image loads quickly or is cached, but if the full image takes a long time to load and you don't move the mouse while it's loading,"
Could it be worth while to "preload" all of the images first with JavaScript. This may allow all of the images to load successfully first, and it may be a little more user friendly for people with slower connections.
You could do something like that : http://jsfiddle.net/jR5Ba/5/
In summary, append a loading layout in front of your image, then append a div containing your large image with a .load() callback to remove your loading layer.
The fiddle above has not been simplified and cleaned up due to lack of time, but I can continue to work on it tomorrow if needed.
$imageContainer = $("#image-container");
$image = $('#image');
$imageContainer.on({
mouseenter: function (event) {
//Add a loading class
$imageContainer.addClass('loading');
$image.css('opacity',0.5);
//Insert div (for styling) containing large image
$(this).append('<div><img class="hidden large-image-container" id="'+this.id+'-large" src="'+fullimageurl+'" /></div>');
//Append large image load callback
$('#'+this.id+'-large').load(function() {
$imageContainer.removeClass('loading');
$image.css('opacity',1);
$(this).slideDown('slow');
//alert ("The image has loaded!");
});
},
mouseleave: function (event) {
//Remove loading class
$imageContainer.removeClass('loading');
//Remove div with large image
$('#'+this.id+'-large').remove();
$image.css('opacity',1);
}
});
EDIT
Here is a new version of the fiddle including the right size loading layer with an animation when the large picture is displayed : http://jsfiddle.net/jR5Ba/6/
Hope it will help
Don't let the IMG tag get added to the DOM until it has an image to download. That way the Load event won't fire until the image has been loaded. Here is the amended JS:
$(function () {
var fullimageurl = 'http://upload.wikimedia.org/wikipedia/commons/3/32/Cairo_International_Stadium.jpg';
var fullimage = $('<img/>')
.addClass('kiyuras-image')
.load(function () {
anchor.show(); // Only happens after IMG src has loaded
});
var anchor = $('<a/>').hide();
$('body').prepend(anchor);
$("#image").on('mouseenter', function () {
fullimage.attr('src',fullimageurl); // IMG has source
$(this).off('mouseenter');
anchor.append(fullimage); // Append IMG to DOM now.
});
});
I did that and it worked on Chrome (version 22.0.1229.94 m):
I changed the css as that:
.kiyuras-image{
position: absolute;
top: 8px;
left: 8px;
max-width: 400px;
}
.not-hovered{
max-width: 220px;
}
and the script this way:
$(function(){
var fullimageurl = 'http://upload.wikimedia.org/wikipedia/commons/3/32/Cairo_International_Stadium.jpg';
var fullimage = $('<img/>')
.addClass('kiyuras-image')
.load(function () {
anchor.show();
});
var anchor = $('<a/>').hide().append(fullimage);
$('body').prepend(anchor);
$('.kiyuras-image').on('mouseout',function(){
$(this).addClass('not-hovered');
});
$('.kiyuras-image').on('mouseover',function(){
$(this).removeClass('not-hovered');
});
$("#image").one('mouseover', function(){
fullimage.attr('src',fullimageurl);
});
});
Basically I think it's a Chrome bug in detecting/rendering the 'hover' status; in fact when I tried to simply change the css as:
.kiyuras-image{
position: absolute;
top: 8px;
left: 8px;
max-width: 400px;
}
.kiyuras-image:not(:hover) {
position: absolute;
top: 8px;
left: 8px;
max-width: 220px;
}
it still didn't worked.
PS: sorry for my english.
I'm not 100% sure why the :hover declaration is only triggered on slight mouse move. A possible reason could be that technically you may not really hover the element. Basically you're shoving the element under the cursor while it is loading (until the large image is completely loaded the A element has display: none and can therefore impossible be in the :hover state). At the same time, that doesn't explain the difference with smaller images though...
So, a workaround is to just use JavaScript and leave the :hover statement out of the equation. Just show the user the two different IMG elements depending on the hover state (toggles in JavaScript). As an extra advantage, the image doesn't have to be scaled up and down dynamically by the browser (visual glitch in Chrome).
See http://jsbin.com/ifitep/34/
UPDATE: By using JavaScript to add an .active class on the large image, it's entirely possible to keep using native CSS animations. See http://jsbin.com/ifitep/48

Quickly repaint array of unicode symbols in JavaScript

I want to change background/foreground color of many symbols with the same CSS class. Right now I'm doing it with jQuery — like $('back_COLORED').css('background-color', '#00FF00'), but this approach is slow when there are many elements with such class (>900).
Seems it's because jQuery don't change CSS rules itself, but finds all elements one-by-one and applies inline styles to them. At least, this is what I see in inspector. So, the question is:
How can I change the CSS rules itself?
Will it be much faster?
Can I make it cross-browser (IE6 doesn't count)?
UPD: I'm trying to make some kind of color scheme editor. The source is at http://github.com/kurokikaze/cinnabar/. Don't mind PHP things, editor is fully client-side (with just some libraries fetched from the net).
UPD2: Tried canvas approach, still slow. Canvas branch is at http://github.com/kurokikaze/cinnabar/tree/canvas.
The most cross-browser friendly way to override a class definition is to write a new rule and add it to the end of the last stylesheet in the document. You can edit an existing style rule, but even some recent browsers can make it difficult.
function newRule(selector, csstext){
var SS= document.styleSheets, S= SS[SS.length-1];
// this example assumes at least one style or link element
if(S.rules){
S.addRule(selector,csstext,S.rules.length);
}
else if(S.cssRules){
S.insertRule(selector+'{'+csstext+'}'),S.cssRules.length)
}
}
newRule('.someclass','background-color:#0f0');
You can add as many 'property:value;' bits in the csstext as you need.
Remember to prefix a '.' to a class name or a '#' to an id,
and the css must be written as a style rule (with-hyphens, not camelCase).
Of course, it will not override inline styles, and it is overkill for small, local changes.
It also may make the redrawing of the page more obvious than changing one element at a time,
but it may be just what you need here.
There are different ways depending on which browser you are dealing with. This is documented on Quirks Mode.
Some libraries provide an abstraction layer, such as YUI's StyleSheet utility.
There should be a significant performance boost since you aren't using JS/DOM to cycle through all the elements.
Another approach would be to predefine your styles:
body.foo .myElements { … }
And then edit document.body.className
If you can select the parent div by id, maybe you could select by tag inside it? Or are there elements of the same kind that should change color and that should not, inside the parent?
It would be nice to have an idea of what you're building here. 900+ objects seems to be a lot... maybe a completely different approach could be used? Canvas, SVG?
Try hiding the items you want to change before changing them, make the change and then display them again. This is common practice to speed up things as you minimize the repaint events in the viewport. In this case when you only setting one css property it might not be that of a benefit but it´s worth a try I say.
Try:
$('back_COLORED').hide();
$('back_COLORED').css('background-color', '#00FF00');
$('back_COLORED').show();
or
$('back_COLORED').hide().css('background-color', '#00FF00').show();
I would stick in trying changing a CSS property, instead of parsing the DOM.It is about the CSS engine vs. DOM+JS here, and the winner is clear.
It happens I just uploaded a tiny library that replaces CSS by Javascript: jstyle
This is may be an overkill, but you will find in the source code of jstyle.js all the code you need to update cross browser the CSS properties of your page.
I think a better solution would be to write a more specific CSS rule (that would override the normal colour) that can be activated by simply changing one element's css class.
So for example if you had the following structural markup:
<div id="container">
<span class="colored">Test 1</span>
<span class="colored">Test 2</span>
</div>
And CSS:-
.colored { background-color: red; }
.newcolor .colored { background-color: blue; }
Then in your jquery you add the .newcolor class to the container div:-
$('#container').addClass('.newcolor');
When you do that the second CSS rule will override the first because it is more specific.
Inject the css code into a style tag:
var style = $('style').attr({
type:"text/css",
media:"screen",
id:'changeStyle'
}).html('.tempClass { color:red } .tempClass p { background:blue }').prependTo('body');
and on every changes on your color with color picker you only rewrite the html inside of #changeStyle tag.
Have no idea if it works (didn't tested) but you should give a try.
This is jQuery pluggin for work with css rules: http://flesler.blogspot.com/2007/11/jqueryrule.html
not sure about its performance, but worth a try.

How can I cause the browser to scroll an element horizontally to a pre-defined location without using JavaScript?

I'm working on 'timeline' project, where I have content inside of list items, in a horizontal unordered list. This is contained in a div, so you can scroll left to right through the content.
My client would like buttons to 'goto' each era. I know this is easily achieved through JavaScript. However they also want this to be functional without JavaScript. I've tried adding anchors to each item, but this doesn't really work since you can't control the exact position the browser want's to end up at. It's very buggy using the anchors with horizontal scrolling.
Any ideas?
Use a vertical timeline (the whole page scrolls, no inner scrollbars) when JavaScript isn't available. Anchors work reasonably well in that scenario. An easy way to achieve this is to make the styles that collapse your list and its containing div dependent on a class higher up in the DOM hierarchy, and set that class at load-time using JavaScript. Something like,
.jsEnabled .containingDiv { height: 10em; overflow: auto; }
.jsEnabled .timelineList li { width: 6em; float: left; }
...
function loadTimeStuff()
{
// enable styles that require JS-assisted scrolling
document.body.className = "jsEnabled";
// ...
}
Sure, it won't look as fancy as the full-blown JS-enhanced page, but it's a fallback - if users want the fancy stuff, they need only use a JavaScript-enabled browser...
You're stuck with javascript here for the most part -- as you found out, anchors don't really do the job.
You do have one other alternative, though you probably wont like it any better: Flash.
You'd have to position the anchors at a certain offset to the item you want to have displayed. F.e. if you want the item in the middle of the screen you would have to position the anchor at x = item.x-screenWidth/2 and y = item.y-screenHeight/2, approximately.
I don't think there's another solution, but using Javascript.
I'm afraid you are out of luck if you have to make this work without JavaScript. At least without some hideous hacking that would involve postbacks and dynamically generating some CSS for offsetting the position of the timeline ...
But as Shog9 has said, non JavaScript version would be a fall-back and can't be expected to work as well as the JS version (why would you need JS then) ...

Limit displayed length of string on web page

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.

Categories

Resources