Skip to content

Instantly share code, notes, and snippets.

@ffoodd
Created February 26, 2014 16:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ffoodd/9233227 to your computer and use it in GitHub Desktop.
Save ffoodd/9233227 to your computer and use it in GitHub Desktop.
A Pen by ffoodd.
<ul class="boxes">
<li class="box box-alpha">
<header class="box-header">Cross-browser : the circle works from Opera 15, Chrome 23, Firefox 17.</header>
<footer class="box-footer">Firefox between 4 and 17 does clip the circle, but does not vertically center it…</footer>
</li>
<li class="box box-beta">
<header class="box-header">The square fallback works from Opera 10.6, Chrome 14, IE9 — IE8 not centered, Safari 1.</header>
<footer class="box-footer"></footer>
</li>
<li class="box box-gamma">
<header class="box-header"></header>
<footer class="box-footer">IE7 gracefully degrades with no generated content.</footer>
</li>
<li class="box box-delta">
<header class="box-header"></header>
<footer class="box-footer">To do : check if Firefox could clip without SVG (flag ?); test how to clip SVG with relatives dimensions and remove this max-width: 800px.</footer>
</li>
</ul>
<div class="text">
<h2>What you should know</h2>
<ol>
<li><strong>Chrome’s good. That’s it.</strong></li>
<li>Firefox’ not bad — but read this :
<ul>
<li>FF can’t clip a basic shape like <<code>>clip-path: circle( 50%, 50%, 5em );</code>.<b>That’s bad.</b></li>
<li>But it can clip any <abbr title="HyperText Markup Language">HTML</abbr> element when referencing a <abbr title="Scalable Vector Graphics">SVG</abbr> <code>clipPath</code> element (watch my <abbr title="Document Object Model">DOM</abbr>). That’s pretty good.</li>
<li>Bad thing is : you have to specify dimensions. Percentage won’t work and you shall cry. Relative units like <code>em</code> will work, but behind FF 17, it becomes weird. <b>That’s a bad thing because you won’t be able to use it on a fluid layout.</b></li>
<li>Prior to version 4, FF will fallback to the ol’ good <abbr title="Cascadinc StyleSheet">CSS</abbr> 2.1 <code>clip</code> property. Which is good, but is restricted to rectangle shapes (as you may know).</li>
</ul>
</li>
<li><b>Opera 15 and up is just good.</b></li>
<li>Opera from 10.6 to 15 fallback to <abbr title="Cascadinc StyleSheet">CSS</abbr> 2.1 <code>clip</code> property. <b>Pretty good.</b></li>
<li><b>Let’s talk about IE.</b> Please sit up.
<ul>
<li>That just doesn’t work on IE 11 and lower. Surprised ? You should be ! IE9 to 11 can clip when referencing a <code>clipPath</code> element (just like Firefox, remember ?) but it can only clip inside a <abbr title="Scalable Vector Graphics">SVG</abbr> element. That means you could use <code>ForeignObject</code> to wrap your <abbr title="HyperText Markup Language">HTML</abbr> inside any <abbr title="Scalable Vector Graphics">SVG</abbr> and it should work ! More test to come…</li>
<li>IE8 will always fallback to <abbr title="Cascadinc StyleSheet">CSS</abbr> 2.1 <code>clip</code> property, but it’s very good ! In our test case, that means it only misses the circle thing — but that’s obvious and logical since it can’t draw a border-radius anyway. <b>Squares everywhere, yay !</b></li>
<li>IE7 just doesn’t do anything with pseudo-elements so it just do a good job.</li>
</ul>
</li>
</ol>
<h2>What you could do</h2>
<p>It’s pretty good when you can specify width and height.</p>
<p>But it maybe doable with other ressources :</p>
<ul>
<li><a href="http://www.w3.org/TR/css-masking-1/#masking"><code>mask-image</code></a> : since it’s now part of the specs, you may try. You can position it just like a background, and the Apple’s version is from 2008.</li>
<li>Pure SVG. Yeah, I know.</li>
<li>Javascript may help for each of these tricks…</li>
</ul>
</div>
<svg width="800" height="390">
<defs>
<clipPath id="circle">
<circle cx="50%" cy="50%" r="80" />
</clipPath>
</defs>
</svg>
*,
:after,
:before {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
section,
header,
footer { display: block; }
/* Références :
* http://codepen.io/iamvdo/pen/EIjLa
* http://codepen.io/iamvdo/pen/hasAm
* http://www.24joursdeweb.fr/2013/les-masques-css/
* http://www.html5rocks.com/en/tutorials/masking/adobe/
* http://docs.webplatform.org/wiki/css/properties/clip-path
* https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Clipping_and_masking
* http://www.w3.org/TR/SVG/masking.html#ClippingPaths
* https://www.webkit.org/blog/181/css-masks/
* https://developer.apple.com/library/safari/documentation/AppleApplications/Reference/SafariCSSRef/Articles/StandardCSSProperties.html#//apple_ref/doc/uid/TP30001266-VisualEffects
*/
/**
* 1. Position is everything — and very useful to place the ::before pseudo-element :)
* 2. Giving background.
* 3. Used to position SVG shape used as a fallback for clip-path: <basic-shape>.
* 4. Useful for IE8.
*/
.boxes {
list-style: none;
padding: 0;
margin: 2em auto 0;
overflow: hidden;
position: relative; /* 1 */
background-image : url(http://lorempixel.com/output/nature-q-c-800-400-10.jpg); /* 2 */
max-width: 800px; /* 3 */
z-index: 1; /* 4 */
}
/**
* @note : The trick is to create a pseudo-element with the exact same dimensions and background than the .boxes, and stack it above. Then we’ll clip it in order to make it a simple circle, creating a « see-hrough » like effect.
* 1. Creating ::before with the same dimensions as its relative parent (.boxes)
* 2. Giving the same background.
* 3. Using a simple rectangle clip for simplest browsers (a.k.a. IE).
* 4. Clipping the pseudo-element to create the centered circle.
* 5. SVG shape is more cross-browser. Circle is centered with <cx> and <cy> attributes : 400 = 800(.boxes’width)/2 and 12em = 6em(.box’s height + margin-bottom)*2.
*/
.boxes:before {
content: '';
position: absolute; /* 1 */
z-index: 2; /* 1 */
bottom: 0; /* 1 */
right: 0; /* 1 */
left: 0; /* 1 */
top: 0; /* 1 */
background-image: inherit; /* 2 */
clip: rect( 7em, 30em, 17em, 20em ); /* 3 */
-webkit-clip-path: circle( 50%, 50%, 5em ); /* 4 */
clip-path: url(#circle); /* 5 */
}
/**
* 1. Width and height are equal t get a square and 5em for proportions with other elements;
* 2. Making a circle;
* 3. Centering the circle.
*/
.boxes:after {
content: '';
position: absolute;
background: #34495e;
height: 5em; /* 1 */
width: 5em; /* 1 */
border: .5em solid #2f3e51;
border-radius: 50%; /* 2 */
z-index: 3;
left: 44%; /* 3 */
top: 40%; /* 3 */
left: calc( 50% - 2.5em ); /* 3 */
top: calc( 50% - 2.5em ); /* 3 */
}
/**
* 1. Feel free to move to inline-block or whatever
* 2. Useful for IE8.
*/
.box {
color: #fff;
float: left; /* 1 */
margin: 1em;
position: relative; /* 2 */
z-index: -1; /* 2 */
width: 45%; /* 2 */
width: calc( 50% - 2em );
}
.box-header,
.box-footer {
min-height: 5em;
padding: 1em;
}
.box-alpha .box-header { background: #1abc9c; }
.box-alpha .box-footer { background: #148f77; }
.box-beta .box-header { background: #2ecc71; }
.box-beta .box-footer { background: #25a25a; }
.box-gamma .box-header { background: #217dbb; }
.box-gamma .box-footer { background: #3498db; }
.box-delta .box-header { background: #804399; }
.box-delta .box-footer { background: #9b59b6; }
/* Legend */
.text {
margin: 2em auto;
max-width: 800px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment