table-layout:fixed use text-overflow:ellipse and a second text showing - css

I am quite new to css, and i was searching already for hours for a solution to this problem.
I have a fixed layout table in a resizable container.
i have a resizing column, that has 2 texts, the first should do a text-overflow:ellipse while the second should always show (if possible).
The requirement is to not show all the text in a table cell if it doesnt fit, but display the last 5 letters.
I figured ill put 2 spans in a td, and give a width to the second, but the width is ignored. When i tried to float the element (i can only float left, cause floating right will put the last 5 letters to the end on an long column with little text, which is not ok), left, but then the first div is not getting smaller so the text-overflow:ellipse is not applied.
E.g i need when td is short:
|Hello budd...ight?|
and
|Hello buddy ho...ight?|
but when td is long:
|Hello buddy how is it going tonight? |
This seems to be a fairly common requirement, so how can i achieve it?
I do not want any javascript, im quite sure it can be solved by css, and maybe some extra divs...
my html:
<table style="table-layout:fixed">
<colgroup>
<col/>
<col width="200px"/>
</colgroup>
<tr>
<td>
<span class="first">Hello buddy how is it going ton</span>
<span class="second">ight?</span>
</td>
<td></td>
</tr>
</table>
my css:
table
{
width: 90%;
margin: 10px;
}
tr
{
height: 100px;
}
td
{
width: 50%;
border: 1px solid blue;
padding: 5px;
height: 100px;
vertical-align: top;
position: relative;
while-space:nowrap;
}
span.first {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
border: 1px solid red;
}
span.second
{
border: 1px solid green;
}
Any ideas how to achieve this?
Any help is very appreciated.
Thanks

