Squeeze a table column to it's minimum possible width - css

Throughout my website, I have many <table>s in which there is a specific column we want to have squeezed to it's minimum possible space (without having it's text wrapped). Other sibling cells share the rest of the space automatically.
I'm using the following trick and it works in all browsers except IE7-. (At this time I actually only care about IE7)
table {width:100%;}
table td.min-col {white-space:nowrap; width:1px; }
jsFiddle link: http://jsfiddle.net/vm8gc/23/
If you try this in IE7 you will notice it acts differently (not expected behavious). -- see screen capture below.
Can anyone think of a fix for IE7 to achieve this?
Attachments:
All other browsers:
IE7:

CSS 2 Version
For some reason Internet Explorer seems to ignore white-space on TDs. Best way around the problem is to use a span inside the TD.
<td><span style="white-space: nowrap;">This should not wrap</span></td>
As usual IE doing it's own thing ;)
For info on white-space support, see here:
http://www.quirksmode.org/css/whitespace.html
PRE Version
An alternative which would have better support with older browsers would be to do the following:
<td><pre>This will not wrap</pre></td>
And then have your pre element set-up to either be styled in the same way as your normal text or enable it to inherit style from it's parents (inheriting probably has less support that just specifiying the style):
td pre { font-family: inherit; font-size: inherit; color: inherit; ... }

Related

Browser specific CSS padding for firefox field

I have a dropdown list in my application whereby in order to center it I must add padding-top 10px while on Mozilla Firefox but on google chrome it does not need the padding. How can I target the select list to set this browser specific. I was hoping I could have done something like the following:
select {
-moz-padding-top: 10px;
-webkit-padding-top: 0px;
}
Any ideas of how I could get round this? Fiddle of problem shown below, if you check this in Chrome and then Firefox, I want it so that text is always in middle
http://jsfiddle.net/uHDa6/
Note: the first part of this answer is now obsolete, as this feature has been removed from Firefox. For the real answer, read on from "However".
The answer to your question is: yes, it's possible to put Mozilla-specific CSS in a stylesheet. (Not in an inline style attribute.)
In this case, you would write
#-moz-document url-prefix() {
select {padding-top:10px;}
}
which is simply the Mozilla-prefixed version of the #document rule, that is not recognised by other browsers.
However, the actual solution to the problem of the mismatched text position is to not set the height, but only the padding of the select. No hacks.
style="font-size: 14px; padding: 11px 0 11px 5px;"
That has the desired effect in all browsers. See new fiddle.

CSS: is it possible to scale the image in a :before {content:url(..)} element?

ok, I admit I'm in the realm of playing around now...
What I want to achieve:
there should be a plus sign before utility links that are used to add some elements in our web application.
It would be good if this sign scales according to the font size the user has set.
What I've tried:
<style type="text/css">
a.addLink:before {
content: url('images/add.png'); height: 1.2em;
}
</style>
<a class="addLink" href="#" onclick="freakyJSFunction">testlink</a>
sadly, the height attribute is ignored.
I know i could just insert a normal <img../> before every link, but that's not as maintainable as we want it to be.
Or I can use one of the fancy unicode characters, for example
content: "\271a"; font-size:1.4em; color:green;
for now, I'll go with the unicode idea (just tested this in IE8...nope, IE 8 doesn't display that character ("greek cross")...:-( )...ok, I will go with the unicode idea if I find a suitable charakter that is displayed in IE8, FF and maybe chrome..
still, I wonder if my initial idea is somehow doable
In css3 you have a background-size property.
http://jsfiddle.net/jQgQv/7/
However background-image can't be applied trough content: so it won't work in your case using :before - only as a normal class.

Is there a CSS workaround for Firefox' bug: inline-block + first-letter with changed size

