2

I don't use Font Awesome but I do use icon fonts in the way described by Chris Coyier on CSS Tricks.

I wish to tweak his code to enable them to work in IE7. I realise generated content is not supported in IE7 so I had a look at how Font Awesome deals with the issue and it looks like they use this JS expression:

.ie7icon(@inner) {
  *zoom: ~"expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '@{inner}')";
}

My problem is that I just can;t get my head around what it is actually doing. I need to know this so I can tweak it and make it work for the way I am using icons.

ADDED:

I have this in my Sass file at the moment:

[data-icon]:before {
  @extend %icon-font
  content: attr(data-icon)
  speak: none
  -webkit-font-smoothing: antialiased
  1. How could I use the JS expression to add IE7 support on? Maybe a mixin would help here somehow?

  2. Can you explain the actual JS expression?

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
rctneil
  • 7,016
  • 10
  • 40
  • 83
  • There are 2 parts to the code you've pasted. First, it is a LESS mixin. Second, it is using some IE proprietary CSS to invoke JavaScript. Now which portion don't you understand? – cimmanon Mar 06 '13 at 21:41
  • Ah, I didn't realise it was a LESS mixin. I use Sass so I didn't pick up on the LESS syntax for mixins. I'll post some more stuff in my OP - Added – rctneil Mar 06 '13 at 21:46

4 Answers4

7

The Sass equivalent of that mixin would be like this:

@mixin ie7icon($inner) {
    *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '#{$inner}');
}

.foo {
    @include ie7icon(\f000);
}

Output:

.foo {
  *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\f000');
}

Zoom is a proprietary IE CSS property and tends to be the property of choice for triggering HasLayout (see: http://haslayout.net/haslayout) because it doesn't have any side effects for non-IE browsers.

The asterisk before the zoom property is your standard star hack. It exploits a bug in the CSS parser for IE<8 as a way to provide styles exclusively to those browsers (see: http://en.wikipedia.org/wiki/CSS_filter#Star_hack)

Expressions are primarily an IE only thing. They allow you to run arbitrary JavaScript via CSS (see: http://msdn.microsoft.com/en-us/library/ms537634(v=vs.85).aspx). This particular expression is setting the contents of whatever tag it is being applied to with the value of $inner, so it is really only intended to be used with an empty tag like so:

<p><i class="foo"></i> I have an icon!</p>
cimmanon
  • 67,211
  • 17
  • 165
  • 171
  • Perfect, Makes sense now. I'll try to build Sass mixin that should allow me to get icon fonts to work with IE fallbacks in standalone and with text situations - hopefully. – rctneil Mar 07 '13 at 09:27
0

First of all, you need to covert your img to font formats, fontsquirrel.com

and the css would like

@font-face { font-family: 'imgtoicon';
src:url('icons.eot');
src: url('icons.eot?#iefix') format('embedded-opentype'),
url('icons.ttf') format('truetype'),
url('icons.svg#icons') format('svg');
font-weight: normal;
font-style: normal;
}

create a class name for the font

.iconic {
display:inline-block;
font-family: 'imgtoicon';
font-weight: normal;
-webkit-font-smoothing: antialiased;
}

icon references example

.cat:before{content:'\e011';}
.dog:before{content:'\e022';}

in your css for IE7

  .iconic {
        font-family: 'imgtoicon'; 
        font-weight: normal;
        }

    .cat{ *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = '\e011'); }
olo
  • 5,225
  • 15
  • 52
  • 92
  • I understand how to use the fonts. It;s the actual javascript line I need explaining. I have this in my SS at the moment: [data-icon]:before { @extend %icon-font; content: attr(data-icon); speak: none; -webkit-font-smoothing: antialiased How could I use the JS expression to add IE7 support on? – rctneil Mar 06 '13 at 21:38
0

You could provide an alternative stylesheet using a conditional like so (credits to Paul Irish) <!--[if IE 7]><link rel="stylesheet" type="text/css" media="screen" href="css/ie7.css" />< ![endif]-->

Then in your ie7.css :

[class^="icon-"],
[class*=" icon-"] {
  font-family: your-icon-font;
 } 
.icon-custom { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = 'utf8-Custom'); }

I think *zoom helps giving a layout to the element and debug a IE+windows weird behavior, while this.innerHTML enables you to provide the utf8 value that corresponds to your icon.

You could also go like this (still Paul Irish and h5bp) and alternatively give a specific class to your html selector by pasting this line below your DOCTYPE :

<!--[if IE 7]>    <html class="no-js lt-ie9 lt-ie8"> <![endif]-->

Then you can go

.lt-ie8 [class^="icon-"],
.lt-ie8 [class*=" icon-"] {
  font-family: your-icon-font;
 } 
.lt-ie8 .icon-custom { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = 'utf8-Custom'); }

h5bp plans to drop support for IE6 IE7 and considers [complete removal for these conditionals][3] but I find them useful for this especially.

Hope this helps Please let me know how it goes

Charles

kartonnade
  • 81
  • 4
  • Thanks, I haven't got a problem in how to target stuff to IE7 or other Ie versions. I have code in for that already. My two issues now are: 1. Could I make the CSS I posted into a mixin with this IE JS expression a fallback? 2. How does the *zoom: part work? - I'm only asking this as I have never seen *zoom inside where the normal css properties go. Normally it is used as a selector? – rctneil Mar 06 '13 at 22:25
0

If your icon is not intented to change at runtime, you could use the following :

.icon-glass {
  *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf000;');
}

If your icon is intended to change at runtime, you could do something like this :

.icon-glass {
  *top:expression(0, this.innerHTML = '&#xf000;');
}

Unfortunately, this is extremely slow. While it is likely to work in IE6 with a significant reduction of your performance, IE7 is likely to crash if you have too many icons on your page. So I wouldn't recommend this second technique unless you use only very few icons and you can afford the performance reduction.

John Slegers
  • 45,213
  • 22
  • 199
  • 169