Conditional CSS for Webkit-based browsers

Edit: Please keep in mind that the below code works also on MS Edge. You can re-write MS Edge specific CSS using @supports (-ms-accelerator:true) {} (read more on the comment section).

On a recent project I had to find a way to apply CSS only on webkit-based browsers. We are all, more or less, very familiar with IE’s conditional comments, but what about other browsers? For webkit-based browsers, the solution is fairly simple. We only need to add our CSS statements into a “special” media query, that only webkit-based browsers will parse :

@media screen and (-webkit-min-device-pixel-ratio:0) {  
/* CSS Statements that only apply on webkit-based browsers (Chrome, Safari, etc.) */  
  body { background:#ccc; }  
}Check out this Pen!

Nice ‘n easy 😉

Wrap any amount of elements with jQuery

Update : Get the nwrapper plugin from the official jQuery plugins site.

jQuery provides a large variety of functions for element manipulation, that in most cases will manipulate the selected elements in no time. A very useful function for every day manipulation is the .wrap() function that we can use to wrap an HTML structure around each jQuery element. But what happens when we want to wrap an HTML structure on every n’th number of the selected elements? Unfortunately, jQuery doesn’t provide any options to the warp function in order to to do something similar.

After a bit of search I came across this solution for the jQuery forum, and created the below jQuery plug in.

(function($) {  
  
$.fn.nwrapper = function(options){  
  
    var defaults = {  
        wrapEvery      : 1,  
        defaultClasses : true,  
        extraClasses   : false,  
        htmlStructure  : 'div'  
    };  
  
    settings = $.extend({}, defaults, options);  
  
    var elements    = $(this).children();  
    var elementsLen = elements.length;  
  
    for ( var i = 0, numb = 1; i < elementsLen; i += settings.wrapEvery, numb++ ){  
  
        // Default Classes Array  
        var classes = [];  
        if ( settings.defaultClasses ) {  
  
            classes[0] = 'wrapper';  
            classes[1] = 'wrapper-' + numb;  
  
            if (numb==1) {  
                classes[2] = 'first';  
            }  
  
            if (numb==Math.ceil(elementsLen/settings.wrapEvery)) {  
                classes[2] = 'last';  
            }  
  
        }  
  
        // Merge Default class with Extra Class  
        if ( settings.extraClasses ) {  
            $.merge( classes, settings.extraClasses );  
        }  
  
        // If you find any classes crete the class string  
        if ( classes.length > 0 ) {  
            htmlClassesString = 'class="' + classes.join(" ") + '"';  
        } else {  
            htmlClassesString = '';  
        }  
  
        elements.filter(':eq(' + i + '), :lt(' + (i + settings.wrapEvery) + '):gt(' + i + ')').wrapAll('<' + settings.htmlStructure + ' ' + htmlClassesString + ' />');  
  
    }  
  
    return $(this);  
};  
  
})(jQuery);

$('#container').nwrapper({  
    wrapEvery      : 2,  
    //defaultClasses : true,  
    //extraClasses   : ['class1', 'class2'],  
    //htmlStructure  : 'span'  
});Check out this Pen!

To use it, select the parent element of the elements you want to wrap, choose how often you’ll apply the wrap (wrapEvery attribute – default is 1), choose if you need any default classes or even provide your own extra classes (extraClasses), and finally provide the HTML structured element you’ll use for a wrapper (the default is div, but you can also use a span).

Now you can wrap every n’th of your elements.

A really simple HTML5 template

Lately I’m using more and more HTML5 elements on my markup. It’s the right thing to do after all, especially on smaller, flexible projects. But as a typical developer I’m too lazy to type everything from scratch, that’s why I’m using more and more the HTML5 Boilerplate from Paul Irish. It’s great but I catch myself deleting many files and lines of code every time, in order to make Boilerplate fulfil my requirements. After all, in most cases I don’t really need things like YUI Profiler, Google Analytics, favicons/iPhone icons and many others for a quick prototype. What I really need, is a very simple template with less features, scripts, and tools! Below you can see/use my HTML5 Boilerplate

Markup :

<!DOCTYPE html>  
<html lang="en">  
<head>  
<meta charset="utf-8" />  
<title>Really simple HTML5 template</title>  
  
<link rel="stylesheet" type="text/css" href="style.css" />  
  
<!--[if lt IE 9]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->  
</head>  
<body>  
    <h1>HTML5 Template</h1>  
</body>  
</html>Check out this Pen!

A single stylesheet and just one script, will do the work just fine. (The html5shiv helps older IE browsers, to style the new HTML5 elements).

CSS :

/*! normalize.css v2.1.2 | MIT License | git.io/normalize */

/* ==========================================================================
   HTML5 display definitions
   ========================================================================== */

/**
 * Correct `block` display not defined in IE 8/9.
 */

article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
nav,
section,
summary {
    display: block;
}

/**
 * Correct `inline-block` display not defined in IE 8/9.
 */

audio,
canvas,
video {
    display: inline-block;
}

/**
 * Prevent modern browsers from displaying `audio` without controls.
 * Remove excess height in iOS 5 devices.
 */

audio:not([controls]) {
    display: none;
    height: 0;
}

/**
 * Address styling not present in IE 8/9.
 */

[hidden] {
    display: none;
}

/* ==========================================================================
   Base
   ========================================================================== */

/**
 * 1. Set default font family to sans-serif.
 * 2. Prevent iOS text size adjust after orientation change, without disabling
 *    user zoom.
 */

html {
    font-family: sans-serif; /* 1 */
    -ms-text-size-adjust: 100%; /* 2 */
    -webkit-text-size-adjust: 100%; /* 2 */
}

/**
 * Remove default margin.
 */

body {
    margin: 0;
}

/* ==========================================================================
   Links
   ========================================================================== */

/**
 * Address `outline` inconsistency between Chrome and other browsers.
 */

a:focus {
    outline: thin dotted;
}

/**
 * Improve readability when focused and also mouse hovered in all browsers.
 */

a:active,
a:hover {
    outline: 0;
}

/* ==========================================================================
   Typography
   ========================================================================== */

/**
 * Address variable `h1` font-size and margin within `section` and `article`
 * contexts in Firefox 4+, Safari 5, and Chrome.
 */

h1 {
    font-size: 2em;
    margin: 0.67em 0;
}

/**
 * Address styling not present in IE 8/9, Safari 5, and Chrome.
 */

abbr[title] {
    border-bottom: 1px dotted;
}

/**
 * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
 */

b,
strong {
    font-weight: bold;
}

/**
 * Address styling not present in Safari 5 and Chrome.
 */

dfn {
    font-style: italic;
}

/**
 * Address differences between Firefox and other browsers.
 */

hr {
    -moz-box-sizing: content-box;
    box-sizing: content-box;
    height: 0;
}

/**
 * Address styling not present in IE 8/9.
 */

mark {
    background: #ff0;
    color: #000;
}

/**
 * Correct font family set oddly in Safari 5 and Chrome.
 */

code,
kbd,
pre,
samp {
    font-family: monospace, serif;
    font-size: 1em;
}

/**
 * Improve readability of pre-formatted text in all browsers.
 */

pre {
    white-space: pre-wrap;
}

/**
 * Set consistent quote types.
 */

q {
    quotes: "\201C" "\201D" "\2018" "\2019";
}

/**
 * Address inconsistent and variable font size in all browsers.
 */

small {
    font-size: 80%;
}

/**
 * Prevent `sub` and `sup` affecting `line-height` in all browsers.
 */

sub,
sup {
    font-size: 75%;
    line-height: 0;
    position: relative;
    vertical-align: baseline;
}

sup {
    top: -0.5em;
}

sub {
    bottom: -0.25em;
}

/* ==========================================================================
   Embedded content
   ========================================================================== */

/**
 * Remove border when inside `a` element in IE 8/9.
 */

img {
    border: 0;
}

/**
 * Correct overflow displayed oddly in IE 9.
 */

svg:not(:root) {
    overflow: hidden;
}

/* ==========================================================================
   Figures
   ========================================================================== */

/**
 * Address margin not present in IE 8/9 and Safari 5.
 */

figure {
    margin: 0;
}

/* ==========================================================================
   Forms
   ========================================================================== */

/**
 * Define consistent border, margin, and padding.
 */

fieldset {
    border: 1px solid #c0c0c0;
    margin: 0 2px;
    padding: 0.35em 0.625em 0.75em;
}

/**
 * 1. Correct `color` not being inherited in IE 8/9.
 * 2. Remove padding so people aren't caught out if they zero out fieldsets.
 */

legend {
    border: 0; /* 1 */
    padding: 0; /* 2 */
}

/**
 * 1. Correct font family not being inherited in all browsers.
 * 2. Correct font size not being inherited in all browsers.
 * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.
 */

button,
input,
select,
textarea {
    font-family: inherit; /* 1 */
    font-size: 100%; /* 2 */
    margin: 0; /* 3 */
}

/**
 * Address Firefox 4+ setting `line-height` on `input` using `!important` in
 * the UA stylesheet.
 */

button,
input {
    line-height: normal;
}

/**
 * Address inconsistent `text-transform` inheritance for `button` and `select`.
 * All other form control elements do not inherit `text-transform` values.
 * Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+.
 * Correct `select` style inheritance in Firefox 4+ and Opera.
 */

button,
select {
    text-transform: none;
}

/**
 * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
 *    and `video` controls.
 * 2. Correct inability to style clickable `input` types in iOS.
 * 3. Improve usability and consistency of cursor style between image-type
 *    `input` and others.
 */

button,
html input[type="button"], /* 1 */
input[type="reset"],
input[type="submit"] {
    -webkit-appearance: button; /* 2 */
    cursor: pointer; /* 3 */
}

/**
 * Re-set default cursor for disabled elements.
 */

button[disabled],
html input[disabled] {
    cursor: default;
}

/**
 * 1. Address box sizing set to `content-box` in IE 8/9.
 * 2. Remove excess padding in IE 8/9.
 */

input[type="checkbox"],
input[type="radio"] {
    box-sizing: border-box; /* 1 */
    padding: 0; /* 2 */
}

/**
 * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
 * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
 *    (include `-moz` to future-proof).
 */

input[type="search"] {
    -webkit-appearance: textfield; /* 1 */
    -moz-box-sizing: content-box;
    -webkit-box-sizing: content-box; /* 2 */
    box-sizing: content-box;
}

/**
 * Remove inner padding and search cancel button in Safari 5 and Chrome
 * on OS X.
 */

input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
    -webkit-appearance: none;
}