It's better to see a bug for yourself in Firefox: http://jsfiddle.net/kizu/btdVd/
The picture, showing the bug:
And the bug filled in 2007 on bugzilla.
The bug appears when you're adding ::first-letter pseudo-element with display: inline-block, and then change the font-size of this first-letter.
More letters in a word after the first: more extra space added (or subtracted — if the font-size is lesser than block's).
Adding float: left to the first-letter inverts the bug: with bigger font-size the width of inline-block shrinks.
So, the question: is there any CSS-only workaround for this bug? It's somewhat killing me.
I've found that triggering reflow on the whole page (or any block with a problem) fixes the problem, so I've found a way to trigger it on every such block with one-time CSS animation: http://jsfiddle.net/kizu/btdVd/23/
Still, while this fix have no downsides in rendering, it have some other ones:
it would work only for Fx5+ (that supports animations);
it still flashes the original bug for a few ms, so it's maybe somewhat blinky.
So, it's not an ideal solution, but would somewhat help when Fx4- would be outdated. Of course, you can trigger such fix onload with JS, but it's not that nice.
I don't think there's a good solution.
I have come up with a flaky solution for you though:
.test:first-letter {
font-size: 2em;
letter-spacing: -0.225em;
}
Add the letter-spacing style to the :first-letter selector in your Fiddle, and you'll find the blocks go back to roughly the right size.
Explanation:
Basically, the bug is being caused by the whole block taking its size from the font specified in the first-letter.
What I'm doing here with the letter-spacing is trying to adjust the size of this font, without affecting it's physical appearance. Adjusting the letter spacing in this way in normal text would result in the letters overlapping each other by .225 of a character width on either side.
I was initially hoping that a value of -0.25 would be sufficient -- ie a quarter of a character on each side would reduce the width of each character by half, which would be what we want because the first letter is font-size:2em, so it's twice as big.
However, the calculation isn't quite as clean as that, because the first and last characters in the string would only be overlapped on one side each, and because the first letter does in fact want to be double width, even if the rest of the characters don't.
All of this means that the exact letter-spacing value required to counter-act the bug will vary depending on how long the text, as well as the font sizes of the original text and the first letter. This is why I had to experiment a bit with the value of the letter spacing to get it working, and also explains why I couldn't get quite a perfect fit on all the text rows in your Fiddle. I would have needed a slightly different value for each block.
The value of -0.225 seems to be about the closest I can get to it being right for all your examples, but in practice you'll need to adjust it to suit your site.
Don't forget also that this is a Firefox bug, and therefore you'll need to write it in as a browser-specific hack of some sort. And be careful to keep an eye on the Firefox bug report you linked; when it does get fixed, you'll need to work out a way to keep your hack in place for users of old versions, but remove it for users with the fix.
[EDIT]
The only other working solution I've come up with is simply not to use the features which trigger the bug. ie drop the :first-letter selector, and use a separate <span> for the first letter of your text if you want to style it differently.
This is the obvious answer really, and would of course solve the problem (and would also mean that your styled first letter works in older browsers), but it would not be ideal from a semantic perspective, and more importantly doesn't actually answer the question, which is why I didn't offer it as a solution in my original answer.
I have been trying to find alternative work around for the bug as well, but the options are limited, and nothing I've tried has given as good results as my initial suggestion.
I tried a hack of making the :first-letter invisible, and using :before to display the big leading capital letter. However, this didn't work for me. I didn't linger on it too long so you may be able to get it working, but there is a problem with it in that you'd have to define the leading letter in your CSS, which wouldn't be ideal.
Another possible solution is to use the CSS font-stretch: condensed; property on the :first-letter. This would reduce the width of the first letter back to 1em, and thus resolve the width issue of the rest of the text. The down sides of this, however, are that firstly it would make the leading letter look squashed, which is probably not what you want, and secondly this style only works for fonts which support the condensed property. It turns out that this isn't well supported by the standard fonts, so may not be workable for you.
In the end, the original letter-spacing solution is still the only way I've found to really work around the bug.
This bug still exists, but some of the fixes don't work anymore. Even after triggering a reflow with an animation, the inline-block returned to the same size for me. I couldn't use the letter-spacing trick because I am already using it on the first letter, that is what is causing the problem for me. I solved the problem by adding this to the CSS for the affected selector:
-moz-padding-end: *number of pixels to compensate*;
At the moment, moz-padding-end seems to be specific to Firefox, and it can add or remove width to the end of the inline-block. Because this is a Firefox specific bug, that did the trick for me.
I know this thread is quite old now, but apparently this bug has not been fixed yet.
Using animation does work but there is a noticeable FOUT (Flash Of Unstyled Text). I was able to work around the problem by wrapping the first-letter in a span. This does work around both the sizing issue and the FOUT, it does add extra elements to the markup, so it depends on the needs of your site/application if this is the best fit.
.test {
background: rgba(0,0,0,0.15); /* For visualisation */
display: inline-block;
}
.test:first-letter {
font-size: 2em;
}
.test2:first-letter {
float: left;
}
.test3:first-letter {
font-size: .5em;
}
<h1>Inline-block with bigger first-letter</h1>
<span class="test">Broken</span>
<br><br>
<span class="test"><span>F</span>ixed</span>
<h1>+ floating to first-letter</h1>
<span class="test test2">Broken</span>
<br><br>
<span class="test test2"><span>F</span>ixed</span>
<h1>small size for first-letter</h1>
<span class="test test3">Broken</span>
<br><br>
<span class="test test3"><span>F</span>ixed</span>
<h1>small size, floating first-letter</h1>
<span class="test test2 test3">Broken</span>
<br><br>
<span class="test test2 test3"><span>F</span>ixed</span>
As of 2023, this is still happening in Firefox.
This is my solution using SASS, but you can see how to make it bare CSS:
txt-brand {
display:inline-block;
}
///Firefox only ///
#-moz-document url-prefix() {
margin-right: .1em;
white-space: nowrap;
&::after {
content: '\00a0';
}
}
}
.txt-brand::first-letter {
letter-spacing: -.11em;
}

