Jekyll2020-05-20T08:13:34+00:00http://blog.javiercejudo.com/feed.xmlTech notes by Javier CejudoFull-stack developerYour ultimate frontend email validation2014-08-03T00:00:00+00:002014-08-03T00:00:00+00:00http://blog.javiercejudo.com/ultimate-frontend-email-validation<p>It is common practice to validate emails using complex regular expressions,
but chances are they are all technically wrong. Frontend validation in general
is great for letting users know of issues early, but it cannot come at the cost
of rejecting valid input:</p>
<p>Well, here is my attempt:</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="dl">'</span><span class="s1">use strict</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">api</span> <span class="o">=</span> <span class="p">{};</span>
<span class="c1">// element needs to have type="email"</span>
<span class="nx">api</span><span class="p">.</span><span class="nx">isValidEmail</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">element</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// leverage the Constraint Validation API when it is available</span>
<span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">element</span><span class="p">.</span><span class="nx">checkValidity</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">function</span><span class="dl">'</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">element</span><span class="p">.</span><span class="nx">checkValidity</span><span class="p">();</span>
<span class="p">}</span>
<span class="c1">// otherwise, this is about the only regex</span>
<span class="c1">// that doesn't reject any valid email addresses</span>
<span class="k">return</span> <span class="p">(</span><span class="sr">/@/</span><span class="p">).</span><span class="nx">test</span><span class="p">(</span><span class="nx">element</span><span class="p">.</span><span class="nx">value</span><span class="p">);</span>
<span class="p">};</span>
<span class="p">}());</span></code></pre></figure>
<p>Please note that, at the time of writing, the Constraint Validation API has a
willful violation of RFC 5322 with the following explanation:</p>
<blockquote>
<p>[RFC 5322] defines a syntax for e-mail addresses that is simultaneously
too strict (before the “@” character), too vague (after the “@” character),
and too lax (allowing comments, whitespace characters, and quoted strings
in manners unfamiliar to most users) to be of practical use here.</p>
</blockquote>
<p>Source: <a href="http://www.w3.org/TR/html5/forms.html#valid-e-mail-address">W3C E-mail state</a></p>
<p>That link also provides a regular <code class="language-plaintext highlighter-rouge">expression</code> that implements the
current specification in case you really want to go down that road:</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"> <span class="o">/^</span><span class="p">[</span><span class="nx">a</span><span class="o">-</span><span class="nx">zA</span><span class="o">-</span><span class="nx">Z0</span><span class="o">-</span><span class="mi">9</span><span class="p">.</span><span class="o">!</span><span class="err">#</span><span class="nx">$</span><span class="o">%&</span><span class="dl">'</span><span class="s1">*+</span><span class="se">\</span><span class="s1">/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:</span><span class="se">\</span><span class="s1">.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/</span></code></pre></figure>It is common practice to validate emails using complex regular expressions, but chances are they are all technically wrong. Frontend validation in general is great for letting users know of issues early, but it cannot come at the cost of rejecting valid input: Well, here is my attempt: (function () { 'use strict'; var api = {}; // element needs to have type="email" api.isValidEmail = function (element) { // leverage the Constraint Validation API when it is available if (typeof element.checkValidity === 'function') { return element.checkValidity(); } // otherwise, this is about the only regex // that doesn't reject any valid email addresses return (/@/).test(element.value); }; }()); Please note that, at the time of writing, the Constraint Validation API has a willful violation of RFC 5322 with the following explanation: [RFC 5322] defines a syntax for e-mail addresses that is simultaneously too strict (before the “@” character), too vague (after the “@” character), and too lax (allowing comments, whitespace characters, and quoted strings in manners unfamiliar to most users) to be of practical use here. Source: W3C E-mail state That link also provides a regular expression that implements the current specification in case you really want to go down that road: /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/Thoughts on the status of web development2014-07-12T00:00:00+00:002014-07-12T00:00:00+00:00http://blog.javiercejudo.com/thoughts-on-the-status-of-web-development<p>Web development is becoming more and more relevant every day, as private
companies, public organisations and even individuals develop ever more
complex (and useful) applications that manage all sorts of processes:
<a href="http://www.theiconic.com.au/mens-shoes/">buying a pair of shoes</a>,
<a href="https://www.healthcare.gov/">applying for health insurance</a> and even
<a href="http://www.qantas.com.au/travel/airlines/flight-search/global/en">purchasing tickets</a>
for your next international flight.</p>
<h2 id="the-exciting-parts">The exciting parts</h2>
<p>In my opinion, one of the most exciting things happening in the field is the
proliferation of incredibly powerful, cost-effective tools that are at the
disposal of the public. I am referring to tools like cloud application platforms
(e.g. <a href="https://www.heroku.com/">Heroku</a>), continuous integration services
(e.g. <a href="https://travis-ci.org/">Travis</a>) and so on.</p>
<p>The concepts behind these tools are not new, but the convenience and
affordability they have brought to the community of web development is
remarkable, usually allowing people to develop their skills free of charge
through their <em>freemium</em> models.</p>
<p>On top of that, there is an increasing trend to share code within the community,
not only from individual developers but also from origanisations. It is hard to
find a technology company not sharing interesting solutions on their
<a href="https://github.com/">GitHub</a> account.</p>
<p>At a more technical level, how all that code comes together without conflicting
with each other is no trivial matter, but tools like <a href="http://bower.io/">Bower</a>
or <a href="http://enderjs.com/">Ender</a> are easing the pain that frontend dependency
management used to be.</p>
<p>The steady shift to rich client-side applications in recent years offers
developers the opportunity to create an enhanced user experience with faster,
more responsive sites and meaningful lightweight animations, among other things.
Frameworks like <a href="https://angularjs.org/">AngularJS</a> or
<a href="http://facebook.github.io/react/">React</a> facilitate that work by providing ways
to organise, extend, and reuse easily testable modules. All these frameworks are
still in a relatively early stage of maturity, so it is my expectation that
their continued improvement will drive the foundation for a better web.</p>
<h2 id="the-necessary-specs">The necessary specs</h2>
<p>Moving onto not so exciting aspects of the field, web developers have already
adopted <a href="http://en.wikipedia.org/wiki/Cascading_Style_Sheets#CSS_3">CSS3</a> and
<a href="http://en.wikipedia.org/wiki/HTML5">HTML5</a> as part of their daily workflow.
AngularJS is designing version 2 using
<a href="http://en.wikipedia.org/wiki/ECMAScript#Versions">ECMAScript 6</a> that compiles
into 5.</p>
<p>However, it is worth mentioning that neither of those have final specifications:
only <a href="http://www.w3.org/TR/#tr_CSS">a few out of over fifty CSS3</a> modules have
been published as recommendations, and HTML5 as well as ECMAScript 6 are still
works in progress. It is easy to get excited about the possibilities for
innovation that new languages bring, but a greater effort and willingness to be
involved will be needed in the coming years.</p>
<p>This ensures that the reality of web development does not fall out of sync with
the specification of the necessary standards to support it.</p>Web development is becoming more and more relevant every day, as private companies, public organisations and even individuals develop ever more complex (and useful) applications that manage all sorts of processes: buying a pair of shoes, applying for health insurance and even purchasing tickets for your next international flight. The exciting parts In my opinion, one of the most exciting things happening in the field is the proliferation of incredibly powerful, cost-effective tools that are at the disposal of the public. I am referring to tools like cloud application platforms (e.g. Heroku), continuous integration services (e.g. Travis) and so on. The concepts behind these tools are not new, but the convenience and affordability they have brought to the community of web development is remarkable, usually allowing people to develop their skills free of charge through their freemium models. On top of that, there is an increasing trend to share code within the community, not only from individual developers but also from origanisations. It is hard to find a technology company not sharing interesting solutions on their GitHub account. At a more technical level, how all that code comes together without conflicting with each other is no trivial matter, but tools like Bower or Ender are easing the pain that frontend dependency management used to be. The steady shift to rich client-side applications in recent years offers developers the opportunity to create an enhanced user experience with faster, more responsive sites and meaningful lightweight animations, among other things. Frameworks like AngularJS or React facilitate that work by providing ways to organise, extend, and reuse easily testable modules. All these frameworks are still in a relatively early stage of maturity, so it is my expectation that their continued improvement will drive the foundation for a better web. The necessary specs Moving onto not so exciting aspects of the field, web developers have already adopted CSS3 and HTML5 as part of their daily workflow. AngularJS is designing version 2 using ECMAScript 6 that compiles into 5. However, it is worth mentioning that neither of those have final specifications: only a few out of over fifty CSS3 modules have been published as recommendations, and HTML5 as well as ECMAScript 6 are still works in progress. It is easy to get excited about the possibilities for innovation that new languages bring, but a greater effort and willingness to be involved will be needed in the coming years. This ensures that the reality of web development does not fall out of sync with the specification of the necessary standards to support it.Microdata for Rich Snippets2013-12-23T00:00:00+00:002013-12-23T00:00:00+00:00http://blog.javiercejudo.com/microdata-for-rich-snippets<h2 id="the-concept">The concept</h2>
<blockquote>
<p>Microdata annotates the DOM with scoped name/value pairs from custom vocabularies.</p>
</blockquote>
<p>The vocabulary we are using is <a href="http://schema.org/">Schema.org</a>, which is
recognized by Google, Bing and Yahoo! among others.</p>
<h2 id="the-goal">The goal</h2>
<p>Help search engines understand the content of a page in a semantic way.</p>
<h2 id="basic-example">Basic example</h2>
<p>Pay special attention to the attributes <code class="language-plaintext highlighter-rouge">itemscope</code>, <code class="language-plaintext highlighter-rouge">itemtype</code> and <code class="language-plaintext highlighter-rouge">itemprop</code>,
and to the <code class="language-plaintext highlighter-rouge">meta</code> tags:</p>
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="nt"><div</span> <span class="na">itemscope</span> <span class="na">itemtype=</span><span class="s">"http://schema.org/Product"</span><span class="nt">></span>
<span class="nt"><meta</span> <span class="na">itemprop=</span><span class="s">"sku"</span> <span class="na">content=</span><span class="s">"123-sku"</span><span class="nt">></span>
<span class="nt"><h1</span> <span class="na">itemprop=</span><span class="s">"name"</span><span class="nt">></span>
Product title
<span class="nt"></h1></span>
<span class="nt"><span</span> <span class="na">class=</span><span class="s">"brand-name"</span> <span class="na">itemprop=</span><span class="s">"brand"</span> <span class="na">itemscope</span>
<span class="na">itemtype=</span><span class="s">"http://schema.org/Brand"</span><span class="nt">></span>
<span class="nt"><a</span> <span class="na">itemprop=</span><span class="s">"url"</span> <span class="na">href=</span><span class="s">"/brand-1"</span><span class="nt">></span>
<span class="nt"><span</span> <span class="na">itemprop=</span><span class="s">"name"</span><span class="nt">></span>Brand name<span class="nt"></span></span>
<span class="nt"></a></span>
<span class="nt"></span></span>
<span class="nt"><span</span> <span class="na">class=</span><span class="s">"star-wrap"</span> <span class="na">itemprop=</span><span class="s">"aggregateRating"</span> <span class="na">itemscope</span>
<span class="na">itemtype=</span><span class="s">"http://schema.org/AggregateRating"</span><span class="nt">></span>
<span class="nt"><meta</span> <span class="na">itemprop=</span><span class="s">"bestRating"</span> <span class="na">content=</span><span class="s">"5"</span><span class="nt">></span>
<span class="nt"><meta</span> <span class="na">itemprop=</span><span class="s">"ratingValue"</span> <span class="na">content=</span><span class="s">"4"</span><span class="nt">></span>
<span class="nt"><meta</span> <span class="na">content=</span><span class="s">"2"</span><span class="nt">></span>
<span class="nt"><span</span> <span class="na">class=</span><span class="s">"fa-icon-star"</span><span class="nt">></span></span>
<span class="nt"><span</span> <span class="na">class=</span><span class="s">"fa-icon-star"</span><span class="nt">></span></span>
<span class="nt"><span</span> <span class="na">class=</span><span class="s">"fa-icon-star"</span><span class="nt">></span></span>
<span class="nt"><span</span> <span class="na">class=</span><span class="s">"fa-icon-star"</span><span class="nt">></span></span>
<span class="nt"><span</span> <span class="na">class=</span><span class="s">"fa-icon-star stop"</span><span class="nt">></span></span>
<span class="nt"><span></span>
(<span class="nt"><span</span> <span class="na">class=</span><span class="s">"rating-num stop"</span> <span class="na">itemprop=</span><span class="s">"reviewCount"</span><span class="nt">></span>2<span class="nt"></span></span>)
<span class="nt"></span></span>
<span class="nt"></span></span>
...
<span class="nt"></div></span></code></pre></figure>
<p>The previous syntax describes a structure like the following:</p>
<ul>
<li><strong>Product</strong> [creates a new scope]
<ul>
<li><em>Sku:</em> 123-sku</li>
<li><em>Name:</em> Product name</li>
<li><strong>Brand</strong> [creates a new scope]
<ul>
<li><em>URL:</em> /brand-1</li>
<li><em>Name:</em> Brand name</li>
</ul>
</li>
<li><strong>Aggregate rating</strong> [creates a new scope]
<ul>
<li><em>Best rating:</em> 5</li>
<li><em>Rating value:</em> 4</li>
<li><em>Review count:</em> 2</li>
</ul>
</li>
<li>…</li>
</ul>
</li>
</ul>
<p>All that information is extracted by search engines and they can use it to
improve their results.</p>
<h2 id="things-to-consider-when-annotating-data">Things to consider when annotating data</h2>
<p>While implementing the rich snippets, one challenge we might come across is
that the data we want to annotate is either not in the DOM or it is not readily
available to be annotated. In other cases, even if the information is readily
available, the vocabulary requires it to be specified in a certain way. Have a
look at the following cases:</p>
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="c"><!-- 1. The data is not in the DOM! --></span>
<span class="nt"><meta</span> <span class="na">itemprop=</span><span class="s">"sku"</span> <span class="na">content=</span><span class="s">"123-sku"</span><span class="nt">></span>
<span class="c"><!-- 2. The data cannot be annotated as is! --></span>
<span class="c"><!--
The rating of a particular product is represented in the DOM
by stars that cannot be annotated.
We need to markup the actual value (★★★★☆ → 4):
--></span>
<span class="nt"><meta</span> <span class="na">itemprop=</span><span class="s">"bestRating"</span> <span class="na">content=</span><span class="s">"5"</span><span class="nt">></span>
<span class="nt"><meta</span> <span class="na">itemprop=</span><span class="s">"ratingValue"</span> <span class="na">content=</span><span class="s">"4"</span><span class="nt">></span>
<span class="c"><!--
The date of a review is displayed but it is not
machine friendly (09/07/2013 → 2013-07-09):
--></span>
<span class="nt"><span</span> <span class="na">itemprop=</span><span class="s">"datePublished"</span> <span class="na">content=</span><span class="s">"2013-07-09"</span><span class="nt">></span>09/07/2013<span class="nt"></span></span>
<span class="c"><!-- 3. The data needs to be specified in a certain way! --></span>
<span class="c"><!--
Stock availability is shown in the DOM as 'In Stock',
but the vocabulary needs it to be specified as follows
--></span>
<span class="nt"><link</span> <span class="na">itemprop=</span><span class="s">"availability"</span> <span class="na">href=</span><span class="s">"http://schema.org/InStock"</span> <span class="nt">/></span></code></pre></figure>
<p>The documentation is clear about which properties need to be declared as above
and the options available.</p>
<h2 id="things-to-consider-when-writing-new-html-applying-css-styles-or-simply-moving-things-around">Things to consider when writing new HTML, applying CSS styles or simply moving things around</h2>
<h3 id="wrap-semantic-blocks">Wrap semantic blocks</h3>
<p>To make it easy for new HTML to be annotated, it is good practice to wrap any
piece of information into its own element. A problem that we had when annotating
the product page was that the only common parent of the product information and
its reviews was the <code class="language-plaintext highlighter-rouge">body</code>, so we needed to wrap all the information in the
product page into its own <code class="language-plaintext highlighter-rouge">div</code>, which of course created a huge diff in Git.
The same applies to small pieces of information: if you need to display the
brand of a product and the product name, wrap each one into its own element:</p>
<figure class="highlight"><pre><code class="language-html" data-lang="html"><span class="c"><!--Suboptimal --></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"product-details"</span><span class="nt">></span>
Brand name - Product name
<span class="nt"></div></span>
<span class="c"><!--Better --></span>
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"product-details"</span><span class="nt">></span>
<span class="nt"><span></span>Brand name<span class="nt"></span></span> - <span class="nt"><span></span>Product name<span class="nt"></span></span>
<span class="nt"></div></span></code></pre></figure>
<h3 id="apply-css-styles-via-html-classes">Apply CSS styles via HTML classes</h3>
<p>Continuing with the example above, if we need to apply styling to the brand
name, it is better to do it through classes as this way is more robust than
applying styles through elements.</p>
<h3 id="moving-things-around">Moving things around</h3>
<p>As the microdata lives within the HTML, changes in the markup of a page can
easily break pre-existing annotations. To prevent that, if a block containing
microdata needs to be refactored, make sure to use the
<a href="http://www.google.com/webmasters/tools/richsnippets">Google Structured Data Testing Tool</a>
to check that the microdata is still valid or needs to be rearranged as well
(e.g. maybe a property that belongs to a particular scope has been moved out
of that scope).</p>
<h2 id="references">References</h2>
<ul>
<li><a href="http://schema.org/docs/gs.html">Getting started with schema.org</a></li>
<li><a href="http://diveintohtml5.info/extensibility.html#what-is-microdata">Dive Into HTML5: What is microdata?</a></li>
<li><a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/microdata.html#microdata">Living Standard - Microdata</a></li>
<li><a href="http://www.google.com/webmasters/tools/richsnippets">Google Structured Data Testing Tool</a></li>
</ul>The concept Microdata annotates the DOM with scoped name/value pairs from custom vocabularies. The vocabulary we are using is Schema.org, which is recognized by Google, Bing and Yahoo! among others. The goal Help search engines understand the content of a page in a semantic way. Basic example Pay special attention to the attributes itemscope, itemtype and itemprop, and to the meta tags: <div itemscope itemtype="http://schema.org/Product"> <meta itemprop="sku" content="123-sku"> <h1 itemprop="name"> Product title </h1> <span class="brand-name" itemprop="brand" itemscope itemtype="http://schema.org/Brand"> <a itemprop="url" href="/brand-1"> <span itemprop="name">Brand name</span> </a> </span> <span class="star-wrap" itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating"> <meta itemprop="bestRating" content="5"> <meta itemprop="ratingValue" content="4"> <meta content="2"> <span class="fa-icon-star"></span> <span class="fa-icon-star"></span> <span class="fa-icon-star"></span> <span class="fa-icon-star"></span> <span class="fa-icon-star stop"></span> <span> (<span class="rating-num stop" itemprop="reviewCount">2</span>) </span> </span> ... </div> The previous syntax describes a structure like the following: Product [creates a new scope] Sku: 123-sku Name: Product name Brand [creates a new scope] URL: /brand-1 Name: Brand name Aggregate rating [creates a new scope] Best rating: 5 Rating value: 4 Review count: 2 … All that information is extracted by search engines and they can use it to improve their results. Things to consider when annotating data While implementing the rich snippets, one challenge we might come across is that the data we want to annotate is either not in the DOM or it is not readily available to be annotated. In other cases, even if the information is readily available, the vocabulary requires it to be specified in a certain way. Have a look at the following cases: <!-- 1. The data is not in the DOM! --> <meta itemprop="sku" content="123-sku"> <!-- 2. The data cannot be annotated as is! --> <!-- The rating of a particular product is represented in the DOM by stars that cannot be annotated. We need to markup the actual value (★★★★☆ → 4): --> <meta itemprop="bestRating" content="5"> <meta itemprop="ratingValue" content="4"> <!-- The date of a review is displayed but it is not machine friendly (09/07/2013 → 2013-07-09): --> <span itemprop="datePublished" content="2013-07-09">09/07/2013</span> <!-- 3. The data needs to be specified in a certain way! --> <!-- Stock availability is shown in the DOM as 'In Stock', but the vocabulary needs it to be specified as follows --> <link itemprop="availability" href="http://schema.org/InStock" /> The documentation is clear about which properties need to be declared as above and the options available. Things to consider when writing new HTML, applying CSS styles or simply moving things around Wrap semantic blocks To make it easy for new HTML to be annotated, it is good practice to wrap any piece of information into its own element. A problem that we had when annotating the product page was that the only common parent of the product information and its reviews was the body, so we needed to wrap all the information in the product page into its own div, which of course created a huge diff in Git. The same applies to small pieces of information: if you need to display the brand of a product and the product name, wrap each one into its own element: <!--Suboptimal --> <div class="product-details"> Brand name - Product name </div> <!--Better --> <div class="product-details"> <span>Brand name</span> - <span>Product name</span> </div> Apply CSS styles via HTML classes Continuing with the example above, if we need to apply styling to the brand name, it is better to do it through classes as this way is more robust than applying styles through elements. Moving things around As the microdata lives within the HTML, changes in the markup of a page can easily break pre-existing annotations. To prevent that, if a block containing microdata needs to be refactored, make sure to use the Google Structured Data Testing Tool to check that the microdata is still valid or needs to be rearranged as well (e.g. maybe a property that belongs to a particular scope has been moved out of that scope). References Getting started with schema.org Dive Into HTML5: What is microdata? Living Standard - Microdata Google Structured Data Testing ToolCSS limitations on IE2013-12-15T00:00:00+00:002013-12-15T00:00:00+00:00http://blog.javiercejudo.com/css-limitations-on-ie<p>If you search for CSS limitations on IE, you will see sites where they state
that IE has asize limitation for CSS files, but in fact that is not the case:</p>
<ul>
<li>All style rules after the first 4,095 selectors are not applied. This is limited per sheet, not globally.</li>
<li>All style tags after the first 31 style tags are not applied.</li>
<li>On pages that uses the <code class="language-plaintext highlighter-rouge">@import</code> rule to continously import external style sheets that import other style sheets, style sheets that are more than three levels deep are ignored.</li>
</ul>
<p>Here is a
<a href="http://demos.telerik.com/testcases/4095issues.html">live demo for the first case</a>.</p>
<p>IE 10 has limitations of the same nature but it’d take a lot more effort to
reach them:</p>
<ul>
<li>A sheet may contain up to 65534 rules.</li>
<li>A document may use up to 4095 stylesheets.</li>
<li><code class="language-plaintext highlighter-rouge">@import</code> nesting is limited to 4095 levels (due to the 4095 stylesheet limit).</li>
</ul>
<p>If you think you might having issues due to the 4,095 constraint, you can take
your CSS and roughly count the number of selectors following the following
formula,</p>
<blockquote>
<p>Selectors ≈ Braces + Commas</p>
</blockquote>
<p>where <code class="language-plaintext highlighter-rouge">Braces</code> is the number of braces (<code class="language-plaintext highlighter-rouge">{</code>), and <code class="language-plaintext highlighter-rouge">Commas</code> is the number of
commas (<code class="language-plaintext highlighter-rouge">,</code>). The formula is an approximation because there are commas inside
some CSS rules. A better option is to run your stylesheets through
<a href="http://cssstats.com">CSS Stats</a>.</p>
<p>A quick solution is to simply separate the CSS file(s) with problems into
smaller pieces.</p>
<p>There is a
<a href="https://github.com/makandra/ie-css-test">github project with tests for this</a>
you can check out that confirms that the size is not the issue:</p>
<blockquote>
<p>There are some rumors on the interwebs about IE breaking at a file size around roughly 288 kilobytes.</p>
<p>We generate a CSS file of about 500 kb (when built statically).</p>
<p>Tested with IE 8 and 9, none broke. People were probably just hitting the selector limit.</p>
</blockquote>
<h2 id="references">References</h2>
<ul>
<li><a href="http://support.microsoft.com/kb/262161">Microsoft Support</a></li>
<li><a href="http://blogs.msdn.com/b/ieinternals/archive/2011/05/14/10164546.aspx">IEInternals</a></li>
</ul>If you search for CSS limitations on IE, you will see sites where they state that IE has asize limitation for CSS files, but in fact that is not the case: All style rules after the first 4,095 selectors are not applied. This is limited per sheet, not globally. All style tags after the first 31 style tags are not applied. On pages that uses the @import rule to continously import external style sheets that import other style sheets, style sheets that are more than three levels deep are ignored. Here is a live demo for the first case. IE 10 has limitations of the same nature but it’d take a lot more effort to reach them: A sheet may contain up to 65534 rules. A document may use up to 4095 stylesheets. @import nesting is limited to 4095 levels (due to the 4095 stylesheet limit). If you think you might having issues due to the 4,095 constraint, you can take your CSS and roughly count the number of selectors following the following formula, Selectors ≈ Braces + Commas where Braces is the number of braces ({), and Commas is the number of commas (,). The formula is an approximation because there are commas inside some CSS rules. A better option is to run your stylesheets through CSS Stats. A quick solution is to simply separate the CSS file(s) with problems into smaller pieces. There is a github project with tests for this you can check out that confirms that the size is not the issue: There are some rumors on the interwebs about IE breaking at a file size around roughly 288 kilobytes. We generate a CSS file of about 500 kb (when built statically). Tested with IE 8 and 9, none broke. People were probably just hitting the selector limit. References Microsoft Support IEInternals