Reputation: 14419
I have a simple setup. A div
that contains a title and titleOptions.
The title sometimes is long and I would like it to have an ellipsis
instead of showing the full title. To the right of the title is titleOptions. These can vary. Sometimes delete, edit and move, sometimes a few those, sometimes none. (The title width therefore cannot be fixed, since the titleOptions vary).
How do I ALWAYS have one line for the title and titleOptions. I don't want it to wrap ever, or push the titleOptions below.
I prefer the titleOptions width be fluid, since that would allow a longer title to have more real estate.
Here is a fiddle for a better explanation: http://jsfiddle.net/K8s3Z/1
Upvotes: 12
Views: 357
Reputation: 18462
You can use flexbox.
.titleBar {
width:980px;
overflow:hidden;
border: 1px solid #EEE;
margin-bottom:2em;
display: -webkit-flex;
}
.title {
border: 1px solid #DDD;
white-space:nowrap;
overflow: hidden;
text-overflow: ellipsis;
-webkit-flex: 1;
}
.titleOptions {
white-space:nowrap;
border: 1px solid #DDD;
}
fiddle (which also has other syntax and prefixes needed, etc).
function getByClassName(collection, className) {
var i = collection.length;
var regexp = new RegExp('\\b' + className + '\\b');
var returnSet = [];
while ( i-- ) {
if ( collection[i].className.match(regexp) ) {
returnSet.push(collection[i]);
}
}
return returnSet;
}
if ( ! Modernizr.flexbox && ! Modernizr.flexboxlegacy ) {
var bars = document.querySelectorAll('.titleBar');
for (var i = 0, l = bars.length; i < l; ++i) {
var bar = bars[i];
var divs = bar.getElementsByTagName('*');
var optWidth = getByClassName(divs, 'titleOptions')[0].offsetWidth;
getByClassName(divs, 'title')[0].style.width = bar.offsetWidth - optWidth + 'px';
}
}
The fiddle has custom functions for checking for flexbox (based on Modernizr) if you don't want to use Modernizr (for some reason). Just assigning those responses to a local object Modernizr
in the fiddle. Also, no jQuery, in case you have an aversion to that as well. Both are easy to replace in here, if you're using them.
Upvotes: 10
Reputation: 6948
If you put you options container at the same level as the text and float it, the text should automatically wrap around the container. With a few adjustments you can display one line only and hide the rest.
Try this html:
<div class="titleBar">
<div class="title"><div class="titleOptions">OPTIONS | CLICK ME</div> THIS IS MY TITLE </div>
</div>
And css:
.titleBar {
border: 1px solid #EEE;
margin-bottom:2em;
}
.title {
overflow:hidden;
white-space:nowrap;
text-overflow: ellipsis;
}
.titleOptions {
float:right;
white-space:nowrap;
border: 1px solid #DDD;
}
As a fallback for IE, you could drop the text overflow property on .title and use this instead
/*IE Fallback*/
.titleOptions {
background-color:white;
position:relative;
z-index:10;
}
.titleOptions:before {
content: "\2026 ";
padding-right: 5px;
}
Upvotes: 1
Reputation: 6353
Here is an option using position
ing (CSS only & all browsers supported minus the box-shadow) and even has a nice blending of the text.
.titleBar {
width:980px;
overflow:hidden;
border: 1px solid #EEE;
margin-bottom:2em;
position: relative;
}
.title {
float:left;
border: 1px solid #DDD;
overflow:hidden;
white-space:nowrap;
}
.titleOptions {
border: 1px solid #DDD;
position: absolute;
right: 0;
top: 0;
background-color: #fff;
/* optional... make it blend in instead of ellipsis */
-moz-box-shadow: 2px 0 25px 50px #fff;
-webkit-box-shadow: 2px 0 25px 50px #fff;
box-shadow: 2px 0 25px 50px #fff;
}
Screenshot of blending... incase you didn't catch it.
Upvotes: 4
Reputation: 26167
To show an ellipsis, you can use the css text-overflow. Though AFAIK, you need to give the container a width so it is aware of where the overflow will occur at.
This CSS property doesn't force an overflow to occur; to do so and make text-overflow to be applied, the author must apply some additional properties on the element, like setting overflow to hidden.
You could run some javascript code after the DOM has loaded to dynamically set the width of .title based on the width of .titleOptions.
Here is a static example of what you're trying to do:
.title {
float:left;
border: 1px solid #DDD;
white-space:nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 76%;
}
Try using js to set width dynamically.
Edit: Here is an example of how you can set width dynamically using javascript (and a little jQuery). Using the css for .title
I have above (minus the width: 76%;
), I added this js:
function getChildByClassName(ele, className) {
for(var i = 0; i < ele.childNodes.length; i++) {
if($(ele.childNodes[i]).hasClass(className)) {
return ele.childNodes[i];
}
}
}
var titleBars = document.getElementsByClassName('titleBar');
var w = 0;
var spacer = 10;
for(var i = 0; i < titleBars.length; i++) {
w = titleBars[i].clientWidth;
w = w - getChildByClassName(titleBars[i], 'titleOptions').clientWidth - spacer;
$(titleBars[i]).children('.title').eq(0).css('width', w + 'px');
}
Upvotes: 9