My page displays a set of news items, each with a headline. The headline can be a variable number of words, but I’d like them to always be on two lines with as balanced widths as possible. For example:
Announcing Bosun, our new open
source monitoring & alerting system
Stack Exchange for
the iPad is here
A
headline
Obviously I could chuck in a <br> element at the correct break point and I could even try to calculate its position automatically, but is there any CSS that will do this for me? It’d be nice to get this working in a responsive layout. I don’t care particularly about browser compatibility so answers that reference upcoming specs that achieve what I want will be accepted too.
So there’s no way of doing this in CSS currently, but CSS4 Text has just added text-wrap: balance to the draft specification which does exactly what my question asked for. I’ll leave this as the answer for the glorious future where this is supported.
http://dev.w3.org/csswg/css-text-4/#text-wrap
That should work:
div {
overflow: hidden;
max-width: 165px; // define max width of the text
height: 30px; // define height of the text based on font size and line height
line-height: 1.4;
font-size: 11px;
}
Plus to make it fancy you can try to add ellipsis (...) to the end of the bottom line:
div {
overflow: hidden;
max-width: 165px; // define max width of the text
height: 30px; // define height of the text based on font size and line height
line-height: 1.4;
font-size: 11px;
-o-text-overflow: ellipsis;
-ms-text-overflow: ellipsis;
text-overflow: ellipsis;
}
Related
There's a billion of tutorials, but none have worked for me unfortunately.
I need some artistnames to be in the header, centered, but with a css ellipsis, so very long names gets the "..." and will be truncated.
You can see the design here: http://www.cphrecmedia.dk/musikdk/mobile/artistchannel.php
Remember to resize your browser window.
Its meant for mobiles, so I cannot have any fixed withs and it should work with all kinds of mobile screensizes. I can make the ellipsis work, but then the text is no longer centered.
Any clue on how to do this best? I would really like to avoid any javascript as performance is highly important.
You need to update the rules for h1 with overflow & text-overflow.
.header h1, .headerwhite h1 {
font-size: 15px;
line-height: 49px;
text-overflow: ellipsis;/* generates dots if text on one single line and truncated */
overflow: hidden;/* triggers text-oveflow and mids floatting elements */
white-space: nowrap;/* keep text on a single line to trigger text-overflow; */
display: block;/* reset to basic behavior of h1 , else inline-block drops down if not enough room */
}
basicly same answer as dartanian300 :)
You may control the max-width of h1 too and add a margin:auto; : demo
UPDATE
Using display: inline-block simply removes the h1 altogether on smaller screens. You should avoid this.
Also, technically, the text is still centered. It takes into account the ellipsis when centering the text.
ORIGINAL ANSWER
In order for the ellipsis styling to work, you've got to set a few things on the element with the text:
display: block;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
display: block ensures that the box you're trying to generate ellipsis on is shown as a block. If it's not, it won't know where the bounding box is.
text-overflow: ellipsis obviously should generate the ellipsis.
overflow: hidden for some reason, browsers won't generate the ellipsis unless you have this. I believe it has to do with the fact that the text will just flow outside the box with it.
white-space: nowrap this prevents your text from wrapping onto multiple lines. That way, you have one line with ellipsis at the end.
That work?
So I have 2 divs, 1 within another. #outer the outermost div and #frame the div w/in #outer.
With regards to #outer, I've applied a background picture that is to take up the entire browser space.
frame is where the text will go - text will constantly change with different string lengths. However, I only want #frame to occupy the center portion of #outer, so that text does not leak outside (this is because the background picture in #outer has a chalkboard-like figure - I want it to look as though the text is being written onto that chalkboard without text running outside the lines).
I'm supposed to use padding for this right? As in set the padding attribute on #frame right? Or should I adjust the frame's width? How do I center this sucker?! Float? Pad? I'm lost...
HTML:
<div id='outer'>
<div id='frame'>
</div>
</div>
CSS:
#outer {
height: 612px;
background: url('http://i151.photobucket.com/albums/s147/yungottii/abveaspi_background_final.png') no-repeat 0 0 scroll;
background-size: 100%;
}
#frame {
text-align: center;
height: 612px;
padding: 50px;
overflow: auto;
font-family: Didot, "Didot LT STD", "Hoefler Text", Garamond, "Times New Roman", serif;
font-size: 60px;
color: black;
}
I've been messing with padding and border and margin for the past hour trying to get a grasp on the box model in general. Any quick pointers that anyone can help me accomplish this?
PS It may be difficult to see, cuz this probably isn't fully compatible with your browser settings yet, but you can go to:
http://www.abveaspirations.com
to see what the above code is currently spitting out. As you may be able to see, the especially long strings/text leak outside of the glass. BTW I'm using textualizer plugin, not sure if that changes anything...
This is a little more complicated of an answer than it could be.. This can pretty much be done with padding, but I feel that this way is the most smooth and solid result for what you are doing, and it also works extremely well for a responsive site, so it won't break as you scale your screen size up and down.
Here's the demo of this in action so you can follow along with what I'm saying, and look at the full code at the same time:
http://jsfiddle.net/9FtFh/1/
Ok so first of all, just to set up your outer div, I basically just set position: relative; on it, everything else is fine. This is just because I'm setting the frame to be position: absolute; and I want it to position relatively to this outer div.
After that, lets look at the changes to the frame...
position: absolute;
top: 10%;
bottom: 20%;
left: 15%;
right: 15%;
These styles serve the purpose of stretching the bounds of the div out to certain points. Notice that there is no set height or width on the frame element anymore, those must be taken out. Basically, these styles say that the top of the div will be 10% from the top of the outer div. The bottom will be 20% from the bottom of the outer div.. and so on. I used percentages instead of pixels, as this will make sure the positioning adapts to whatever width the screen is.
Notice that I set a dotted border on the frame so that you can see where the box is being sized and positioned at all times.
I didn't worry about vertical centering of the text content because I'm fairly certain that your plugin for the text effect handles that. Just let me know if I was wrong on that count, and I can expand on that.
Now, there's another challenge in the fact that once the screen gets to a certain smaller size, the image begins to have a smaller height than the outer container. This probably isn't something you want, so I added a media query:
#media only screen
and (max-width: 1060px) {
#outer {
height: 0;
padding-top: 47.85%;
}
}
What this does is it applies styles only after the screen gets to be a certain width. I choose the max-width based on the point where the image starts to shrink past the edges of the container.
As for the styles that get applied, this is a little trick for maintaining the aspect ratio of a container on re-size. I set the height to 0, and then re-create the height using padding-top. The number that I used (47.85%) is an approximate ratio of the height of the image relative to the width. (The image is about 47.85% as high as it is wide.) This will now begin to scale the whole container down with the screen, to match the image. Because your frame is positioned absolutely, it will stay around for the ride, and maintain it's percentage based position.
One thing I did not do that you might be interested in is setting another media query once the image width starts to get so wide that the bottom gets cut off. At this point you could set the frame bottom to be 0% so that it matches that. (you may also need to periodically update the top property, as the screen gets wider and wider. This is only because you have a set height cutting off the image, making the percentages irrelevant.)
In that example I linked to, try re-sizing that bottom frame's width larger and smaller, and watch how the dotted lines stay right where they should be, and the content inside adjusts. Also notice how the container stays the set height up until the image gets too small, and then everything begins to scale down.
There's only one glaring issue that I can see left, and that is that because all of your text content gets positioned absolutely letter by letter, re-sizing the screen will cause elements to spill out, until a new slide comes in, and the letters are re-positioned based on the new width. That's just something to keep in mind going forwards.
Option 1 http://jsfiddle.net/bdbpY/
#outer {
background-size: 100% 100%;
}
And it works. The only issue is that it will change the height/width of your image to something other than you may want.
Option 2 http://jsfiddle.net/bdbpY/1/
Another option which probably will work better is this
#frame {
height: 100px;
overflow: hidden;
}
This works how you want.
If you're going for adjustable widths instead of a fixed px, you can than try stuff like
#frame {
max-height: 50%;
overflow: hidden;
}
Option 3 http://jsfiddle.net/qLNFz/
This is probably the best choice , and easiest.
All I did was this
#frame {
height: 29%;
padding: 10px 20px;
}
HTML
<div id='outer'>
<div id='frame'><span class="sp">Sample Sample Sample Sample Sample Sample Sample Sample Sample Sample Sample Sample Sample Sample Sample </span>
</div>
</div>
CSS
* {
margin:0px;
padding:0px;
}
#outer {
background: url('http://i151.photobucket.com/albums/s147/yungottii/abveaspi_background_final.png') no-repeat 0 0 scroll;
background-size: 100% 100%;
width:1000px;
margin:0px;
}
#frame {
margin:20px auto;
text-align: center;
width:600px;
height:400px;
padding: 50px;
overflow: hidden;
font-family: Didot, "Didot LT STD", "Hoefler Text", Garamond, "Times New Roman", serif;
font-size: 60px;
color: black;
border:1px solid black;
}
.sp {
overflow:hidden;
}
Demo
I have used overflow:hidden; for long text to accommodate in the frame. So your board will be like this http://jsfiddle.net/3pNSx/70/
Is it possible to create a rule that will make the following HTML:
<div style="width: 100%"></div>
of one line height using just CSS, or do I need to put as the content?
Some possibilities:
Set height (or min-height) to the line-height's used value.
The initial value of line-height is normal, whose used value is implementation-dependent, but the spec suggests a number between 1.0 and 1.2
In my case (FF27 for winXP with font-family: "times new roman") that value is 1.25, so you could use height: 1.25em. However, that value might be different with other fonts or implementations.
Then, it's better to manually set line-height to some value, like line-height: 1.25em.
div {
border: 1px solid red;
min-height: 1.25em;
line-height: 1.25;
}
<div></div>
Note that if you want to set those styles to the elements only when it has no content, you can use the :empty pseudo-class:
div:empty {
border: 1px solid red;
height: 1.25em;
line-height: 1.25;
}
<div></div>
Inserting some content to the element.
For example, you can add a normal space and set white-space to pre-wrap (or pre) to prevent the space from collapsing:
div {
border: 1px solid red;
white-space: pre-wrap;
}
<div> </div>
Alternatively, you can use a zero-width space ()
div { border: 1px solid red; }
<div></div><!-- There is a zero-width space inside -->
As you say, would also work. However, it is a non-breaking space, so its purpose is preventing automatic line breaks. Then, using it would be semantically incorrect IMO.
And as #BoltClock says, those whitespaces could be inserted with CSS pseudo-elements, but note that might not work on very old browsers.
Just another solution:
.your-selector:empty::after {
content: ".";
visibility: hidden;
}
That depends on your definition of a single-line height, since there isn't a CSS unit that corresponds to the computed line height of an element.
If you know the exact line-height value for this element, then you can just explicitly set height to the same value. But, given your question, this is likely not the case.
There is a unit that corresponds to font size, em, which you can use if the height of one line is equal to the computed font size:
<div style="width: 100%; height: 1em"></div>
Otherwise you will have to put in some sort of filler content. You can either throw in an and be done with it:
<div style="width: 100%"> </div>
Or go a little overkill by writing a CSS rule with a pseudo-element, but you must be able to target this element somehow:
div::before { content: '\00a0'; }
If the element may or may not have content but you want it to have a minimum height,
use min-height where you would have used height instead, or
select div:empty::before instead if you choose to use a pseudo-element so the filler doesn't get inserted if there is content.
The solution with visibility: hidden; is clever. It is simpler to set the content to Unicode character feff, which is the byte order mark. This has no width but has height; it behaves the same on every browser all the way back to IE6.
.your-selector:empty::before {
content: '\feff';
}
I have found that WebKit (at least on Mac OS) applies slightly different (1px) line height to bold text than normal text for some fonts. To enforce uniformity (in this case, we would need to apply even to non-empty selectors):
.your-selector::before {
content: '\feff';
font-weight: 900;
}
The problem I had was with jQuery Terminal that needed to have empty line same size of normal lines. Other solution was problematic because when using fixed line-height there was gaps between lines also there was bug in Firefox that I've reported about layout with font-size + line-height.
By best solution so far is this:
div::before {
content: '\0200B';
float: left;
display: block;
}
and no line-height/min-height in the code and it works perfectly. Also when not using line-height it have good looking style selection without gaps.
What height do you want to keep? Will that be in relation with your font-size? That can be in em, pt, px or %.
This is just an example where 1.5em is arbitrary value:
<div style="width: 100%; height: 5px" ></div>
If you don't have anything to write in this div, use some height value.
I have tried all the solutions I can find to this problem, but the damn thing keeps overflowing. To be specific, when I add anything more than an extra word to the "Watch the space" text to the right here http://robinlovelace.net/ , it disappears from where it should be an moves to the bottom of the page, below the 'comments' link.
I've tried adding overflow: auto; and word-wrap: break-word; in the CSS #home_right area, (as recommended here) but this fails also. It's such a simple problem I think I must be missing something that may be of use to others.
You need to set a width on it.. try the following:
#home_right {
width: 220px;
}
This is what it currently is:
#home_right {
overflow: auto width: 10 em; /* Syntax is incorrect, you forgot the ; */
}
In this case, there is actually no need for overflow.. all you needed was a width!
This is because the div is floated and when you add content to it the width is extended by the text and becomes larger than the available area and so it floats to the nearest available space. To prevent the text from widening the div, you need to set a width on the sidebar. Using firebug I figured out that in your case you need to add this in your CSS for #home_right:
width: 224px;
What you have:
overflow: auto width: 10 em;
What you should have:
overflow: auto;
width: 10em;
Spaces and semi-colons, be careful!
I'm deep into some iPhone (Safari/WebKit) web app development at the moment and want to have items of a set height with title text and body text such that 3 lines are always showing. If the title text is short, 2 lines of body text should show. If the title text is very long, it should take up a maximum of 2 lines and leave 1 line for body text. Whenever text is truncated, it should display an ellipsis as the last character.
I've come up with the following that does everything I need, except that it does not display the ellipsis. Is there a way to get this solution to satisfy that last requirement?
(source: segdeha.com)
<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
#container {
width: 100px;
}
p {
/* white-space: nowrap; */
font-family: Helvetica;
font-size: 12px;
line-height: 16px;
text-overflow: ellipsis;
max-height: 48px;
overflow: hidden;
border: solid 1px red;
}
strong {
/* white-space: nowrap; */
font-size: 16px;
display: block;
text-overflow: ellipsis;
max-height: 32px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="container">
<p>
<strong>Short title</strong>
This is the text description of the item.
It can flow onto more than 2 lines, too,
if there is room for it, but otherwise
should only show 1 line.
</p>
<p>
<strong>Long title that will span more
than 2 lines when we're done.</strong>
This is the text description of the item.
It can flow onto more than 2 lines, too,
if there is room for it, but otherwise
should only show 1 line.
</p>
</div>
</body>
</html>
One solution to this problem is to fade the text out rather than to add an ellipsis. If this is an acceptable alternative for you then please read on.
Since the line height is fixed at 16px you can use a simple png image with a gradient (or use a css3 gradient) that goes from transparent to the relevant background color and position it in the lower right corner of the paragraph.
The same will work for the headline if you position the gradient image 16px from the top so that it will only be visible if the heading reaches two lines (thanks to overflow hidden).
You can specify the font size to be used within this field (font-size), then fix the height and width of the field (because now you know how many lines of font-size size can fit), and then use the overflow property (not text-overflow)
Try this one: jsfiddle.net/7BXtr/.
It only uses CSS (no JavaScript).
Basically, the text has overflow: hidden applied, and ... is positioned after it.
Downsides:
An ellipsis will always appear after the description, even if it is short.
The ellipses always appear at the same positions on the right.
I know this is too late of a response. But for others looking for the same problem:
I am developing on top of Magnus Magnusson answer.
To create a translucent shade, you can use the box-shadow property which can be used to create an inner shade effect.