Looks like I was able to get something working... here's the changed CSS:
span.first {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
/* --- everything below this line is new --- */
float: left;
padding-right: 5ex;
max-width: 100%;
display: inline-block;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
span.second
{
width: 4ex;
margin-left: -5ex;
display: inline-block;
}​
Compatible in:
I have not tested Opera or IE<9 (although I can pretty much guarantee that IE7 won't run it, because the MDN states that IE introduced box-sizing with IE8)
Explanation:
.first
float: left; lets both spans use the same line when combined with display: inline-block;
padding-right: 5ex; makes room for the last five characters (works with MOST fonts)
max-width: 100%; lets the first span grow up to (but not beyond) the width of the TD
display: inline-block; needed to use max-width effectively
box-sizing: border-box; puts padding inside content area (max-width) use prefixes because Firefox doesn't support the non-prefixed variant yet.
.second
width: 4ex; because it gets screwy if you use 5ex with the below
margin-left: -5ex; makes .second sidle up to the edge of the text area for .first
Note: You can change the ex values to suit your needs, but make sure both
margin-left== -(padding-right)
width<=padding-right- 0.5

Related

absolute positioning of :before in tables vs divs

I'm adding a pseudo-element with :before and position it absolutely to its parent which can be a table or a div. For design purposes the parent also has to have a 20px border.
wwhy are firefox and IE inconsistent and treat the positioning of the pseudo-element differently in the table?
Please have a look at my jsFiddle or the code below.
Tested with IE10, Chrome29 and FF23.
HTML:
<div>i am a div</div>
<table>
<thead>
<tr><th>header 1</th><th>header 2</th></tr>
</thead>
<tbody>
<tr><td>entry 1</td><td>entry 2</td></tr>
</tbody>
</table>
CSS:
table,
div {
border: 20px solid yellow;
position: relative;
margin-bottom: 30px;
height: 50px;
}
table:before,
div:before {
background: red;
content: " ";
position: absolute;
display: block;
position: absolute;
top: 0;
left: 0;
width: 10px;
height: 10px;
}
Seems to be an issue with how Firefox handles absolutely positioned elements within tables. Can you try wrapping the div and table inside their own relatively positioned parent divs?
Check this DEMO.
EDIT: In cases where the html structure cannot be modified, try giving the elements box-sizing: border-box;.
This DEMO seems to work in Chrome, FF & IE on my machine. Let me know if it isn't rendering, and I'll give it another shot.
It seems to be that :before works good with just table less layouts on FF. There is some information on MDN which might be helpful.
Although the positioning fixes in Firefox 3.5 do not allow content to be generated as a separate previous sibling (as per the CSS spec stating "The :before and :after pseudo-elements elements interact with other boxes... as if they were real elements inserted just inside their associated element."), they can be used to provide a slight improvement on tableless layouts (e.g., to achieve centering)
when I added display: block to the table element and removed the fixed height, it is working fine.
table,
div {
border: 20px solid yellow;
position: relative;
margin-bottom: 30px;
display: block;
}
table:before,
div:before {
background: red;
content: " ";
position: absolute;
display: block;
top: 0;
left: 0;
width: 10px;
height: 10px;
}
Working Fiddle
For more information, go through MDN.

CSS hell, I just want a box with min sizes and 1 pixel gap

Please help to achieve this with CSS:
I have array of text strings, from 1 char to 200 chars.
I need to display them in webpage each in separate box.
the box flow is similar to text, left to right until the end of page then wrap
the background color of each box must be cyan.
minimal width and height must both be 50 pixels
1-2 pixel space between boxes (maybe achieve with margin=1)
there must always be at least two pixels between text and the edge of the box
text is vertically aligned to middle
text is horizontally aligned to center
maximum width of box must be 300 px
if text does not fit in 50x300 it is cropped inside the box (box will not grow)
each box should have 1 pixel black border
this must be simple for someone experienced! I already try almost every possible CSS tag; but always something is wrong. I read about CSS boxing, but surprisingly it just made it more compilcated.
<style>
z {
min-width: 50;
#min-height: 50;
padding: 1px;
padding-color: magenta;
margin: 1px;
margin-color: red;
#padding-left: 10px;
display: table-cell;
#height: 50;
#vertical-align: middle;
#text-align:center;
background-color: cyan;
#border: 1px;
#border-color:green;
/* padding:10px 10px 10px 10px; */
border-top:1px solid
border-style:solid;
border-color:#ff0000 #0000ff;
outline-style:dotted;
outline-color:#00ff00;
outline-width: 1px;
color: blue;
}
</style>
<html>
<z>1</z>
<z>abcdefghijklmnope</z><z>2</z><z>blablablabla</z>
</html>
I am pasting this so just you can see how hard and wrong I try.
Ok.
Don't use made up/invalid HTML elements or invalid CSS comments. Just because "it doesn't seem it matters", doesn't mean it won't make problems. When your HTML/CSS is invalid it's impossible to tell if that's the problem or not and you'll only get answers that tell you to correct them.
CSS requires units on lengths. min-width: 50; is invalid and if it's working for you, that just means you aren't writing corrent HTML/CSS and the document is in Quirks mode, meaning the browser emulates old IE errors, which makes debugging just more difficult.
There is no such properties as padding-color or margin-color. Don't make up things. Use a CSS and a validator to check your code. (http://validator.w3.org and http://jigsaw.w3.org/css-validator/).
Using display: table-cell; will just place all elements in one "table row" with no wrapping.
<p><span><span>1</span></span></p>
<p><span><span>abcdefghijklmnope</span></span></p>
<p><span><span>2</span></span></p>
<p><span><span>blablablabla</span></span></p>
p {
min-width: 50px;
max-width: 300px;
height: 50px;
padding: 2px;
margin: 1px;
float: left;
background-color: cyan;
border: 1 px solid blue;
color: blue;
overflow: hidden;
}
p > span {
display: table;
height: 100%;
width: 100%;
}
p > span > span {
display: table-cell;
vertical-align: middle;
text-align: center;
}
See http://jsfiddle.net/DyzAD/1/
(Refined answer)
It's not display:block that is wanted if height/width is required, as the OP also wants the elements to appear next to each other, then break, so float:left; is required rather than display block;
I have implemented the usage of text-overflow:ellipses; to aid in "breaking" the text so the elements will always have a visual balance and vertical alignment. Maybe you could provide a tooltip or html abbr attribute to display the whole text?
float:left on 'z' on any element will (should) fix your problem.
span {
min-width: 50px;
max-width:200px;
height: 24px;
margin: 1px;
float:left;
text-overflow:ellipsis;
overflow:hidden;
vertical-align: middle;
text-align:center;
background-color: cyan;
border: 1px solid green;
padding:10px;
color: blue;
white-space:no-wrap;
}
http://jsfiddle.net/MzKCh/3/
I am not sure if I understand your requirements properly but mixture of float:left elements with display:table-cell will give you text that wraps when it gets to the end of the page but allows both vertical and horizontal center aligning
html:
<div><span>test</span></div>
<div><span>test 1</span></div>
<div><span>loads of text that wraps if the text goes over 300px in length</span></div>
<div><span>loads of text that wraps if the text goes over 300px in length and will hide extra content if really really long</span></div>
<div><span>a</span></div>
<div><span>Amassivewordwithnospacesthatwillalsowrapifithits300px</span></div>
css:
div
{
border:1px solid #000000;
background-color:cyan;
float:left;
margin:1px 1px 0 0;
box-sizing:border-box;
height:50px;
max-width:300px;
overflow:hidden;
}
div > span
{
display:table-cell;
min-width:50px;
max-width:300px;
height:50px;
padding:2px;
text-align:center;
word-wrap:break-word;
box-sizing:border-box;
vertical-align:middle;
}
http://jsfiddle.net/up6KC/6/

How to create a flexible leader line in div after a label field

<div class="titelcontent">
<div class="name">Name</div>
<div class="hzline"></div>
</div>
I want name div and hzline div to auto fit 100% in titelcontent.
The label (for example, Name) will vary in length and I want the red underline to span the remainding space of the titlecontent div.
How do I achieve the following? It is easy to do this using tables but I can't figure out how to do this via span or div.
You can use div like a table by using table-cell.
.titlecontent {
display: table;
}
.name {
display: table-cell;
white-space: nowrap;
}
.hzline {
display: table-cell;
border-bottom: 3px solid red;
width: 100%;
}
See DEMO.
Updated to allow background images to show through
You can make the mark-up a bit tighter by using a pseudo-element as follows:
<div class="wrapper">
<div class="inner">Photoshop</div>
</div>
and use the following CSS styling:
div.wrapper {
color:#82439a;
font-size: 16px;
font-weight: bold;
font-family: tahoma;
line-height: 180%;
background: red url(http://placekitten.com/1000/500) no-repeat left top;
overflow: hidden;
}
div.inner {
position: relative;
display: inner;
color: yellow;
padding-right: 0.50em;
border: 1px dotted yellow;
}
div.inner:after {
content: "\A0";
position: absolute;
bottom: 0;
left: 100%;
border-bottom: 5px solid #d71d00;
width: 1000%;
}
Demo fiddle: http://jsfiddle.net/audetwebdesign/wE8bC/
How It Works
The parent element div.wrapper may contain a background image or be transparent and show the background of some ancestor element. You need to set overflow: hidden.
For the label (<div.inner>), set position: relative and then generate a 100% width pseudo-element with a bottom border to serve as an underline. Use absolute positioning to place div.inner:after to the right of <div.inner> (left: 100%) and make the width relatively large. The pseudo-element will trigger an overflow condition but this is taken care of by hiding the overflow in the parent element. You can control left/right spacing using padding.
You can use set the display property to either inline or inline-block. If you use display: inline, it will work in IE7; adjust the line height as needed for styling.
Note that the generated content is a non-breaking space, hex code "\A0".
Support for IE7
If you need to support IE7, you will need a hack if you use inline-block as discussed in a previous question: IE7 does not understand display: inline-block
IE7 also does not support table-cell so some of the other posted solutions will face the same limitation.
Or an alternative to using display: table:
.name {
float: left;
}
.line-wrapper {
display: block;
overflow: hidden;
padding-top: 6px;
}
.hzline {
border-bottom: 3px solid red;
width: 100%;
}
See example.
I've guessed you are looking something like this. Please find my solution based on my understanding about the image you posted.
HTML
<div>
<span>Photoshop</span>
</div>
<div>
<span>Adobe Illustrator</span>
</div>
<div>
<span>3D Max</span>
</div>
<div>
<span>Maya</span>
</div>
<div>
<span>Windows 8 Pro</span>
</div>
CSS
div {
line-height: 150%;
border-bottom: 5px solid #d71d00;
}
div span{
position:relative;
bottom: -10px;
background:#fff;
padding: 0 5px;
color:#82439a;
font-size: 16px;
font-weight: bold;
font-family: tahoma;
}
Please do let me know your feedback. Thanks

Vertical align middle on an inline-block anchor tag

I have a need for my links and buttons to look the same, but I've been unable to vertically align the text within an "a" tag in the same manner as the "button" tag. It is important to note that the tags need to be able to handle multiple lines of text (so line-height will not work).
a,button {
display: inline-block;
-moz-box-sizing: border-box;
width: 150px;
height: 150px;
vertical-align: middle;
border: 1px solid #000;
text-align: center;
}
See the jsfiddle below:
http://jsfiddle.net/bZsaw/3/
As you can see, I can get it to work with a combination of a span tag inside and setting "display:table" to the "a" and setting "display:table-cell" and "vertical-align:middle" to the span, but that doesn't work in IE7.
a,button {
width: 150px;
height: 150px;
border: 1px solid #000;
text-align: center;
}
a {
display: table;
-moz-box-sizing: border-box;
}
a span, button span {
vertical-align: middle;
text-align: center;
}
a span {
display: table-cell;
}
Looking for a simple CSS only solution.
The only reliable way to I've found align text vertically and allow wrapping of the text if it gets too long is with a 2 container approach.
The outer container should have a line height of at least double that specified for the inner container. In your case, that means the following:
a {
width: 150px;
height: 150px;
border: 1px solid #000;
text-align: center;
line-height: 150px;
display: block;
}
a span {
display:inline;
display:inline-table;
display:inline-block;
vertical-align:middle;
line-height: 20px;
*margin-top: expression(this.offsetHeight < this.parentNode.offsetHeight ? parseInt((this.parentNode.offsetHeight - this.offsetHeight) / 2) + "px" : "0");
}
Add float left on the a tag if you want everything inline. Here's the updated example with long text in the A tag too..
http://jsfiddle.net/bZsaw/13/
You can set the line height on the span to whatever you like and if it is less than half of the line height of the parent, it will center AND allow text wrapping if your text exceeds the parent container width. This works on all modern browsers as far as I know.
All answers are not updated,and all of them are basically hacks, you should use new CSS3 features, in this case flexbox
a,button {
-moz-box-sizing: border-box;
width: 150px;
height: 150px;
display:flex;/*CSS3*/
align-items:center;/*Vertical align*/
justify-content:center;/*horizontal align*/
border: 1px solid #000;
}
<span>Testing 1,2,3</span>
<button><span>Testing 1,2,3</span></button>
That should work for your problem, note that align-items and justify-content will behave the opposite if set flex-direction:vertical, default is flex-direction:row.
Feel free to use, all browsers support it caniuse.com/#search=flex
Also check out the free and excellent course flexbox.io/ he is the best teacher at this
Also check out css-grid, also new in CSS3
If your text won't be larger than the width of the box you could set the line-height equal to the height of the box.
line-height:150px;
The cleanest and most consistent way I found is this
display: grid;
place-items: center;
https://jsfiddle.net/j8bktum9/
Use line-height:150px; and display-inline:block;

How can I make a fieldset legend-style "background line" on heading text?

I'm attempting to style heading text similar to how your default legend text appears in fieldsets; that is to say, I'd like a strikethrough-like line to come up to, but not through, the text. I can't seem to find any information on how I might accomplish this, and since on numerous other questions Google's always directed me to Stack Overflow for answers, I thought someone here may be able to give me advice.
For greater clarity. I'm attempting to get this effect on header text:
Centered Header Text
Is there any way to do this?
See: http://jsfiddle.net/thirtydot/jm4VQ/
If the text needs to wrap, this won't work. In IE7, there will be no line.
HTML:
<h2><span>Centered Header Text</span></h2>
CSS:
h2 {
text-align: center;
display: table;
width: 100%;
}
h2 > span, h2:before, h2:after {
display: table-cell;
}
h2:before, h2:after {
background: url(http://dummyimage.com/2x1/f0f/fff&text=+) repeat-x center;
width: 50%;
content: ' ';
}
h2 > span {
white-space: nowrap;
padding: 0 9px;
}
Edit:
<h2><strike> </strike>Your Text Here<strike> </strike></h2>
Here's how you can do it with a few simple tags and non-breaking spaces.
I'd use an image and call it a day, but this seemed to work for me:
CSS
fieldset {
border-right: 0px;
border-left: 0px;
border-bottom: 0px;
width: 200px;
}
legend {
margin: 0 25%;
}
HTML
<fieldset>
<legend>My Text Here</legend>
</fieldset>
That's the only way I could figure out how to do it with css. Note the width is fixed. Once again I wouldn't do this myself.
I came up with a quick, image-less solution that seems to work pretty well in IE 8+ and other browsers, whilst gracefully degrading in IE 6/7:
<h1>CSS 2.1 EXAMPLE</h1>
h1 { position: relative; text-align: center; }
h1:first-line { background-color: white; }
h1:before {
position: absolute;
z-index: -1;
content: '';
left: 0px;
right: 0px;
height: 1px;
top: 50%;
background-color: black;
}
It does come with the following limitations, though:
The text must match the overall background colour exactly, otherwise it will look weird.
If you want any kind of padding on the text, you need to use non-breaking spaces at either side of the text (see demo).
Heading text must always be on one line (works best if fixed width).
Here's a demo: http://jsfiddle.net/AndyE/3tFQJ/​
With flexbox being supported by all the latest browsers out there, and it being five years since the IE8 requirement was mentioned by the author, I wanted to have some fun building a new solution using that.
A variety of examples getting more complicated:
https://jsfiddle.net/0mL79b4h/1/
https://jsfiddle.net/0mL79b4h/2/
CSS
div {
display: flex;
align-items: center;
}
div:before,
div:after {
border: 1px solid #000000;
border-radius: 2px;
height: 2px;
display: block;
content: "";
flex: 1;
width: 100%;
}
h1 {
text-align: center;
margin: 8px;
}
HTML
<div>
<h1>Example Text</h1>
</div>
<div>
<h1>Multi-Line<br>Example Text</h1>
</div>
Pros:
Uses flexbox!
Super simple HTML.
Left and right sides can be adjusted for asymmetry.
Zero background issues, no inheriting colors, etc.
Fluid width.
Multi-Line support.
Left/Center/Right/Custom Alignment: Just adjust the flex property separately for the before and after elements, higher numbers will dedicate more space to that side. Remove one entirely to left or right align it.
Interesting effects by playing with the border style (I actually chose a round border in this example). Set height to 0px and use border-top instead for a generic line.
Cons:
Uses flexbox. Call me lazy, but I didn't build in any backward compatibility in this example so it'll look odd on a browser that supports psuedo elements but doesn't support flexbox, although last I checked that was Chrome (Firefox, etc), which are all automatically updated anyway. Might want to use some Modernizr.
Here is what I am using on a client's site: http://jsfiddle.net/TPgE4/
Pros:
No images needed - renders instantly
Uses padding to control space on both sides of text
Text can be center aligned, or left/right aligned — just add, e.g., margin-left: 8px or margin-right: 8px on h2 span style definition to make it look good
Cons:
Requires use of additional tag such as <span>...</span> inside heading tag
Text must fit on one line for good appearance
Background color on <span> element must match surrounding background color, so if you have a non-solid background image, gradient or pattern it won't match perfectly
Kind of late to the party, but this is my solution: https://jsfiddle.net/g43pt908/
Requires no images, and doesn't depend on a background color.
HTML
<div class="hr-text">
<span>Some text</span>
</div>
CSS
.hr-text {
border-top: 1px solid #999;
text-align: center;
background-color: inherit;
}
.hr-text span {
display: inline-block;
position: relative;
height: 14px;
top: -12px;
font-size: 14px;
font-style: italic;
color: #666;
background-color: inherit;
padding: 0 10px;
}
I'm not sure if this would suit your need...
h1:before, h1:after {
content: " ------------- ";
}
This doesn't feel like a very good answer, but I'm posting it anyway.
See: http://jsfiddle.net/rFmQg/
<h2><span>Centered Header Text</span></h2>
h2 {
background: url(http://dummyimage.com/2x1/f0f/fff&text=+) repeat-x center;
text-align: center
}
h2 span {
background: #fff;
padding: 0 9px
}
I don't like it because:
You have to use an image.
This. (it only works if the backgrounds match)
body { padding-top: 100px; }
div.parent {
text-align: center;
border-top: 1px solid #ccc;
}
div.parent div {
display: inline-block;
margin-top: -0.8em;
padding: 0 0.5em;
background: #fff;
}
<body>
<div class="parent">
<div>My Text Here</div>
</div>
</body>
This is a fluid-width solution that matches your design and should be ok in IE7 (though I'll admit I didn't check). There are a couple of downsides:
You lose the fieldset/legend semantics.
You can't put a transparent background on the text.
If you don't need it to be fluid-width, onteria_'s solution is probably your best bet.

Resources