/**
 * Remove inner padding and border in Firefox 4+.
 */

button::-moz-focus-inner,
input::-moz-focus-inner {
    border: 0;
    padding: 0;
}

/**
 * 1. Remove default vertical scrollbar in IE 8/9.
 * 2. Improve readability and alignment in all browsers.
 */

textarea {
    overflow: auto; /* 1 */
    vertical-align: top; /* 2 */
}

/* ==========================================================================
   Tables
   ========================================================================== */

/**
 * Remove most spacing between table cells.
 */

table {
    border-collapse: collapse;
    border-spacing: 0;
}Check out this Pen!

For CSS, I’m just using the normalize.css.

That’s it, our super minimal HTML5 template is ready for use! Just copy, paste and enjoy…

How to create a bookmarklet

A bookmarklet is a small Javascript program stored into a url. A user can bookmark the specific url, and execute the Javascript code on any page. The good news is that it’s not so hard to create one. A very simple example is the bookmarklet below:

<a href="javascript:alert("Phrappe.com rocks!")>A vary basic bookmarklet!</a>Check out this Pen!

As you can see, you instruct the browser to run a javascript url. You can drag & drop the link to your bookmarks, and execute the bookmarklet on any page! That’s the power of bookmarklets. Go on try it 😉

Unfortunately, we have some browser limitations on url size (usually 2000 characters), that makes it impossible to write serious js code straight into a url. To tackle this limitation we can use our bookmarklet as a loader to an external js file using the below code :

