IE6 css hacks and their standard css equivalence? - css

in the following there are some IE6 css hacks I need their standard equivalence.
.header {
zoom: expression(runtimeStyle.zoom=1);
z-index: 1;
}
.hmenu ul li {
float: left !important;
}
ul.hmenu li {
margin-left: expression(this.previousSibling==null?'0':'1px');
}
.nav {
position: expression(runtimeStyle.position='relative');
}

ul.hmenu li {
margin-left:expression(this.previousSibling==null?'0':'1px');
}
This is equivalent to li { margin-left: 1px; } and li:first-child { margin-left: 0; }.
I don't see the point of the other expressions, other than to set the properties in an IE<9-only way.

zoom: expression(runtimeStyle.zoom=1);
is setting zoom:1 so you can achieve hasLayout
float: left !important;
!important is supported in all browser and simply adds another layer of specificity to your declaration. i am quite positive that !important is not important in the above css...no pun intended :)
position: expression(runtimeStyle.position='relative');
runtimeStyle object represents the style of the object, which overrides the format and style specified in global style sheets, inline styles, as well as HTML attributes.
in this case, on pageload, .nav's position is set to relative

Related

Simplify css selectors with the same parent

.content p, .content ul, .content h1 {
text-indent: 35px;
}
Are there any shortcuts for this selector, like .content p, ul, h1 {}?
                                                           
                                     
With normal CSS you do not have a choice.
With CSS compilers like SASS or LESS you can write something like that:
.content {
.p, ul, h1 {
text-indent: 35px;
}
}
I nowadays highly recommend using Compass which makes writing CSS so much more fun.
There is a :matches() functional pseudo-class in Selectors Level 4 (aka CSS 4):
.content :matches(p, ul, h1) {
text-indent: 25px;
}
However, it isn't supported by any browser yet. But there are :-webkit-any() and :-moz-any() that bring the same functionality to Chrome and Firefox respectively.

SASS Replicating nested selector

I'm using SASS for a project and so far I'm pretty satisfied with it.
However I have some code that should only be presented for IE 7 and below, using the class name .ie-lt8 for that. But when i extend that selector in SASS, with a nested selector i create multiple selectors.
Example (extending a display: inline-block code for IE):
SASS
/* My extension code */
.ie-lt8 %ie-inline-block {
display: inline;
zoom: 1;
}
/* I want the li to be inline-block */
#my-ul li {
display: inline-block;
#extend %ie-inline-block;
}
CSS produced
/* My extension code */
.ie-lt8 #my-ul, #my-ul .ie-lt8 li {
display: inline;
zoom: 1;
}
/* I want the li to be inline-block */
#my-ul li {
display: inline-block;
}
Generally this is just fine, but the #my-ul .ie-lt8 li worries me a little. In this example it's ok as the code works fine with both selector (the mentioned selector just doesn't exists). But what if i have another code where the selector DOES matter, then this would cause a problem.
A thought example:
SASS
/* I want the div to get a red border,
but the div inside .container to have a green border */
#myid .container div { border: 5px dotted green; }
#myid div {
#extend %red-border;
}
/* My extension code */
.container %red-border {
border: 1px solid red;
}
CSS it would produce
/* I want the div to get a red border,
but the div inside .container to have a green border */
#myid .container div { border: 5px dotted green; }
/* My extension code */
.container #myid div, #myid .container div {
border: 1px solid red; /* [OVERRIDE OF THE BORDER] */
}
My question is then; is there a way to make SASS only take the initial selector, without creating multiple selectors from a nested selector (a lot of selectors in one sentence)?
I tried gooling for this issue, but i find it hard to find any articles/blogs/etc. regarding this issue.
UPDATE
I'm aware of various workarounds, such as using #mixin's instead. I was just wondering whether there was something i missed regardig SASS, or if someone could tell me why this is? Cause it seems to me like it's kind of a bug.
My answer is in SCSS - not SASS so you'll have to convert...
For browser targeting like this, I would recommend using mixins, and furthermore - #content within a #mixin to achieve your desired results. It also sets up a much more understandable set of rules with context.
For your specific example, it's as simple as moving your inline-block fix into a mixin instead of declaring only as a class.
#mixin ie7-inline-block {
display: inline;
zoom: 1;
}
#my-ul li {
display: inline-block;
.ie-lt8 & {
#include ie7-inline-block;
}
}
Even better than that though, by using #content, you can always ensure that your style is prefixed with .ie-lt8 by making a mixin like so:
#mixin ie7 {
.ie-lt8 & {
#content;
}
}
#my-ul li {
display: inline-block;
#include ie7 {
display: inline;
zoom: 1;
}
}
Which will output the same css, but allows your IE7-Specific styles to be wrapped each time in some context that makes sense to anyone who reads your code.