box-sizing support in IE7

I just discovered the box-sizing: border-box CSS property which solves a bunch of cross browser layout problems for me.
The only issue I now have is that IE7 doesn't seem to support it. Is there a hack to get IE7 to support it?
There are several ways to do this, none perfect.
As you point out:
Firefox / Opera / Safari / Chrome / IE8+ will recognise the box-sizing property allowing you to use border-boxes.
IE6 will use the old school (correct?) border-box model by default.
However IE7 uses the W3C padding box model when in standards mode, and will not recognise the CSS box-sizing property so there's no way to revert to the border box model. If you need to support IE7 (and you probably still do), you're stuck with one of four options:
1. Conditional Comments:
<!--[if IE 7]>
Special instructions for IE 7 here
<![endif]-->
Use box-sizing for IE8 and 9, then make specific overrides for IE7. This option will be painful.
2. The Schepp Box Sizing Polyfill:
https://github.com/Schepp/box-sizing-polyfill
This excellent Polyfill is an HTC file which modifies the default browser behavior in IE6 and 7 so they use the W3C box model. It's fine for light use, but may cause problems of it's own if used extensively. Use with caution and TEST.
3. Old Style Nested Divs:
The old style nested div approach is still a fine way:
<div style="width:100px; border:1px solid black">
<div style="margin:10px">
Content
</div>
</div>
A non-semantic nested div provides the padding indirectly, with the disadvantage that your markup becomes untidy. Obviously don't use inline styles, I'm using them here for the sake of illustration.
The old adage Never use padding on a fixed width element still stands true.
4. My Preferred Solution - A Direct Child Selector:
The other way round this is with the direct child selector. Say you have a fixed width div containing some content:
<div class="content">
<h1>Hi</h1>
<p>hello <em>there</em></p>
</div>
You can then write a rule to add left and right margins to all the direct children of the div:
.content {
width:500px;
padding:20px 0;
}
.content > * {
margin:0 20px;
}
This will add a little margin to the h1 and p, but not to the nested em, giving the appearance of 20px padding on the content div, but without triggering the box model bug.
5. Consider Dropping IE7 support
IE7 is the last browser not to recognise the box-sizing property. If you're getting little traffic from IE7, you might consider dropping support. Your CSS will be much nicer.
As of late 2013, this is my preferred option.
2017 EDIT: It's probably long past time to drop support for IE7 now, and just use border-box.
You can use a polyfill to make it work on some items, it didn't work for my input fields though.
https://github.com/Schepp/box-sizing-polyfill
box-sizing: border-box;
*behavior: url(/css/boxsizing.htc);
Just note that the behavior url is relative to the page and not the css file. Use relative paths to site's root (start the url with an slash and then go from there).
I'm assuming you're using this to get around the IE6 box model. Unfortunately, there really is no general way to trick earlier versions of IE into supporting arbitrary CSS properties.
I would recommend not using the box-sizing property, because every browser other than IE6 will implement the box model correctly. The Wikipedia article does a good job of explaining how IE6 differs.
To solve this, I recommend using a separate style sheet for IE6, and including it using IE conditional comments. In your IE6 style sheet, you can specify different widths/heights/padding/margins to make your layout look consistent. You can include a style sheet for IE6 only like this:
<!--[if IE 6]>
<link href="ie6sucks.css" rel="stylesheet" type="text/css" />
<![endif]-->

margin-top not working with :before

I have inserted content using the :before pseudo-element for a class. I was trying to position this content using margin-top but firefox is simply ignoring the property. The code follows:
.bef {
line-height: 2em;
white-space: nowrap;
font-size:24px;
display: block;
}
.bef:before {
display: block;
margin-top:2em;
padding: 0;
color: #666666;
content:"Hello";
}
Does anybody know why Firefox may be ignoring the margin-top property?
EDIT: Although margin-top is being totally ignored, margin-bottom:-Xem is working and I am able to move the :before element around
It appears that Darko Z is right.
http://jquery.nodnod.net/cases/577
Hypothetically, the first two test cases (separated by <hr>) should render identically, which they do in Gecko (via FF3.5/Mac), but Webkit (via Safari4/Mac) renders the :before and :after segments as inline. The third test case seems to imply that Webkit currently requires the triggering element to be block in order for the generated content to be block.
The spec isn't clear on what the correct behavior is. It may be worth raising a question on www-style to see which rendering engine's behavior is correct, then filing a bug with the incorrect rendering engine to get it fixed in future versions. Feel free to use my code as a test case.
try making .bef display block also? just a guess that the containing element of the :before needs to be block so it can listen to the margin-top...

Resources