Truncating Long Strings With Css: Feasible Yet

Truncating long strings with CSS: feasible yet?

Update: text-overflow: ellipsis is now supported as of Firefox 7 (released September 27th 2011). Yay! My original answer follows as a historical record.

Justin Maxwell has cross browser CSS solution. It does come with the downside however of not allowing the text to be selected in Firefox. Check out his guest post on Matt Snider's blog for the full details on how this works.

Note this technique also prevents updating the content of the node in JavaScript using the innerHTML property in Firefox. See the end of this post for a workaround.

CSS

.ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
-moz-binding: url('assets/xml/ellipsis.xml#ellipsis');
}

ellipsis.xml file contents

<?xml version="1.0"?>
<bindings
xmlns="http://www.mozilla.org/xbl"
xmlns:xbl="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
>
<binding id="ellipsis">
<content>
<xul:window>
<xul:description crop="end" xbl:inherits="value=xbl:text"><children/></xul:description>
</xul:window>
</content>
</binding>
</bindings>

Updating node content

To update the content of a node in a way that works in Firefox use the following:

var replaceEllipsis(node, content) {
node.innerHTML = content;
// use your favorite framework to detect the gecko browser
if (YAHOO.env.ua.gecko) {
var pnode = node.parentNode,
newNode = node.cloneNode(true);

pnode.replaceChild(newNode, node);
}
};

See Matt Snider's post for an explanation of how this works.

CSS style to truncate long text doesnt work

add your ellipsis styling to the .navbar-header instead, you also need to define a width or max-width, you can see this working on my codepen

alternatively you can add width or max-width to the .navbar-title but as its an inline element you will need to change the display to inline-block too I believe.

I need an overflow to truncate from the left, with ellipses

Try to use this trick:

HTML

<p class="ellipsis">ert3452654546</p>

CSS

.ellipsis {
overflow: hidden;
width: 60px;
direction: rtl;
margin-left: 15px;
white-space: nowrap;
}

.ellipsis:after {
position: absolute;
left: 0px;
content: "...";
}​

FIDDLE

Truncating text inside a div

Use these styles:

white-space: nowrap;      /*keep text on one line */
overflow: hidden; /*prevent text from being shown outside the border */
text-overflow: ellipsis; /*cut off text with an ellipsis*/

Smart way to truncate long strings

Essentially, you check the length of the given string. If it's longer than a given length n, clip it to length n (substr or slice) and add html entity (…) to the clipped string.

Such a method looks like

function truncate(str, n){
return (str.length > n) ? str.slice(0, n-1) + '…' : str;
};

If by 'more sophisticated' you mean truncating at the last word boundary of a string then you need an extra check.
First you clip the string to the desired length, next you clip the result of that to its last word boundary

function truncate( str, n, useWordBoundary ){
if (str.length <= n) { return str; }
const subString = str.slice(0, n-1); // the original check
return (useWordBoundary
? subString.slice(0, subString.lastIndexOf(" "))
: subString) + "…";
};

You can extend the native String prototype with your function. In that case the str parameter should be removed and str within the function should be replaced with this:

String.prototype.truncate = String.prototype.truncate || 
function ( n, useWordBoundary ){
if (this.length <= n) { return this; }
const subString = this.slice(0, n-1); // the original check
return (useWordBoundary
? subString.slice(0, subString.lastIndexOf(" "))
: subString) + "…";
};

More dogmatic developers may chide you strongly for that ("Don't modify objects you don't own". I wouldn't mind though).

An approach without extending the String prototype is to create
your own helper object, containing the (long) string you provide
and the beforementioned method to truncate it. That's what the snippet
below does.

const LongstringHelper = str => {
const sliceBoundary = str => str.substr(0, str.lastIndexOf(" "));
const truncate = (n, useWordBoundary) =>
str.length <= n ? str : `${ useWordBoundary
? sliceBoundary(str.slice(0, n - 1))
: str.slice(0, n - 1)}…`;
return { full: str, truncate };
};
const longStr = LongstringHelper(`Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum`);

const plain = document.querySelector("#resultTruncatedPlain");
const lastWord = document.querySelector("#resultTruncatedBoundary");
plain.innerHTML =
longStr.truncate(+plain.dataset.truncateat, !!+plain.dataset.onword);
lastWord.innerHTML =
longStr.truncate(+lastWord.dataset.truncateat, !!+lastWord.dataset.onword);
document.querySelector("#resultFull").innerHTML = longStr.full;
body {
font: normal 12px/15px verdana, arial;
}

p {
width: 450px;
}

#resultTruncatedPlain:before {
content: 'Truncated (plain) n='attr(data-truncateat)': ';
color: green;
}

#resultTruncatedBoundary:before {
content: 'Truncated (last whole word) n='attr(data-truncateat)': ';
color: green;
}

#resultFull:before {
content: 'Full: ';
color: green;
}
<p id="resultTruncatedPlain" data-truncateat="120" data-onword="0"></p>
<p id="resultTruncatedBoundary" data-truncateat="120" data-onword="1"></p>
<p id="resultFull"></p>


Related Topics



Leave a reply



Submit