:hover:before text-decoration none has no effects?

As title, I'm adding icons using .icon-*. When adding an icon to an hyperlink:
Email me!
The content inserted by content property shows the underline text-decoration on hover. I'd like to disable the text-decoration only for the content before:
[class^="icon-"]:before, [class*=" icon-"]:before {
font-family: 'IcoMoon';
font-style: normal;
speak: none;
}
.icon-mail:before {
content: "\37";
}
[class^="icon-large-"]:before, [class*=" icon-large"]:before {
font-size: 48px;
line-height: 48px;
}
a[class^="icon-"]:before, a[class*=" icon-"]:before {
margin-right: 5px;
vertical-align: middle;
}
I've tried this but it's not working (decoration is still visible):
a[class^="icon-"]:hover:before, a[class*=" icon-"]:hover:before {
text-decoration: none;
color: white;
}
Insert display:inline-block; in your css. Something like the one below:
.icon-mail:before {
content: "\37";
display:inline-block;
text-decoration:none;
}
Here is the JS FIDDLE:
http://jsfiddle.net/73p2k/18/
As the :before pseudo-element is rendered as a descendant box (more specifically, just before the first child content box) of its generating element, it obeys the same rules its normal descendant boxes do with respect to text-decoration:
The 'text-decoration' property on descendant elements cannot have any effect on the decoration of the ancestor.
See these answers for more details:
CSS text-decoration property cannot be overridden by child element
How do I get this CSS text-decoration override to work?
There isn't any good way around this... the only alternatives that come immediately to mind are:
Wrap the text in its own span element, then apply text-decoration to that span, as shown by skip405. The disadvantage is, of course, extra markup.
Use an inline block background image instead of inline text in an icon font with your :before pseudo-element (I've also corrected the inconsistencies with your class selectors):
[class^="icon-"]:before, [class*=" icon-"]:before {
display: inline-block;
width: 1em;
height: 1em;
background-size: contain;
content: "";
}
.icon-email:before {
background-image: url(icon-mail.svg);
background-repeat: no-repeat;
}
.icon-large:before {
width: 48px;
height: 48px;
}
a[class^="icon-"]:before, a[class*=" icon-"]:before {
margin-right: 5px;
vertical-align: middle;
}
The advantage this has over skip405's solution is that you don't have to modify the HTML, but given that it uses SVG vector background images and background-size, it won't work in IE8.
If you do need IE8 support, then you have to fall back to bitmap images:
.icon-email:before {
background-image: url(icon-mail.png);
}
.icon-email.icon-large:before {
background-image: url(icon-mail-large.png);
}
A pseudoelement selector must be the last item in a selection chain.
You can apply a style to element:hover:before but not to element:before:hover.
You can set height & overflow:hidden for :before element, and text-decoration will not be visible :)
Tried some things using just the a tag as a markup, but alas. A possible workaround for you may be to inner wrap the link in another element, a span, for instance. Thus you can have the underline on this element (instead of a pseudoelement) - which is perfectly controlled by css.
A live example is here: http://jsfiddle.net/skip405/fQHUH/
This solution worked for me. It excluedes the pseude-elements.
But for this you need to wrap the content of the <a> tag into an extra element.
a:hover { text-decoration: none; }
a:hover > * { text-decoration: underline; }
<span>content</span>

"Best clearfix ever?"

