23 July 2015

CSS3 Drop Menu Fade In

The Basics

I have an HTML menu:

UL - top menu
  LI - first item
    A
    UL - sub menu
      LI - first sub item
        A 

and some basic CSS:

#menu li ul {
  display: none;
}

#menu li:hover > ul {
  display: block;
}

So when we hover over the first item, the sub-menu appears.  Simples.


Fade-in using transition

I wanted to make the menu fade in using the lovely new css transition attribute, and I thought by adding an opacity attribute it would, appear then fade in.

#menu li ul {
     display: none;
     opacity: 0;
  transition: opacity .25s;
}

#menu li:hover > ul {
  display: block;
  opacity: 1;
}

So in theory when we hover the display is changed to block, and the opacity will fade the menu in a .25 seconds.

It doesn't work however, using the display attribute breaks the transition, no idea why but it does.

CSS animate to the rescue

We can make it work using the animate property and a keyframes block.

@keyframes fadein {
    0% { opacity: 0; }
  100% { opacity: 1; }
}

#menu li ul {
    display: none;
    opacity: 0;
  animation: fadein .25s;
}

#menu li:hover > ul {
  display: block;
  opacity: 1;
}

There is one drawback with this method however,  we can't do a fadeout, because the display:hidden happens at the start of the animation, not a the end, which is what we want to happen in a fadeout. 

Thanks to Hermann Schwarz for the idea.

20 July 2015

Kerberos SSO for Google Chrome on Mac OS X

Normally Macs are better at doing this stuff, however.

To get Kerberos SSO (SPNEGO) authentication working on chrome you normally have to use command line parameters with the Chrome binary; which while certainly possible on macs can be done by creating a startup script.

A far simpler way is to issue the following commands from the command line:

$ defaults write com.google.Chrome AuthServerWhitelist “*.example.com”
$ defaults write com.google.Chrome AuthNegotiateDelegateWhitelist “*.example.com

Thanks to Jeff Geerling for this one.

31 July 2014

Internet Explorer Woes Still!

Microsoft WHY WHY WHY!


I have gone back in time.   I am fighting with IE AGAIN.

Internet Explorer Version 11.  Its the latest and greatest, and for the most part standards compliant browser.  Well done.

SVG


Today I have been using SVG graphics.  SVG's are awesome, they are the future, they should have been around 10 years ago, except for IE's failure to support them.  Finally now all modern browsers support them (and have done for a while), at least in their basic incarnation.

<img src="mywonderfulgraphic.svg" />

Ok, I still have to have image fallback for IE8 and below, and older androids.

<img onerror="this.onerror=null;this.src='fallback.png'" src="newshiny.svg" />

There are other ways to do this I agree, but this way to me seems the simplest, and most efficient.

I have also added a simple server optimisation.  Doing some "evil" browser sniffing, if the browser is MSIE 8 or below, I just serve the PNG, and don't bother with SVG. 

<img src="fallback.png" />

So far so good.

Until we come to IE11


IE has an SVG scaling bug, which means the SVG image wont scale correctly: Given a percentage width it wont scale the height appropriately resulting in stretched images. PNG's scale just fine.

I investigated trying to fiddle it, using CSS, but without jumping through a lot of hoops, it becomes just awkward.  So my next thought was, it's ok, I can just deliver the PNG instead, I'll just use the browser sniffing to check the IE version.

The IE team have decided to the remove "MSIE" from the User Agent String.  I now dont know which browser is talking to the server, because IE pretends to be all of them.

(Update) Actually they have changed the User Agent String, and after a bit of fidding the IE browser version can be detected for any IE version using the following regex:

\b(?:MSIE\s|Trident\/[0-9.]+;\srv:)([0-9.]+)

It can used like this from PHP: 

$version = [false,false];
$isIE = preg_match("/\b(?:MSIE\s|Trident\/[0-9.]+;\srv:)([0-9.]+)/",$_SERVER['HTTP_USER_AGENT'],$version);
return $isIE? $version[1]: false; 

Aha!, they say "You should be using feature detection instead of User Agent sniffing".

Well thats all very well if your features worked like they should, then I wouldn't have to deliver browser specific content in the first place.  Which, as a matter of fact, is why browser sniffing was needed in the first place!

What about conditional comments you say. 

Nope they don't work for IE11 either. The IE team decided to remove them from IE 11. 

Rock meet Hard Place.


(Update) There are various sites on the interwebs which give ideas about getting round the SVG issue eg. larrybotha on github

If I make sure the SVG has the viewBox attribute set, I can set the height in CSS to 100%

To target IE 10+ browsers, use the following css media query:

@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
    /* IE10+ specific styles */
    .selector img[src$=".svg"] { height: 100%; }
}

I got that hack from here: limecanvas.com


(Update) Safari also suffers from SVG scaling bugs.  I was trying to do hovering on scaled images, using image replacement, and every time the image got swapped, it messed up the image aspect or scaling.