javascript:(function() {  
  var s=document.createElement("script");  
  s.src="http://phrappe.com/script.js";  
  document.body.appendChild(s);  
})();Check out this Pen!

We start with the standard js url notation, and then we create a self executing anonymous function. Into that function, we just create a new script element, pass a source attribute to it and append it to our current document. Then we can finally start writing some serious javascript code to our external script, without any of the usual bookmarklet limitations! The script itself can again be a self executing anonymous function (because we don’t want to mess with document’s js code and variables).

(function() {  
//code  
})();Check out this Pen!

Keep in mind that bookmarklets have access to all the content and code of the document within which we ran them. So if you don’t trust a boorkmarklet code, don’t use it on sensitive pages, because the bookmarklet can access sensitive and personal data such as cookies, variables or elements! Be extra careful when you use them and if you don’t trust the source/author don’t use them at all!

Below you can see a very simple bookmarklet I created to transform sites to a more console-like layout (black background, monospace green fonts, etc.).

Console it! (drag’n drop it to your bookmarks and try it at google.com 😉 ). You can see the code below or simply download it.

(function() { 

var body      = document.body,
	links     = document.getElementsByTagName('a');

body.setAttribute("style", "background-color:#000; color:#fff; font-family: \"Courier New\", Courier, monospace;");

for ( i in links ){
	links[i].setAttribute("style", "color:#347c17; font-family: \"Courier New\", Courier, monospace;");	
}

})();Check out this Pen!