I saw this rather different method for clearfix here: http://www.marcwatts.com.au/blog/best-clearfix-ever/
It proposes adding the following CSS code which automates clearfix and does not require you to add a 'clearfix' or similar class to the elements you want to clear.
/* our Global CSS file */
article:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
aside:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
div:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
footer:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
form:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
header:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
nav:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
section:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
ul:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }
/* our ie CSS file */
article { zoom:1; }
aside { zoom:1; }
div { zoom:1; }
footer { zoom:1; }
form { zoom:1; }
header { zoom:1; }
nav { zoom:1; }
section { zoom:1; }
ul { zoom:1; }
Are there any disadvantages to this method? Could this end up clearfix'ing elements that you may not necessarily want clearfix'ed? Or are the rules such that this will account for any situation?
I think that's a bad idea. Are you really going to trust somebody who seemingly forgot to do this:
article, aside, div, footer, form, header, nav, section, ul { zoom:1; }
Clearing floats is not a complicated thing to get right.
It should be handled on a case-by-case basis, not sledge-hammered onto "every" element.
Doing that will come back to bite you in some way, I'm sure of it.
For one thing, I agree with #Guffa's answer.
An edge case reason against it concerns IE7: http://www.satzansatz.de/cssd/onhavinglayout.html
zoom: 1 is a common method to provide something known as hasLayout to elements. Applying hasLayout to an element fixes certain kinds of rendering problems, but it can also cause other problems. A quote from the linked document:
Don't give layout to all. Poison in that concentration,
having layout is not the cure, it
changes the rendering fundamentally.
I personally like to use the overflow: hidden method to contain floats. When that doesn't work, then I use clearfix.
You should use the version of clearfix from http://html5boilerplate.com/:
.clearfix:before,
.clearfix:after {
content: " "; /* 1 */
display: table; /* 2 */
}
.clearfix:after {
clear: both;
}
/*
* For IE 6/7 only
* Include this rule to trigger hasLayout and contain floats.
*/
.clearfix {
*zoom: 1;
}
Could this end up clearfix'ing
elements that you may not necessarily
want clearfix'ed?
Yes. I would not like every div element to be cleared.
Are there any disadvantages to this method?
One would be that it won't be enough in < IE8, since the 'after' element isn't that well supported. More about that at CSS tricks
In Cascade Framework, I'm using the following clearfix on all "block level" elements :
div:after {
content: "";
display: table;
}
div:after {
clear: both;
}
div {
*zoom: 1;
}
I never encountered any problems with this technique, except for minor quirks when using third party JS libraries... which can easily be fixed by "unclearfixing" the parent element.
Personally, I think clearfixed block level elements are lot more intuitive to work with and I don't really want to go back to working with floats the traditional way anymore. The only reason I see not to clearfix all block level elements by default, is because it's non-standard behavior and it might confuse the hell out of other people reading your code.
In cases where you actually want a parent of a floated element to collapse, an alternative strategy would be to use display: relative for the parent and display: absolute for the child. I haven't encountered any use case so far where this strategy isn't a suitable alternative for collapsed parents of floated elements.
I've been clearing all divs globally for the past couple of years in my projects, and it has been working great for me. In approximately 95% of the cases where I use divs, clearfix has worked like a charm when applied to a site globally. There are certainly cases where a potential issue will arise, and I end up undoing the clearfix for any problematic divs. The CSS declarations I use are:
div:after {
clear: both;
margin: 0;
padding: 0;
display: table;
font-size: 0;
line-height: 0;
content: ' ';
visibility: hidden;
overflow: hidden;
}
div {
*zoom: 1;
}

Overriding a css property

My Html is like this:
<a class="another addAnother">Add another</a>
I defined a style for the above using 'another' class like this in a external style sheet.
fieldset.associations a.another {
color: #693;
display: block;
margin: 7.5px 0px 15px;
}
I am trying to override the style of tag using 'addAnother' class, like this(wherever required):
fieldset.associations a.addAnother {
display: none;
}
But I am unable to override. Any help is appreciated.
Is there any rule that while overriding a style the selector should be same(I tried this, but no avail)??
Both properties have the same importance, because both selectors are equally specific. So if the second one appears first in the CSS, it needs to acquire more importance to override one that is lower down. You could override the first one by being more specific, like this:
fieldset.associations a.addAnother.another {
display: none;
}
or
#someID fieldset.associations a.addAnother {
display: none;
}
or
body fieldset.associations a.addAnother {
display: none;
}
Both your original declarations have a specificity of 0,0,2,2. If the second declaration is below the first, it should overrule it. If it doesn't, reorder your declarations or increase the specificity.
You could add the body tag in order to increase specificity:
body fieldset.associations a.addAnother {
display: none;
}
That will increase specificity by 0,0,0,1, the minimum amount of specificity you can add.
You can also make it specific to the .another class by chaining class declarations:
fieldset.associations a.another.addAnother {
display: none;
}
That will increase specificity by 0,0,1,0.
Here is an article explaining CSS specificity. Note that the article fails to mention that !important increase specificity by 1,0,0,0, making it near impossible to overrule.
fieldset.associations a.addAnother {
display: none !important;
}
It would ultimately depend on where those two styles are in your CSS, but you can't give one more importance like this:
fieldset.associations a.addAnother {
display: none !important;
}

Resources