Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<h1>SnappySnippet</h1> <p>I finally found some time to create this tool. You can install <a href="https://chrome.google.com/webstore/detail/snappysnippet/blfngdefapoapkcdibbdkigpeaffgcil">SnappySnippet</a> from Chrome Web Store. It allows easy HTML+CSS extraction from the specified (last inspected) DOM node. Additionally, you can send your code straight to CodePen or JSFiddle. Enjoy!</p> <p><img src="https://i.stack.imgur.com/AasFL.png" alt="SnappySnippet Chrome extension"></p> <h1>Other features</h1> <ul> <li>cleans up HTML (removing unnecessary attributes, fixing indentation)</li> <li>optimizes CSS to make it readable</li> <li>fully configurable (all filters can be turned off)</li> <li>works with <code>::before</code> and <code>::after</code> pseudo-elements</li> <li>nice UI thanks to <a href="http://getbootstrap.com/">Bootstrap</a> &amp; <a href="http://designmodo.github.io/Flat-UI/">Flat-UI</a> projects</li> </ul> <h1>Code</h1> <p>SnappySnippet is open source, and you can find the <a href="https://github.com/kdzwinel/SnappySnippet">code on GitHub</a>.</p> <h1>Implementation</h1> <p>Since I've learned quite a lot while making this, I've decided to share some of the problems I've experienced and my solutions to them, maybe someone will find it interesting.</p> <h2>First attempt - getMatchedCSSRules()</h2> <p>At first I've tried retrieving the original CSS rules (coming from CSS files on the website). Quite amazingly, this is very simple thanks to <code>window.getMatchedCSSRules()</code>, however, it didn't work out well. The problem was that we were taking only a part of the HTML and CSS selectors that were matching in the context of the whole document, which were not matching anymore in the context of an HTML snippet. Since parsing and modifying selectors didn't seem like a good idea, I gave up on this attempt.</p> <h2>Second attempt - getComputedStyle()</h2> <p>Then, I've started from something that @CollectiveCognition suggested - <code>getComputedStyle()</code>. However, I really wanted to separate CSS form HTML instead of inlining all styles.</p> <h3>Problem 1 - separating CSS from HTML</h3> <p>The solution here wasn't very beautiful but quite straightforward. I've assigned IDs to all nodes in the selected subtree and used that ID to create appropriate CSS rules.</p> <h3>Problem 2 - removing properties with default values</h3> <p>Assigning IDs to the nodes worked out nicely, however I found out that each of my CSS rules has ~300 properties making the whole CSS unreadable.<br/> Turns out that <code>getComputedStyle()</code> returns all possible CSS properties and values calculated for the given element. Some of them where empty, some had browser default values. To remove default values I had to get them from the browser first (and each tag has different default values). The solution was to compare the styles of the element coming from the website with the same element inserted into an empty <code>&lt;iframe&gt;</code>. The logic here was that there are no style sheets in an empty <code>&lt;iframe&gt;</code>, so each element I've appended there had only default browser styles. This way I was able to get rid of most of the properties that were insignificant.</p> <h3>Problem 3 - keeping only shorthand properties</h3> <p>Next thing I have spotted was that properties having shorthand equivalent were unnecessarily printed out (e.g. there was <code>border: solid black 1px</code> and then <code>border-color: black;</code>, <code>border-width: 1px</code> itd.).<br/> To solve this I've simply created a list of properties that have shorthand equivalents and filtered them out from the results.</p> <h3>Problem 4 - removing prefixed properties</h3> <p>The number of properties in each rule was significantly lower after the previous operation, but I've found that I sill had a lot of <code>-webkit-</code> prefixed properties that I've never hear of (<code>-webkit-app-region</code>? <code>-webkit-text-emphasis-position</code>?).<br/> I was wondering if I should keep any of these properties because some of them seemed useful (<code>-webkit-transform-origin</code>, <code>-webkit-perspective-origin</code> etc.). I haven't figured out how to verify this, though, and since I knew that most of the time these properties are just garbage, I decided to remove them all.</p> <h3>Problem 5 - combining same CSS rules</h3> <p>The next problem I have spotted was that the same CSS rules are repeated over and over (e.g. for each <code>&lt;li&gt;</code> with the exact same styles there was the same rule in the CSS output created).<br/> This was just a matter of comparing rules with each other and combining these that had exactly the same set of properties and values. As a result, instead of <code>#LI_1{...}, #LI_2{...}</code> I got <code>#LI_1, #LI_2 {...}</code>.</p> <h3>Problem 6 - cleaning up and fixing indentation of HTML</h3> <p>Since I was happy with the result, I moved to HTML. It looked like a mess, mostly because the <code>outerHTML</code> property keeps it formatted exactly as it was returned from the server.<br/> The only thing HTML code taken from <code>outerHTML</code> needed was a simple code reformatting. Since it's something available in every IDE, I was sure that there is a JavaScript library that does exactly that. And it turns out that <a href="https://code.google.com/p/jquery-clean/">I was right (jquery-clean)</a>. What's more, I've got unnecessary attributes removal extra (<code>style</code>, <code>data-ng-repeat</code> etc.).</p> <h3>Problem 7 - filters breaking CSS</h3> <p>Since there is a chance that in some circumstances filters mentioned above may break CSS in the snippet, I've made all of them optional. You can disable them from the <em>Settings</em> menu.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload