{"id":103,"date":"2006-01-22T00:21:23","date_gmt":"2006-01-22T00:21:23","guid":{"rendered":"http:\/\/lachy.id.au\/log\/2006\/01\/anatomy-of-a-hack"},"modified":"2006-04-30T23:25:12","modified_gmt":"2006-04-30T23:25:12","slug":"csshack","status":"publish","type":"post","link":"https:\/\/lachy.id.au\/log\/2006\/01\/csshack","title":{"rendered":"Anatomy of a CSS Hack"},"content":{"rendered":"<p>As web developers, CSS hacks form an integral part of our every day lives\r\n\tand as we\u2019re building a web site, there is all too often occasions where our\r\n\tonly choice is to resort to using one to work around a browser bug.  But although\r\n\twe make such frequent use of them, many authors may not fully understand the\r\n\tissues at hand and may not be able to make the best decision about which hack\r\nto use, or even whether to use a hack at all.<\/p>\r\n<p>Every single hack is made up of a combination of 3 different types of components\r\n\tthat form together in combination to make up what we often refer to as a single\r\n\tentity: a <em>CSS hack<\/em>.  These types are <a href=\"#csshack-limitation\">limitations<\/a>, <a href=\"#csshack-filter\">filters<\/a> and <a href=\"#csshack-patch\">patches<\/a>\tand each hack will usually make use of at least one of each.<\/p>\r\n\r\n<h3 id=\"csshack-limitation\">The Limitation<\/h3>\r\n<p>This is, in fact, the driving force behind the desire\/requirement to use a\r\n\thack in the first place.  It is the buggy behaviour and\/or lack of support for\r\n\ta specific feature that requires us to find an alternative.  In IE, for example,\r\n\tthe double margin float bug, the lack of support for a property like <code>min-height<\/code>\tor the <code>::before<\/code> and <code>::after<\/code> pseudo-elements are all limitations which often\r\n\trequire workarounds, usually in the form of a hack.<\/p>\r\n<p>Without a limitation, there is no need for a hack at all and when it comes\r\n\tto the decision of whether or not to use a hack, it\u2019s important to understand\r\n\twhether the limitation is legitimate, or simply failure on your part to understand\r\n\tthe correct behaviour.<\/p>\r\n<p>For example, say you have some CSS in your page and are looking at it in two\r\n\tdifferent browsers, but both browsers are displaying different results and\r\n\tyou don\u2019t understand which is correct (assume for the moment that one of\r\n\tthem definitely is).  In this situation, without more information, it is\r\n\timpossible to decide upon the best course of action to take \u2014 you cannot\r\n\tdecide to use a hack because you don\u2019t yet know which browser to target.<\/p>\r\n\r\n<h3 id=\"csshack-patch\">The Patch<\/h3>\r\n<p>The patch is, obviously, the mechanism used to fix, or <em>patch<\/em>, the\r\n\tlimitation.  These usually work by providing some alternate styling that either\r\n\tproduces a similar result or triggers some special behaviour in the browser\u2019s\r\n\trendering engine to make it work, for the most part, as intended.  For example,\r\n\tusing &#8216;<code>height<\/code>&#8216; as the substitute for IE\u2019s lack of support for &#8216;<code>min-height<\/code>&#8216; is\r\n\ta form of alternate styling, whereas using &#8216;<code>display: inline;<\/code>&#8216; to fix the double\r\n\tmargin float bug or &#8216;<code>height: 1%;<\/code>&#8216; to trigger the hasLayout property are more\r\n\tlike triggers to make IE work properly.<\/p>\r\n<p>Some patches rely on further buggy behaviour, like IE\u2019s broken implementation\r\n\tof &#8216;<code>height<\/code>&#8216;; some are benign in nature which have no detrimental effect if applied\r\n\tto any other browsers, such as &#8216;<code>display: inline;<\/code>&#8216; for the double margin float\r\n\tbug; and, lastly, some are a completely conformant alternative which may not\r\n\tbe as ideal, but are at least supported by the target browser and are a suitable\r\n\tsubstitute.<\/p>\r\n<p>For example, one could use &#8216;<code>display: inline-block;<\/code>&#8216; which is supported\r\n\tby IE, as an alternative to &#8216;<code>display: table-cell;<\/code>&#8216; in some cases.  They\u2019re\r\n\tnot perfect substitutes (and it\u2019s probably not the best example), but one\r\n\tcould make use of their similarities to produce similar results across the browsers.<\/p>\r\n\r\n<h3 id=\"csshack-filter\">The Filter<\/h3>\r\n<p>The filter is the glue that binds it all together and is used to make sure\r\n\tthat only a select set of browsers will apply the patch and there is a <a href=\"http:\/\/centricle.com\/ref\/css\/filters\/\">large\r\n\trange of CSS filters<\/a> available for the picking.  These come\r\n\tin two primary forms: hide from target browsers and hide from conformant\r\n\tbrowsers.<\/p>\r\n<p>The first is to hide the correct CSS from the target browsers (such as using\r\n\tthe child combinator to hide styles from IE).  With this form, it is the conformant\r\n\tCSS that is hidden from the target browsers, yet the patch itself is not usually\r\n\thidden; it is simply overridden by subsequent styles or styles with a higher\r\n\tspecificity, effectively causing the patch to be ignored by conformant browsers\r\n\tanyway.  In this case, it\u2019s important to ensure that all conforming browsers\r\n\t(with respect to the limitation) also support the filter, so that the correct\r\n\tCSS is applied.<\/p>\r\n<p>The second form is to hide the patch from newer, conformant browsers (such\r\n\tas using <a href=\"http:\/\/centricle.com\/ref\/css\/filters\/tests\/star_html\/\">star\r\n\thtml<\/a> or a <a href=\"http:\/\/msdn.microsoft.com\/workshop\/author\/dhtml\/overview\/ccomment_ovw.asp\">conditional\r\n\tcomment<\/a> to hide from everything but IE). \r\n\tIn this case, the conforming CSS will be seen by all browsers, yet the patch\r\n\tshould only be seen by the target browser.  In such cases, the filter usually\r\n\tdepends on an additional limitation in the target browser and, as a result,\r\n\tyou must be careful that all browsers suffering from the filter limitation also\r\n\tsuffer from the original limitation.<\/p>\r\n<p>Such cases are rare, but they do happen and they need to be dealt with appropriately. \r\n\tFor example, the \u201cbe nice to Opera\u201d patch within the <a href=\"http:\/\/www.tantek.com\/CSS\/Examples\/boxmodelhack.html\">Box\r\n\tModel Hack<\/a> is an example\r\n\tof where the first patch (intended for IE5) was incorrectly applied to Opera\r\n\t\u2013 a conforming browser with respect to the original limitation, but non-conforming\r\n\twith respect to the filter \u2013 and thus needed an additional work around.<\/p>\r\n<p>Lastly, some filters are actually a combination of both types, whereby the\r\n\tpatch is hidden from conformant browsers and the conformant CSS is hidden\r\n\tfrom the target browsers.  For example, there\u2019s an <a href=\"http:\/\/annevankesteren.nl\/2005\/10\/ie-import-hack\"><code>@import<\/code> hack<\/a> which\r\n\twill load one CSS file in conforming browsers and another in non-conforming\r\n\tbrowsers.<\/p>\r\n","protected":false},"excerpt":{"rendered":"Every single hack is made up of a combination of 3 different types of components that form together in combination to make up what we often refer to as a single entity: a CSS hack. These types are limitations, filters and patches and each hack will usually make use of at least one of each.","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/posts\/103"}],"collection":[{"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/comments?post=103"}],"version-history":[{"count":0,"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/posts\/103\/revisions"}],"wp:attachment":[{"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/media?parent=103"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/categories?post=103"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lachy.id.au\/log\/wp-json\/wp\/v2\/tags?post=103"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}