Best html5 questions in January 2012

How to make a circular Div in Chrome?

9 votes

I have this div which acts a lens in zooming of the image. But the problem is that I want it circular I am using this for that:

-webkit-border-radius:999px;-moz-border-radius:999px;border-radius:999px;

problem is that it makes the div circular but do not hide the image corners which are not part of the circle and hence show a rectangle.

Url is: http://chokate.maninactionscript.com/chokates/ Click on the desert picture and then see the bigger image on the right for zoom effect. If you give the lens div border 1px solid red then you can see that the div is actually circular but it doesn't hide the useless part of images.

Any ideas?

If you have an image inside an element that has border-radius set, and you want to hide the "corners" of the image, you need to set border-radius on the image to match.

But in your case that won't work because your image is much larger than your containing element. Better is to use a <div> as the lens and set background-image to match your image.

Demo: http://jsfiddle.net/ThinkingStiff/wQyLJ/

HTML:

<div id="image-frame">
<img id="image" src="http://thinkingstiff.com/images/matt.jpg" />
<div id="lens" ></div>
<div>

CSS:

#image-frame {
    position: relative;
}

#lens {
    background-repeat: no-repeat;
    border-radius: 150px;
    height: 150px;
    position: absolute;
    width: 150px;
}

Script:

document.getElementById( 'image-frame' ).addEventListener( 'mousemove', function ( event ) {

    var lens = document.getElementById( 'lens' ),
        image = document.getElementById( 'image' ),
        radius = lens.clientWidth / 2,
        imageTop = this.documentOffsetTop,
        imageLeft = this.documentOffsetLeft,
        zoom = 4,
        lensX = ( event.pageX - radius - imageLeft ) + 'px',
        lensY = ( event.pageY - radius - imageTop ) + 'px',
        zoomWidth = ( image.clientWidth * zoom ) + 'px',
        zoomHeight = ( image.clientHeight * zoom ) + 'px',
        zoomX = -( ( ( event.pageX - imageLeft ) * zoom ) - radius ) + 'px',
        zoomY = -( ( ( event.pageY - imageTop ) * zoom ) - radius ) + 'px';

    if( event.pageX > imageLeft + image.clientWidth 
        || event.pageX < imageLeft
        || event.pageY > imageTop + image.clientHeight 
        || event.pageY < imageTop  ) {

        lens.style.display = 'none';

    } else {

        lens.style.left = lensX;
        lens.style.top = lensY;
        lens.style.backgroundImage = 'url(' + image.src + ')';
        lens.style.backgroundSize = zoomWidth + ' ' + zoomHeight;
        lens.style.backgroundPosition = zoomX + ' ' + zoomY;
        lens.style.display = 'block';

    };

}, false );

window.Object.defineProperty( Element.prototype, 'documentOffsetTop', {
    get: function () { 
        return this.offsetTop + ( this.offsetParent ? this.offsetParent.documentOffsetTop : 0 );
    }
} );

window.Object.defineProperty( Element.prototype, 'documentOffsetLeft', {
    get: function () { 
        return this.offsetLeft + ( this.offsetParent ? this.offsetParent.documentOffsetLeft : 0 );
    }
} );

Output:

enter image description here

Does the h1 need to be the first semantic element in a header tag?

9 votes

I am using a Chrome outliner extension to check the semantics of my page. It seems to be a problem to have any structural element before the h1 in the document main header tag. I was thinking the order does not matter, but apparently it does:

+Document Body
  +Header
    +nav
      +h1 Main Navigation
    +h1 MyPage
  -Section
  -Footer

Does outline like this:

Untitled Body
  Main Navigation
  MyPage
  etc...

But when the h1 is the first element in my header:

+Document Body
  +Header
    +h1 MyPage
    +nav
      +h1 Main Navigation
  -Section
  -Footer

it does outline like this:

MyPage
  Main Navigation
  etc...

Why is that? Is the outliner buggy, or did I understand something wrong in HTML5 semantics? The W3C Specification does not seem to mention it: http://dev.w3.org/html5/spec/Overview.html#the-header-element

After revisiting the specs, I agree that the h1 does not have to be the first element. I suspect the issue is with the chrome extension you are using.

I ran the following two scenarios through this HTML outlining tool and received the same results (My Navigation appears under My Header):

With h1 second element under header:

<body>
<header>
<h1>My Header</h1>
<nav><h1>My Navigation</h1></nav>
</header>
<section><h1>My Section</h1></section>
<footer></footer>
</body>

With H1 first element under header:

<body>
<header>
<nav><h1>My Navigation</h1></nav>
<h1>My Header</h1>
</header>
<section><h1>My Section</h1></section>
<footer></footer>
</body>