Finally, a very useful bookmarklet I use all the time is jQuerify. It loads jQuery on any page. Then I can just do the cool stuff through console 😉

A really simple “equal heights” method for jQuery!

Nothing special, a really basic “equal heights” method written in jQuery.

$.fn.equalHeights = function() {  
    var maxHeight = 0;  
    $(this).each(function(index){  
        var height = $(this).height();  
  
        if (maxHeight < height) {  
            maxHeight = height  
        }  
   });  
   $(this).height(maxHeight);  
}

$("ul li").equalHeights();Check out this Pen!

Then you just need to apply the method on the element you want using $("ul li").equalHeights();.

CSS3 PIE : My new favorite IE enhancement

IE sucks big time, period! Even version 8 doesn’t support many useful CSS rules such as border radius and box shadow, both standard things for 2010. For those who already use all the nice CSS3 features that IE doesn’t support, try CSS3 PIE. The installation is easy (you only need to upload one file and that’s it) and after that, you’ll finally force IE to support many CSS3 features such as border-radius, box-shadow, border-image, multiple background images, linear backgrounds, rgba as well as some other features. Give it a try, it’s not bad at all (plus you keep all the behavior inside your CSS file, you don’t need to write/code/attach any Javascript code).

How to attach a custom apple iPhone/iPad icon to your website

If you already have an iPhone, iPad or any other iOS-based device, you have definitely seen the strange bookmarking Safari option “Add to home screen“. The specific option creates an application like bookmark to your iOS screen for quicker browsing.

Clever idea and it works great, but if the site you’ve just bookmarked doesn’t have a custom iOS icon, iOS adds a poor quality screenshot of the site for icon! But don’t worry the solutions to this problem are super easy.

Just create a 57 x 57 pixels PNG (for iPhone, or 114 x 114 for iPhone 4 or 72 x 72 for iPad) with your custom icon, name it apple-touch-icon.png and put it into the root directory of your site. That’s it! You don’t even have to worry about the rounded corners of the PNG image, since iOS is clever enough to add them for you! The final URL of your icon must be something like http://www.yoursite.com/apple-touch-icon.png. If you want to supprt all iOS devices a 114 x 114 will do the job, although iPhone classic and iPad will scale it down.

Now if you don’t have access to the root directory of the site (no way!), or simply you don’t want to mess things up there, you have an alternative. Just put it wherever you like (maybe into the images/icons folder), and point to it with the below markup:

<link rel="apple-touch-icon" href="/images/mycustomiphoneicon.png" />Check out this Pen!

 

The above code must be placed in the head section of our document and it must have a link relation (rel) with the value “apple-touch-icon“, that’s the only two requirements. As you noticed we can name our PNG file as we want. Finally, yes we can use absolute paths as well, or even load our icon from other domains!

<link rel="apple-touch-icon" href="http://www.othersite.com/images/mycustomiphoneicon.png" />Check out this Pen!

 

Beginning HTML ordered lists with numbers other than 1

Yes it is possible and easy! You only have to use the (rare/unknown?) start attribute at your ordered list element (see example below).

<ol start="4">  
    <li>list item 1</li>  
    <li>list item 2</li>  
    <li>list item 3</li>  
    <li>list item 4</li>  
    <li>list item 5</li>  
</ol> Check out this Pen!

And guess what? It works with negative numbers as well!

Convert a jQuery object to raw DOM object

There are two, easy ways to achieve this. The first one is simply by using the array [] notation directly on the jQuery object :

var myDiv = $('div')[0]; // myDiv is a raw DOM object  
myDiv.innerHTML = 'New Hello World text!'; // and we can do all the normal things with itCheck out this Pen!

The second one is by using the get method, the “core get” method, not the “AJAX get” one. The get method returns an array with the selected elements, and we can optionally pass an index number parameter to return the element we need.

var myDiv= $('div').get(0); // myDiv is again a raw DOM object  
myDiv.innerHTML = 'New Hello World text!'; // and we can do all the normal things with itCheck out this Pen!

Super easy, isn’t it?