Jon Rohan Web Designer & Developer http://jonrohan.codes/assets/images/apple-touch-icon-72x72.png http://jonrohan.codes/assets/images/apple-touch-icon-72x72.png 2015-06-02T00:00:00-07:00 http://jonrohan.codes/ &copy; Jon Rohan 2018. All rights reserved. Jon Rohan http://jonrohan.codes http://jonrohan.codes/fieldnotes/implementing-an-all-css-tooltip Implementing an all CSS tooltip 2015-06-02T00:00:00-07:00 2015-06-02T00:00:00-07:00 GitHub's UI is a complex system of actions, notes and complex meanings. As a result, we've leaned pretty hard on tooltips. Since the site first launched we used a tooltip plugin called tipsy. Performance troubles led us to build CSS tooltips. &copy; Jon Rohan 2015. All rights reserved. <p>GitHub’s UI is a complex system of actions, notes and complex meanings. As a result, we’ve leaned pretty hard on tooltips. Since the site first launched we used a tooltip plugin called <a href="https://github.com/jaz303/tipsy">tipsy</a>.</p> <h3 id="tipsy">Tipsy</h3> <p>Tipsy, <em>now unmaintained</em>, was a jQuery plugin to replicate Facebook’s tooltip styles. Back then it was simple to add to the site, we dropped it in, and kept it around for a while.</p> <p>Last year I began to turn a <img class="emoji" title=":mag:" alt=":mag:" src="https://assets.github.com/images/icons/emoji/unicode/1f50d.png" height="20" width="20" align="absmiddle" /> critical eye to tipsy. We were focusing on front-end performance and were trimming all excess javascript events. What I found was we were firing sometimes hundreds of <code>mouseover</code> &amp; <code>mouseout</code> events on pages that had a lot of tooltips.</p> <p>We knew then that we wanted to kill tipsy from our site, but the only hope we had was to make a fully CSS solution.</p> <h3 id="hintcss">Hint.css</h3> <p>It was about this time that a library was released on GitHub. <a href="http://kushagragour.in/lab/hint/">Hint.css</a>, is <em>”..a tooltip library written in SASS which uses only HTML/CSS to create simple tooltips.”</em> This was a very interesting development and perfect timing because we were considering a tooltip replacement. Hint promised to be everything we wanted.</p> <p>We investigated and found that Hint.css is a very elegant solution, but didn’t match our tooltip style. More specifically, we wanted tooltips that centered on content.</p> <h3 id="hint-vs-tipsy">Hint vs Tipsy</h3> <p>I didn’t want to have to redesign our tooltips or figure out how they fit on all the different places we scattered them. The fact that Hint.css, <em>at the time</em>, only showed tooltips from the top left or bottom left made using it a non-starter.</p> <figure class="post-image image-style-full"> <div class="image-wrap"> <img src="http://jonrohan.codes/assets/images/posts/css-tooltips/hintvstipsy.png" /></div> </figure> <h3 id="primercss-tooltips">Primer.css tooltips</h3> <p><em>“I was tinkering around and found a way we can replace tipsy with all css tooltips. I’ve already seen a couple of downside and upsides, but I will create a pull request with the advantages and disadvantages here. We can have a thread on if we really want to do this or not.”</em></p> <p>That’s how I started a pull request off where I had been working out a way to rebuild our tooltips with CSS. The breakthrough happened when I read about <code>translateX</code> which has pretty good <a href="#browser-support">browser support</a> now. Translate calculates the position based on the <a href="http://jonrohan.codes/fieldnotes/vertically-center-clipped-image/#a-fist-full-of-properties">object’s size</a>. The difficulty before was, we don’t know how wide the tooltips are going to be. We can’t position them in the old fashion where we offset with <code>margin-left: -50px;</code>.</p> <p>What we <a href="https://github.com/primer/primer/blob/f266ae3bd95137c0a0cf4f6703c61335721cfa56/scss/_tooltips.scss">ended up with</a>, was a hybrid of Hint and Tipsy.</p> <h3 id="replacing-717-tooltips">Replacing 717 tooltips</h3> <p>I’m not exaggerating when I say <strong>I replaced 717 tooltips</strong> across our codebase. This didn’t happen in one big swoop. And it wasn’t released to non-staff for a few weeks.</p> <p>The approach I took was to start out by making the new <a href="https://github.com/primer/primer/blob/f266ae3bd95137c0a0cf4f6703c61335721cfa56/scss/_tooltips.scss">Primer tooltips</a> and tipsy work side by side. To do this, I added a class to the body for all non-staff. <code>tipsy-tooltips</code>.</p> <pre><code class="language-coffee">$.observe '.tipsy-tooltips .tooltipped', init: -&gt; el = $(this) el.attr('aria-label', el.attr('title')) unless el.attr('aria-label') el.tipsy { gravity: gravity title: 'aria-label' } add: -&gt; $(this).tipsy 'enable' remove: -&gt; $(this).tipsy 'disable' $.fn.tipsy.revalidate() </code></pre> <p>Doing this would turn on tipsy tooltips for anyone who had the <code>tipsy-tooltips</code> class.</p> <p>For GitHub staff, I had a conditional around the tooltip stylesheet bundle. Which would only add the css to the page if the user was staff.</p> <pre><code class="language-erb">&lt;%= stylesheet_bundle 'tooltipped' if css_tooltips_enabled? %&gt; </code></pre> <p>The strategy behind this was to give us the ability to find the bugs with the new system before shipping it to the public.</p> <hr /> <h3 id="advantages">Advantages</h3> <p>There were going to be trade-offs in going from a JS based tooltip solution to a CSS based solution. I wanted to list the advantages and disadvantages to see if the benefits outweighed the trade-offs.</p> <h4 id="performance">Performance</h4> <p>This was the first question in my head, because we’re doing a bunch of transformations and transitions with the css version it’s unclear that it’s really a win. But early diagnostics look good! Here’s the mouse hovering over the collapsed repository sidebar tipsy vs. primer css tooltips.</p> <figure class="post-image image-style-full"> <div class="image-wrap"> <img class="zoom-image js-zoom-image" alt="Tipsy repaints in the Chrome devtools event timeline" src="http://jonrohan.codes/assets/images/posts/css-tooltips/repaint-before.png" /></div> <figcaption class="image-caption">Tipsy repaints in the Chrome devtools event timeline</figcaption> </figure> <p>In the tipsy timeline, you can see at the top there are spikes that are shooting into the 30fps range. This causes <a href="http://jankfree.org/">jank</a> hovering and scrolling on some of our larger pages.</p> <p>Notice also the yellow bar that occurs at the beginning of the event waterfall. This is the time it takes for the JS mouseover event to fire and move the tooltip into position.</p> <figure class="post-image image-style-full"> <div class="image-wrap"> <img class="zoom-image js-zoom-image" alt="Primer css tooltip repaints in the Chrome devtools event timeline" src="http://jonrohan.codes/assets/images/posts/css-tooltips/repaint-after.png" /></div> <figcaption class="image-caption">Primer css tooltip repaints in the Chrome devtools event timeline</figcaption> </figure> <p>For comparison here is the Primer.css tooltip timeline. All of the actions remain in the 60fps <img class="emoji" title=":sparkles:" alt=":sparkles:" src="https://assets.github.com/images/icons/emoji/unicode/2728.png" height="20" width="20" align="absmiddle" />.</p> <p>I was also looking into the paint rectangles that happen when tipsy was fired, versus primer.css tooltips.</p> <figure class="post-image image-style-full"> <div class="image-wrap"> <img src="http://jonrohan.codes/assets/images/posts/css-tooltips/paint-calcs-before.png" /></div> </figure> <p>Tipsy’s paint triangle was the whole screen. I believe because the tooltip is moved off screen and repositioned after every hover.</p> <figure class="post-image image-style-full"> <div class="image-wrap"> <img src="http://jonrohan.codes/assets/images/posts/css-tooltips/paint-calcs-after.png" /></div> </figure> <p>The fully css tooltips had very little screen repaints.</p> <h4 id="flexibility">Flexibility</h4> <figure class="post-image image-style-smallest"> <div class="image-wrap"> <img class="zoom-image js-zoom-image" src="http://jonrohan.codes/assets/images/posts/css-tooltips/focus.gif" /></div> <figcaption class="image-caption">Tooltips on <code>:focus</code></figcaption> </figure> <p>There was more flexibility with how and when we triggered the tooltips.</p> <p>We could easily add <code>:focus</code> triggers for the tooltips without adding more js events to them.</p> <p>Even adding transitions and delays to the tooltips. Delays could be useful if we didn’t want the tooltips to appear right away. Giving the UX a more natural feel.</p> <hr /> <h3 id="disadvantages">Disadvantages</h3> <p>There were some disadvantages that caused us to rework some of our code.</p> <h4 id="overflow-hidden">Overflow hidden</h4> <p>This was one of the biggest trade-offs we had to overcome. There are many reasons you may want to use <code>overflow: hidden;</code> or scroll. We do this in our issue comments, and in a lot of places that traditional <a href="http://jonrohan.codes/fieldnotes/clear-fixes/#post">clearfix</a> fixes won’t work.</p> <p>The problem is the tooltips were no longer global elements in the DOM. They now existed right along side the element that was triggering the tooltip. When these elements were inside a container that had <code>overflow:hidden;</code> applied to it, you would get clipped content and not see the full tooltip or sometimes none of it.</p> <p>With tipsy we didn’t have this problem, because tipsy creates a global tooltip that it reuses for every element. The global tooltip element lives at the bottom of the page, placing it safe from clipping.</p> <h4 id="before-after-collisions"><code>:before, :after</code> collisions</h4> <p>Anytime we used <code>.tooltipped</code> classes in conjunction with another class that used the <code>:before, :after</code> pseudo-selectors we had collisions. This meant that we couldn’t use the <code>.tooltipped</code> class with our <a href="https://github.com/blog/1106-say-hello-to-octicons">octicons</a>, clearfix or a few other minor places we used <code>:before</code> and <code>:after</code>.</p> <p>We would get around this by separating these to separate elements.</p> <h4 id="title-attributes">title attributes</h4> <figure class="post-image image-style-smallest"> <div class="image-wrap"> <img class="zoom-image js-zoom-image" src="http://jonrohan.codes/assets/images/posts/css-tooltips/title-conflict.png" /></div> <figcaption class="image-caption">Native tooltips and css tooltips all together.</figcaption> </figure> <p>The way that tipsy worked was it used the already defined <code>title=</code> attribute on an element, grab the data within, destroy the <code>title=</code> attribute, then display the tooltip. This was how it got around displaying both the native tooltip and the tipsy tooltip.</p> <p>That is a lot of logic that we couldn’t accomplish with pure CSS tooltips. We ended up using <a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute">aria-label</a> instead. Which would not display a native tooltip, but would add context for users with accessibility issues. <em>“The aria-label attribute is used to define a string that labels the current element. Use it in cases where a text label is not visible on the screen.”</em></p> <p>What seemed like a disadvantage turned out to be an advantage. Our site was now getting more accessible.</p> <hr /> <h3 id="going-live">Going live</h3> <p>After all the bugs <img class="emoji" title=":bug:" alt=":bug:" src="https://assets.github.com/images/icons/emoji/unicode/1f41b.png" height="20" width="20" align="absmiddle" /> were squashed, we decided that it was ready for everyone. Before shipping, we began tracking window performance with <code>window.performance</code> to see the results.</p> <figure class="post-image image-style-full"> <div class="image-wrap"> <img class="zoom-image js-zoom-image" src="http://jonrohan.codes/assets/images/posts/css-tooltips/slow-js-events.png" /></div> <figcaption class="image-caption">When we turned on the all css tooltips this was the performance graph of slow mouseover events</figcaption> </figure> <p>The graphs looked GREAT! When we turned on the css tooltips, slow mouseover js events went from around 30,000 an hour to almost 0.</p> <img src="http://www.google-analytics.com/collect?v=1&t=pageview&dl=http%3A%2F%2Fjonrohan.codes%2Fatom%2Ffieldnotes%2Fimplementing-an-all-css-tooltip&ul=en-us&de=UTF-8&dt=Implementing%20an%20all%20CSS%20tooltip&cid=198907588.1430708348&tid=UA-543420-18"> http://jonrohan.codes/fieldnotes/vertically-center-clipped-image How to vertically center a clipped image in CSS 2015-05-08T00:00:00-07:00 2015-05-08T00:00:00-07:00 Sometimes you need to clip an image to a certain height, even though the image may be taller. This article shows you how to clip the image and center it vertically. &copy; Jon Rohan 2015. All rights reserved. <p>Sometimes you need to clip an image to a certain height, even though the image may be taller. Except when you do this, you end up getting only the top or bottom portion of the image, which probably isn’t useful.</p> <p>Here’s how you vertically align the image inside of a clipping window.</p> <h4 id="heres-an-example">Here’s an example</h4> <p>This is a <code>600px</code> image clipped to a <code>100px</code> high wrapper. I added some visual lines to help you see the center. You can click it to see the full original image.</p> <div class="docs-example clearfix"><div class="image-wrapper"> <img class="zoom-image js-zoom-image" src="http://jonrohan.codes/assets/images/posts/centering.png" /> </div></div> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"image-wrapper"</span><span class="nt">&gt;</span> <span class="nt">&lt;img</span> <span class="na">class=</span><span class="s">"zoom-image js-zoom-image"</span> <span class="na">src=</span><span class="s">"http://jonrohan.codes/assets/images/posts/centering.png"</span><span class="nt">/&gt;</span> <span class="nt">&lt;/div&gt;</span></code></pre></div> <h4 id="calculating-the-offset">Calculating the offset</h4> <p>This is tricky because you need to calculate the amount of vertical offset based on the height of the image and the height of the wrapper. For example this image is <code>600px</code> and the window is <code>100px</code> <code>(600 - 100) / 2 = 250px</code>. We’ll need to bump image up vertically <code>250px</code> It is impractical to calculate for all your images, or costly to use JavaScript.</p> <p>If we use some algebra to move our equation around, we end up with <code>a * 0.5 + b * -0.5</code> where <code>a = wrapper height</code> and <code>b = image height</code>.</p> <h4 id="a-fist-full-of-properties">A fist full of properties</h4> <p>The two properties that we use to compute this dynamically is <code>top</code> and <code>translate</code>.</p> <ul> <li> <h5 id="top"><code>top</code></h5> <p>top calculates based on the wrapper. If we’re moving the <code>img { top: 50%; }</code> it moves the image down 50% of the wrapper height.</p> </li> <li> <h5 id="translatey"><code>translateY</code></h5> <p>translateY calculates based on the height of the object. When we’re applying it to the <code>img { transform: translateY(-50%); }</code> That moves the image back up, 50% of the image height.</p> </li> </ul> <p>Putting it together we get this css. We also need to set the <code>position: relative;</code> on the img and <code>overflow: hidden;</code> on the parent wrapper. Or we’ll end up seeing all the image anyways.</p> <div class="highlight"><pre><code class="language-css" data&#45;lang="css"><span class="nc">.image-wrapper</span> <span class="p">{</span> <span class="nl">height</span><span class="p">:</span> <span class="m">100px</span><span class="p">;</span> <span class="nl">overflow</span><span class="p">:</span> <span class="nb">hidden</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.image-wrapper</span> <span class="nt">img</span> <span class="p">{</span> <span class="nl">position</span><span class="p">:</span> <span class="nb">relative</span><span class="p">;</span> <span class="nl">top</span><span class="p">:</span> <span class="m">50%</span><span class="p">;</span> <span class="nl">transform</span><span class="p">:</span> <span class="n">translateY</span><span class="p">(</span><span class="m">-50%</span><span class="p">);</span> <span class="p">}</span></code></pre></div> <p>Oh and if you’re not using <a href="https://github.com/postcss/autoprefixer">autoprefixer</a>, which I highly recommend you put it in your workflow somewhere, then here are the browser prefixes you’ll need.</p> <div class="highlight"><pre><code class="language-css" data&#45;lang="css"><span class="nt">-webkit-transform</span><span class="o">:</span> <span class="nt">translateY</span><span class="o">(</span><span class="nt">-50</span><span class="o">%);</span> <span class="nt">-ms-transform</span><span class="o">:</span> <span class="nt">translateY</span><span class="o">(</span><span class="nt">-50</span><span class="o">%);</span> <span class="nt">transform</span><span class="o">:</span> <span class="nt">translateY</span><span class="o">(</span><span class="nt">-50</span><span class="o">%);</span></code></pre></div> <h4 id="practical-example">Practical example</h4> <p>I threw together an example on <a href="http://codepen.io/jonrohan/full/vOLENV/">codepen</a>. The example is similar to an image reveal you might find in a social timeline. Click the photo to see more of the image.</p> <p data&#45;height="360" data&#45;theme-id="14162" data&#45;slug-hash="vOLENV" data&#45;default-tab="result" data&#45;user="jonrohan" class="codepen">See the Pen <a href="http://codepen.io/jonrohan/pen/vOLENV/">Vertically center image</a> by Jon Rohan (<a href="http://codepen.io/jonrohan">@jonrohan</a>) on <a href="http://codepen.io">CodePen</a>.</p> <img src="http://www.google-analytics.com/collect?v=1&t=pageview&dl=http%3A%2F%2Fjonrohan.codes%2Fatom%2Ffieldnotes%2Fvertically-center-clipped-image&ul=en-us&de=UTF-8&dt=How%20to%20vertically%20center%20a%20clipped%20image%20in%20CSS&cid=198907588.1430708348&tid=UA-543420-18"> http://jonrohan.codes/fieldnotes/a-big-update-to-this-site A big update to this site 2015-05-03T00:00:00-07:00 2015-05-03T00:00:00-07:00 I recently updated this site. I wanted to share what I was using to build this site. With details on what each thing is good for. &copy; Jon Rohan 2015. All rights reserved. <p>Its been a <a href="https://dribbble.com/shots/107376-Field-guide-take-2">while</a> since I’ve given any attention to my site. I felt like devoting this weekend to it felt right. I’ve updated it to a new look. Its hosted on <a href="https://pages.github.com/">GitHub pages</a> which fits perfectly into my daily workflow. The design was custom by me.</p> <figure class="post-image image-style-full"> <div class="image-wrap"> <img src="http://jonrohan.codes/assets/images/posts/site-shot.png" /> </div> <figcaption class="image-caption">That new homepage feel</figcaption> </figure> <h3 id="tools">Tools</h3> <p>Heres a list of tools I’ve used in building this site.</p> <ul> <li><a href="#autoprefixer">autoprefixer</a></li> <li><a href="#bower">bower</a></li> <li><a href="#grunt">grunt</a></li> <li><a href="#ionicons">ionicons</a></li> <li><a href="#jekyll">jekyll</a></li> <li><a href="#normalize">normalize</a></li> <li><a href="#primer">primer</a></li> <li><a href="#momentjs">moment.js</a></li> <li><a href="#typekit">typekit</a></li> </ul> <h4 id="autoprefixer">Autoprefixer</h4> <p><a href="https://github.com/postcss/autoprefixer">Autoprefixer</a> is a great tool for normalizing all your prefixed css property. Instead of always remembering and writing the <code>-webkit-</code> prefixes for different css3 properties that haven’t been fully supported yet. Autoprefixer remembers those things for you.</p> <h4 id="bower">Bower</h4> <p><a href="http://bower.io/">Bower.io</a> is another package manager which is great for moving front end assets around like js/css libraries. You can checkout versions of jquery or d3.js and have them and any bug updates automatically included into your front end stack.</p> <h4 id="grunt">Grunt</h4> <p><a href="http://gruntjs.com/">Gruntjs</a> is like make, but for node. What makes grunt great is I can use it to hook in existing node and grunt packages to do tasks for me. I use it to update my bower libraries, build my jekyll site, and publish to gh-pages.</p> <h4 id="ionicons">ionicons</h4> <p>Most of the icons you see on the site are <code>svg</code> images of <a href="http://ionicons.com/">ionicons</a> I picked them because they were free and open source. And were really easy to drop into my designs.</p> <h4 id="jekyll">jekyll</h4> <p><a href="http://jekyllrb.com/">Jekyll</a> is the technology that is behind GitHub pages. It’s whole deal is it builds sites from html and markdown files and compiles them into plain old html. Then GitHub serves it. By computing the logic before you take out a lot of the processing time when a website is loaded.</p> <h4 id="normalize">normalize</h4> <p>Back in the day it was Eric Meyer’s css reset, but now you should really be using <a href="http://necolas.github.io/normalize.css/">normalize.css</a> It takes out any of the discrepancies between browser’s default settings. Making all of the default styles the same.</p> <h4 id="primer">Primer</h4> <p>I’m using <a href="http://primercss.io/">primer’s</a> grid and markdown styles. Because sometimes you don’t really need to re-invent something that is great.</p> <h4 id="momentjs">Moment.js</h4> <p><a href="http://momentjs.com/">Moment.js</a> is a way to take a date <code>2014-04-01T16:30:00-08:00</code> and turn it into something like <code>2 years ago</code>. Jekyll doesn’t include this sort of date calculation, but I wanted to have something and this worked.</p> <h4 id="typekit">typekit</h4> <p><a href="https://typekit.com/">Typekit</a> is probably the best way to include some beautiful fonts on your site. On this site I’m using:</p> <ul> <li>‘Proxima Nova’ for the body</li> <li>‘Quatro Slab’ for the headings and logo</li> <li>‘Source Code Pro’ for the code snippets</li> </ul> <hr /> <h5 id="more-to-come">More to come…</h5> <p>I’ll go into details in a later post on my gh-pages grunt build setup.</p> <img src="http://www.google-analytics.com/collect?v=1&t=pageview&dl=http%3A%2F%2Fjonrohan.codes%2Fatom%2Ffieldnotes%2Fa-big-update-to-this-site&ul=en-us&de=UTF-8&dt=A%20big%20update%20to%20this%20site&cid=198907588.1430708348&tid=UA-543420-18"> http://jonrohan.codes/fieldnotes/scale-box-by-ratio Scale a block-level element in CSS 2015-05-02T00:00:00-07:00 2015-05-02T00:00:00-07:00 Sometimes you want to scale an iframe window like an image, but the iframe doesn't behave that way. A good example is when you embed a youtube video in your site. &copy; Jon Rohan 2015. All rights reserved. <p>Sometimes you want to scale an iframe window like an image, but the iframe doesn’t behave that way. A good example is when you embed a youtube video in your site.</p> <figure class="post-image image-style-smallest"> <img class="zoom-image js-zoom-image" src="http://jonrohan.codes/assets/images/posts/scaling.gif" /> <figcaption class="image-caption">"Chewie, we're home"</figcaption> </figure> <p>A threw together a <a href="http://codepen.io/jonrohan/full/PqqdBz/">little demo</a> on codepen showing how to accomplish this with only CSS.</p> <p>If you are building a responsive site like a news site, or blog. You will probably include some video content, and when you do you will want to have the video scale properly with the container of the site.</p> <hr /> <h4 id="breaking-it-down">Breaking it down</h4> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;iframe</span> <span class="na">width=</span><span class="s">"560"</span> <span class="na">height=</span><span class="s">"315"</span> <span class="na">src=</span><span class="s">"https://www.youtube.com/embed/wCc2v7izk8w?rel=0&amp;amp;showinfo=0"</span> <span class="na">frameborder=</span><span class="s">"0"</span> <span class="na">allowfullscreen</span><span class="nt">&gt;&lt;/iframe&gt;</span></code></pre></div> <p>First thing you’ll have is a video, let’s say from youtube. By itself, the video will not scale. The actual video inside the <code>&lt;iframe&gt;</code> is scaling to fit the iframe as best it can. But the iframe doesn’t have the knowledge of the size of the video inside it. That’s why you typically set the width and height on the iframe.</p> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"scale-video"</span><span class="nt">&gt;</span> <span class="nt">&lt;iframe</span> <span class="na">width=</span><span class="s">"560"</span> <span class="na">height=</span><span class="s">"315"</span> <span class="na">src=</span><span class="s">"https://www.youtube.com/embed/wCc2v7izk8w?rel=0&amp;amp;showinfo=0"</span> <span class="na">frameborder=</span><span class="s">"0"</span> <span class="na">allowfullscreen</span><span class="nt">&gt;&lt;/iframe&gt;</span> <span class="nt">&lt;/div&gt;</span></code></pre></div> <p>Wrap the video in a <code>&lt;div&gt;</code>. We’re gonna be using this as the scaling container. The key is to add a <code>padding-top: n%</code> with a <code>width: 100%;</code> to the container. This makes the container scale when the parent container is scaled. For a 16:9 video size, you would calculate <code>(9 / 16 * 100) = 56.25</code></p> <div class="highlight"><pre><code class="language-css" data&#45;lang="css"><span class="nc">.scale-video</span> <span class="p">{</span> <span class="nl">width</span><span class="p">:</span> <span class="m">100%</span><span class="p">;</span> <span class="nl">padding-top</span><span class="p">:</span> <span class="m">56.25%</span><span class="p">;</span> <span class="nl">position</span><span class="p">:</span> <span class="nb">relative</span><span class="p">;</span> <span class="p">}</span></code></pre></div> <p>Then all you need to do is absolutely position the iframe and have it scale to fill the parent container.</p> <div class="highlight"><pre><code class="language-css" data&#45;lang="css"><span class="nc">.scale-video</span> <span class="nt">iframe</span> <span class="p">{</span> <span class="nl">position</span><span class="p">:</span> <span class="nb">absolute</span><span class="p">;</span> <span class="nl">top</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span> <span class="nl">left</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span> <span class="nl">width</span><span class="p">:</span> <span class="m">100%</span><span class="p">;</span> <span class="nl">height</span><span class="p">:</span> <span class="m">100%</span><span class="p">;</span> <span class="p">}</span></code></pre></div> <img src="http://www.google-analytics.com/collect?v=1&t=pageview&dl=http%3A%2F%2Fjonrohan.codes%2Fatom%2Ffieldnotes%2Fscale-box-by-ratio&ul=en-us&de=UTF-8&dt=Scale%20a%20block-level%20element%20in%20CSS&cid=198907588.1430708348&tid=UA-543420-18"> http://jonrohan.codes/fieldnotes/primer-css-styleguide Primer CSS Styleguide 2015-03-23T00:00:00-07:00 2015-03-23T00:00:00-07:00 We recently open sourced Primer, because we wanted to be transparent with our styleguide and if anyone could get any use out of it we would like to share. The toolkit isn’t meant to be a full fledged CSS framework like Bootstrap. &copy; Jon Rohan 2015. All rights reserved. <p><a href="http://primercss.io/">Primer</a> is GitHub’s internal styleguide and css toolkit. It is used as a way to share buttons, forms, grids, tooltips and more with all the internal and external properties of GitHub. For example <a href="https://gist.github.com/">Gist</a>, <a href="https://enterprise.github.com/">Enterprise</a> and <a href="https://github.com/">GitHub.com</a>.</p> <p>We recently open sourced Primer, because we wanted to be transparent with our styleguide and if anyone could get any use out of it we would like to share. The toolkit isn’t meant to be a full fledged CSS framework like Bootstrap.</p> <hr /> <h3 id="lets-build-a-toolkit">Lets build a toolkit</h3> <blockquote> <p>I’ve been copying and pasting the stylesheets from github/github for new gist.</p> </blockquote> <p>In 2012 it started becoming more apparent that we needed a toolkit that we could share between our other github properties. Until that year gist was and always had been a separate rails app combined with github.com.</p> <p>Gist shared everything with github, because it lived in the same codebase. We <a href="https://github.com/blog/1276-welcome-to-a-new-gist">were working</a> on a big initiative to upgrade the whole app and separate it into it’s own codebase.</p> <p>During the process I was talking with the designer/developer working on the front-end, and we were tossing around the idea of building something to make it easier to share common styles (buttons, forms, text, syntax) between the properties. <em>“How have you been using the styles?”</em> I said. <em>“I’ve been copying and pasting the stylesheets from github/github for new gist.”</em> o_O <em>“Ok, I’m going to create a repo tomorrow, lets start sharing stuff.”</em></p> <figure class="post-image image-style-full"> <div class="video"> <iframe src="https://player.vimeo.com/video/123020478?color=ffffff&amp;portrait=0" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe> </div> <figcaption class="image-caption">I performed a slam poem about <a href="http://primercss.io/">primercss.io</a> at a GitHub summit on November 11, 2012. Sorry about the first half of the video being blacked out.</figcaption> </figure> <hr /> <h3 id="lets-open-source-it">Lets open source it</h3> <p>Primer went through a few iterations. It started as a rails gem, because bower.js wasn’t fully realized at the time. It wasn’t until recently that the work was beginning to look clean polished and ready for others to read and use.</p> <p>A lot of what primer is today, is due to the hard work <a href="http://markdotto.com/2015/03/23/introducing-primer/">@mdo</a> has been putting into it. He got us ready to release it.</p> <p>Check out the <a href="https://github.com/primer/primer">source code</a> or browse through the <a href="http://primercss.io/">docs</a> on GitHub.</p> <img src="http://www.google-analytics.com/collect?v=1&t=pageview&dl=http%3A%2F%2Fjonrohan.codes%2Fatom%2Ffieldnotes%2Fprimer-css-styleguide&ul=en-us&de=UTF-8&dt=Primer%20CSS%20Styleguide&cid=198907588.1430708348&tid=UA-543420-18"> http://jonrohan.codes/fieldnotes/semantic-css-class-naming Class Naming: Semantic Approach 2012-01-20T00:00:00-08:00 2012-01-20T00:00:00-08:00 With the rise of web standards we have seen the rise of the semantic web. This applies to the HTML elements selected as well as the class names chosen for the HTML. When choosing semantic elements and class names you want to pick a name considering the function or meaning of the element as it is on your page, not the position or style of the element. &copy; Jon Rohan 2012. All rights reserved. <h3 id="the-semantic-web">The Semantic Web</h3> <p>With the rise of web standards we have seen the rise of the semantic web. This applies to the HTML elements selected as well as the class names chosen for the HTML. When choosing semantic elements and class names you want to pick a name considering the function or meaning of the element as it is on your page, not the position or style of the element.</p> <h3 id="the-meaning">The Meaning</h3> <p>What exactly am I talking about “meaning” or “function”? This means that when picking a name you want to pick one regardless of where it is, only what it contains or what you’re using it for.</p> <p>example: Imagine we have some markup that represents a search result</p> <p><strong>THE BAD WAY</strong></p> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"search-result"</span><span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"search-result-large-header"</span><span class="nt">&gt;&lt;a</span> <span class="na">href=</span><span class="s">""</span><span class="nt">&gt;</span>My Search Result<span class="nt">&lt;/a&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"search-result-gray-description"</span><span class="nt">&gt;</span>This is the best search result<span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"bottom-search-result-info"</span><span class="nt">&gt;&lt;a</span> <span class="na">href=</span><span class="s">""</span><span class="nt">&gt;</span>1 comment<span class="nt">&lt;/a&gt;</span> <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">""</span><span class="nt">&gt;</span>12 views<span class="nt">&lt;/a&gt;&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span></code></pre></div> <p>There is a lot of things wrong with this. To name a few, there are too many unnecessary DIV’s; The class names have style and position specific properties; Since this is a search result, multiples of these makes me want to pass out.</p> <p><strong>THE SEMANTIC WAY</strong></p> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"search-result"</span><span class="nt">&gt;</span> <span class="nt">&lt;h3&gt;&lt;a</span> <span class="na">href=</span><span class="s">""</span><span class="nt">&gt;</span>My Search Result<span class="nt">&lt;/a&gt;&lt;/h3&gt;</span> <span class="nt">&lt;p&gt;</span>This is the best search result<span class="nt">&lt;/p&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"meta"</span><span class="nt">&gt;&lt;a</span> <span class="na">href=</span><span class="s">""</span><span class="nt">&gt;</span>1 comment<span class="nt">&lt;/a&gt;</span> <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">""</span><span class="nt">&gt;</span>12 views<span class="nt">&lt;/a&gt;&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span></code></pre></div> <p>using the semantic way, I don’t need as many divs and when I do use a div I try to pick a name that describes what I’m putting in the tag. I’m calling it “meta” because that info is the meta data for that search result. It has nothing to do with the bottom, and it doesn’t need “search-result” in the name because it is a child of search-result anyways.</p> <p>I also selected h3 and p elements because an h3 refers to a heading, which the title of the search result is certainly a heading, and p, because this is a paragraph of text which describes the search result.</p> <p>You may ask, “What’s the big deal? It’s all gonna render the same in the browser anyways?” The benefits for semantic code translate into faster development time, javascript traversal becomes easier and it makes me happy. :)</p> <p>Some more bad names that I have witnessed: <code>.padding5px</code>, <code>.topBorderGreen</code>, <code>.redErrorText</code>. What happens if you want a padding of 4px, or suddenly the border becomes blue, or if the error text becomes yellow. Then you’ll need to go back through all your html and re-name classes. May I suggest names like <code>.content</code>, <code>.important</code>, or <code>.error</code>.</p> <img src="http://www.google-analytics.com/collect?v=1&t=pageview&dl=http%3A%2F%2Fjonrohan.codes%2Fatom%2Ffieldnotes%2Fsemantic-css-class-naming&ul=en-us&de=UTF-8&dt=Class%20Naming%3A%20Semantic%20Approach&cid=198907588.1430708348&tid=UA-543420-18"> http://jonrohan.codes/fieldnotes/list-git-contributors List of Git Contributors 2012-01-15T00:00:00-08:00 2012-01-15T00:00:00-08:00 Get a list of git contributors and sort by number of commits. &copy; Jon Rohan 2012. All rights reserved. <p>This is one of my favorite Git commands, I think mainly because I like to see where I am in a list of contributors.</p> <div class="highlight"><pre><code class="language-sh" data&#45;lang="sh">git shortlog -s -n</code></pre></div> <p>This produces an ordered list of contributors to a Git repo, based on number of commits. Like this:</p> <div class="highlight"><pre><code class="language-sh" data&#45;lang="sh">450 Jon Rohan 230 Jim Smith 100 Joe Jones 2 Fred Smith</code></pre></div> <p>Go ahead and try it on your repo.</p> <img src="http://www.google-analytics.com/collect?v=1&t=pageview&dl=http%3A%2F%2Fjonrohan.codes%2Fatom%2Ffieldnotes%2Flist-git-contributors&ul=en-us&de=UTF-8&dt=List%20of%20Git%20Contributors&cid=198907588.1430708348&tid=UA-543420-18"> http://jonrohan.codes/fieldnotes/clear-fixes Clear Fixes 2011-01-20T00:00:00-08:00 2011-01-20T00:00:00-08:00 There is a common problem in front end engineering where, when you float an element it is actually removed from it's parents' flow. This can cause the elements below the floating element to run into the floating elements. &copy; Jon Rohan 2011. All rights reserved. <p>There is a common problem in front end engineering where, when you float an element it is actually removed from it’s parents’ flow. This can cause the elements below the floating element to run into the floating elements. Like below. The green box is floating and it’s parent has the red border. The blue box is below the red border box.</p> <div style="overflow:hidden;"> <div style="border:1px solid red;"> <div style="background-color:green;float:left;width:20px;height:20px;"></div> </div> <div style="background-color:blue;width:50px;height:50px;"></div> </div> <p>There are a few solutions to this, but I have heard of a new solution that I don’t think is widely published. <code>overflow:hidden;</code></p> <p>First lets go through the other solutions.</p> <h3 id="clearboth">clear:both</h3> <p>This is the most common that I’ve found, and the one I’ve used the most. The style in this code is inline, but typically you can create a class called .clear and apply these styles.</p> <div style="border:1px solid red;"> <div style="background-color:green;float:left;width:20px;height:20px;"></div> <div style="clear:both;"></div> </div> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;div</span> <span class="na">style=</span><span class="s">"border:1px solid red;"</span><span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">style=</span><span class="s">"background-color:green;float:left;width:20px;height:20px;"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">style=</span><span class="s">"clear:both;"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span></code></pre></div> <p>In this example you place another element at the end of the child elements in the red border box. This last element gets applied the style <code>clear:both</code> which disallows any floating elements on either side of it.</p> <p>This can run into problems if you have multi-column layouts this can clear the content in the other columns</p> <h3 id="clearfix-hack">clearfix hack</h3> <p>This is essentially taking the previous method and adding to it. I don’t use this very often.</p> <div class="highlight"><pre><code class="language-css" data&#45;lang="css"><span class="nc">.clearfix</span><span class="nd">:after</span> <span class="p">{</span> <span class="nl">content</span><span class="p">:</span> <span class="s1">"."</span><span class="p">;</span> <span class="nl">display</span><span class="p">:</span> <span class="nb">block</span><span class="p">;</span> <span class="nl">clear</span><span class="p">:</span> <span class="nb">both</span><span class="p">;</span> <span class="nl">visibility</span><span class="p">:</span> <span class="nb">hidden</span><span class="p">;</span> <span class="nl">line-height</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span> <span class="nl">height</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span> <span class="p">}</span> <span class="nc">.clearfix</span> <span class="p">{</span> <span class="nl">display</span><span class="p">:</span> <span class="n">inline-block</span><span class="p">;</span> <span class="p">}</span> <span class="nt">html</span><span class="o">[</span><span class="nt">xmlns</span><span class="o">]</span> <span class="nc">.clearfix</span> <span class="p">{</span> <span class="nl">display</span><span class="p">:</span> <span class="nb">block</span><span class="p">;</span> <span class="p">}</span> <span class="o">*</span> <span class="nt">html</span> <span class="nc">.clearfix</span> <span class="p">{</span> <span class="nl">height</span><span class="p">:</span> <span class="m">1%</span><span class="p">;</span> <span class="p">}</span></code></pre></div> <div style="border:1px solid red;line-height:20px;"> <div style="background-color:green;float:left;width:20px;height:20px;"></div> <div class="clearfix"></div> </div> <div style="background-color:blue;width:50px;height:50px;"></div> <p>This method works but it feels like a lot of overhead, and now my CSS is non-standard.</p> <h3 id="overflowhidden">overflow:hidden</h3> <p>In this method you apply overflow:hidden to the parent element which is the red border box. And that’s it!</p> <div style="border:1px solid red;overflow:hidden;"> <div style="background-color:green;float:left;width:20px;height:20px;"></div> </div> <div style="background-color:blue;width:50px;height:50px;"></div> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;div</span> <span class="na">style=</span><span class="s">"border:1px solid red;overflow:hidden;"</span><span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">style=</span><span class="s">"background-color:green;float:left;width:20px;height:20px;"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">style=</span><span class="s">"background-color:blue;width:50px;height:50px;"</span><span class="nt">&gt;&lt;/div&gt;</span></code></pre></div> <p>Pretty simple! And it doesn’t require extra div tags. I’ve tested this in IE7, Firefox, Safari, and Chrome works in all.</p> <img src="http://www.google-analytics.com/collect?v=1&t=pageview&dl=http%3A%2F%2Fjonrohan.codes%2Fatom%2Ffieldnotes%2Fclear-fixes&ul=en-us&de=UTF-8&dt=Clear%20Fixes&cid=198907588.1430708348&tid=UA-543420-18"> http://jonrohan.codes/fieldnotes/creating-triangles-in-css Creating Triangles in CSS 2011-01-18T00:00:00-08:00 2011-01-18T00:00:00-08:00 I've come across a few techniques and tips in my career, while working at my last gig a co-worker pointed me to this technique. I believe this was originally discovered by the legendary Eric Meyer, but I couldn't find much documentation about it on the web. Which is why I am sharing it here. &copy; Jon Rohan 2011. All rights reserved. <p>I’ve come across a few techniques and tips in my career, while working at my last gig a co-worker pointed me to this technique. I believe this was originally discovered by the legendary Eric Meyer, but I couldn’t find much documentation about it on the web. Which is why I am sharing it here.</p> <figure class="post-image image-style-bleed"> <div class="image-wrap"> <img src="http://jonrohan.codes/assets/images/posts/96046762253.jpg" /></div> </figure> <h3 id="the-details">The details</h3> <p>Few people realize when a browser draws the borders, it draws them at angles. This technique takes advantage of that. One side of the border is colored for the color of the arrow, and the rest are transparent. Then you set the width of the border to something large, the ones above are 20px. To demonstrate here is a div with all sides colored.</p> <h5 id="example">Example</h5> <div class="docs-example clearfix"><div class="css-arrow-multicolor"></div> <style type="text/css"> .css-arrow-multicolor { border-color: red green blue orange; border-style:solid; border-width:20px; width:0; height:0; } </style></div> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"css-arrow-multicolor"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;style </span><span class="na">type=</span><span class="s">"text/css"</span><span class="nt">&gt;</span> <span class="nc">.css-arrow-multicolor</span> <span class="p">{</span> <span class="nl">border-color</span><span class="p">:</span> <span class="no">red</span> <span class="no">green</span> <span class="no">blue</span> <span class="no">orange</span><span class="p">;</span> <span class="nl">border-style</span><span class="p">:</span><span class="nb">solid</span><span class="p">;</span> <span class="nl">border-width</span><span class="p">:</span><span class="m">20px</span><span class="p">;</span> <span class="nl">width</span><span class="p">:</span><span class="m">0</span><span class="p">;</span> <span class="nl">height</span><span class="p">:</span><span class="m">0</span><span class="p">;</span> <span class="p">}</span> <span class="nt">&lt;/style&gt;</span></code></pre></div> <p>As you can see there are triangles hidden in that square. These triangles are right triangles with a little tweaking with the border sizes you can get acute triangles.</p> <h5 id="example-1">Example</h5> <div class="docs-example clearfix"><div class="css-arrow-acute"></div> <style type="text/css"> .css-arrow-acute { border-color: red green blue orange; border-style:solid; border-width:25px 10px 15px 30px; width:0; height:0; } </style></div> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"css-arrow-acute"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;style </span><span class="na">type=</span><span class="s">"text/css"</span><span class="nt">&gt;</span> <span class="nc">.css-arrow-acute</span> <span class="p">{</span> <span class="nl">border-color</span><span class="p">:</span> <span class="no">red</span> <span class="no">green</span> <span class="no">blue</span> <span class="no">orange</span><span class="p">;</span> <span class="nl">border-style</span><span class="p">:</span><span class="nb">solid</span><span class="p">;</span> <span class="nl">border-width</span><span class="p">:</span><span class="m">25px</span> <span class="m">10px</span> <span class="m">15px</span> <span class="m">30px</span><span class="p">;</span> <span class="nl">width</span><span class="p">:</span><span class="m">0</span><span class="p">;</span> <span class="nl">height</span><span class="p">:</span><span class="m">0</span><span class="p">;</span> <span class="p">}</span> <span class="nt">&lt;/style&gt;</span></code></pre></div> <p>With a little creativity and tweaking there are lots of shapes that can be made.</p> <h5 id="example-border-style-dotted">Example <code>border-style: dotted;</code></h5> <div class="docs-example clearfix"><div class="css-arrow-multicolor" style="border-style:dotted;"></div></div> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"css-arrow-multicolor"</span> <span class="na">style=</span><span class="s">"border-style:dotted;"</span><span class="nt">&gt;&lt;/div&gt;</span></code></pre></div> <h5 id="example-border-style-dashed">Example <code>border-style: dashed;</code></h5> <div class="docs-example clearfix"><div class="css-arrow-multicolor" style="border-style:dashed;"></div></div> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"css-arrow-multicolor"</span> <span class="na">style=</span><span class="s">"border-style:dashed;"</span><span class="nt">&gt;&lt;/div&gt;</span></code></pre></div> <h5 id="example-border-style-outset">Example <code>border-style: outset;</code></h5> <div class="docs-example clearfix"><div class="css-arrow-multicolor" style="border-style:outset;"></div></div> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"css-arrow-multicolor"</span> <span class="na">style=</span><span class="s">"border-style:outset;"</span><span class="nt">&gt;&lt;/div&gt;</span></code></pre></div> <h5 id="example-border-style-inset">Example <code>border-style: inset;</code></h5> <div class="docs-example clearfix"><div class="css-arrow-multicolor" style="border-style:inset;"></div></div> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"css-arrow-multicolor"</span> <span class="na">style=</span><span class="s">"border-style:inset;"</span><span class="nt">&gt;&lt;/div&gt;</span></code></pre></div> <h5 id="example-border-style-ridge">Example <code>border-style: ridge;</code></h5> <div class="docs-example clearfix"><div class="css-arrow-multicolor" style="border-style:ridge;"></div></div> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"css-arrow-multicolor"</span> <span class="na">style=</span><span class="s">"border-style:ridge;"</span><span class="nt">&gt;&lt;/div&gt;</span></code></pre></div> <h5 id="example-border-style-groove">Example <code>border-style: groove;</code></h5> <div class="docs-example clearfix"><div class="css-arrow-multicolor" style="border-style:groove;"></div></div> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"css-arrow-multicolor"</span> <span class="na">style=</span><span class="s">"border-style:groove;"</span><span class="nt">&gt;&lt;/div&gt;</span></code></pre></div> <h5 id="example-border-style-double">Example <code>border-style: double;</code></h5> <div class="docs-example clearfix"><div class="css-arrow-multicolor" style="border-style:double;"></div></div> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"css-arrow-multicolor"</span> <span class="na">style=</span><span class="s">"border-style:double;"</span><span class="nt">&gt;&lt;/div&gt;</span></code></pre></div> <p>Now for application:</p> <h5 id="demo">Demo</h5> <div class="docs-example clearfix"><div class="chat-bubble"> Buongiorno! <div class="chat-bubble-arrow-border"></div> <div class="chat-bubble-arrow"></div> </div></div> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"chat-bubble"</span><span class="nt">&gt;</span> Buongiorno! <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"chat-bubble-arrow-border"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"chat-bubble-arrow"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span></code></pre></div> <p>This is a classic chat bubble, no images used.</p> <p>This technique doesn’t work in ie6 as is, mainly because ie6 doesn’t allow transparent borders, but there is a fix for that. What you need to do is give the “transparent” sides a completely different color like pink and then use filter: chroma to turn that color transparent.</p> <div class="highlight"><pre><code class="language-css" data&#45;lang="css"><span class="c">/* IE6 */</span> <span class="nc">.chat-bubble-arrow</span> <span class="p">{</span> <span class="py">_border-left-color</span><span class="p">:</span> <span class="no">pink</span><span class="p">;</span> <span class="py">_border-bottom-color</span><span class="p">:</span> <span class="no">pink</span><span class="p">;</span> <span class="py">_border-right-color</span><span class="p">:</span> <span class="no">pink</span><span class="p">;</span> <span class="py">_filter</span><span class="p">:</span> <span class="n">chroma</span><span class="p">(</span><span class="n">color</span><span class="err">=</span><span class="no">pink</span><span class="p">);</span> <span class="p">}</span></code></pre></div> <img src="http://www.google-analytics.com/collect?v=1&t=pageview&dl=http%3A%2F%2Fjonrohan.codes%2Fatom%2Ffieldnotes%2Fcreating-triangles-in-css&ul=en-us&de=UTF-8&dt=Creating%20Triangles%20in%20CSS&cid=198907588.1430708348&tid=UA-543420-18"> http://jonrohan.codes/fieldnotes/classes-and-inheritance Classes and Inheritance 2010-10-15T00:00:00-07:00 2010-10-15T00:00:00-07:00 Object oriented JavaScript is everywhere today, and its the type of thing that takes a developer from someone tinkering with JavaScript on the path to becoming a JavaScript ninja. &copy; Jon Rohan 2010. All rights reserved. <p>Object oriented JavaScript is everywhere today, and its the type of thing that takes a developer from someone tinkering with JavaScript on the path to becoming a JavaScript ninja. In this post I’m gonna discuss the basics of creating a JavaScript class, and a subclass which inherits methods from the superclass.</p> <h3>A JavaScript Class</h3> <p>Let’s start out with a basic class. The Person class has one method getName, when you create a new instance of the Person class you will pass in the Person’s name.</p> <h4>The Person class</h4> <div class="highlight"><pre><code class="language-js" data&#45;lang="js"><span class="kd">function</span> <span class="nx">Person</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span> <span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="nx">name</span><span class="p">;</span> <span class="p">}</span> <span class="nx">Person</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">getName</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">;</span> <span class="p">}</span></code></pre></div> <p>In the above example I created a Person class with a name attribute and a function to retrieve the name. Now I’ll create a new person, “Jon Rohan”.</p> <div class="highlight"><pre><code class="language-js" data&#45;lang="js"><span class="kd">var</span> <span class="nx">p</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">(</span><span class="s2">"Jon Rohan"</span><span class="p">);</span> <span class="c1">// output: Jon Rohan</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">p</span><span class="p">.</span><span class="nx">getName</span><span class="p">());</span></code></pre></div> <p>The &lt;pre&gt;p&lt;/pre&gt; is a new Person with the name “Jon Rohan”, when I log to the console the result of &lt;pre&gt;p.getName()&lt;/pre&gt; it returns “Jon Rohan”.</p> <h3>Prototype Chain</h3> <p>Now we bring in the prototype chain. The chain is like an inheritance chain. Developer inherits → from Person. We are defining a Developer as a Person, cause developers are people too. ;-) The developer takes the name attribute like Person, and an array of skills. The first line of the Developer class is to &lt;pre&gt;call&lt;/pre&gt; the Person class. This calls the Person’s constructor. The Developer class also has a new method getSkills, because a Person is too general to have skills, but as a Developer, there are skills that they have.</p> <p>We also need to set Developer.prototype to the Person’s prototype, by creating a new Person. Now we set the Developer’s constructor to the Developer. And we have successfully created a prototype chain from Developer to Person.</p> <h4>The Developer Class</h4> <div class="highlight"><pre><code class="language-js" data&#45;lang="js"><span class="kd">function</span> <span class="nx">Developer</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">skills</span><span class="p">)</span> <span class="p">{</span> <span class="nx">Person</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">name</span><span class="p">);</span> <span class="c1">// we call the Person constructor since it's the superclass</span> <span class="k">this</span><span class="p">.</span><span class="nx">skills</span> <span class="o">=</span> <span class="nx">skills</span><span class="p">;</span> <span class="k">this</span><span class="p">.</span><span class="nx">getSkills</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">skills</span><span class="p">;</span> <span class="p">};</span> <span class="p">}</span> <span class="nx">Developer</span><span class="p">.</span><span class="nx">prototype</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Person</span><span class="p">();</span> <span class="nx">Developer</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">constructor</span> <span class="o">=</span> <span class="nx">Developer</span><span class="p">;</span></code></pre></div> <p>Now we’ll create a new Developer, with the name “Jon Rohan” and skills [“Javascript”, “HTML”, “CSS”]. When we create the new developer, he’ll also have the getName method inherited from the Person class, and the getSkills method from the Developer class.</p> <div class="highlight"><pre><code class="language-js" data&#45;lang="js"><span class="kd">var</span> <span class="nx">d</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Developer</span><span class="p">(</span><span class="s2">"Jon Rohan"</span><span class="p">,[</span><span class="s2">"Javascript"</span><span class="p">,</span> <span class="s2">"HTML"</span><span class="p">,</span> <span class="s2">"CSS"</span><span class="p">]);</span> <span class="c1">// output: Jon Rohan</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">d</span><span class="p">.</span><span class="nx">getName</span><span class="p">());</span> <span class="c1">// output: Javascript, HTML, CSS</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">d</span><span class="p">.</span><span class="nx">getSkills</span><span class="p">().</span><span class="nx">join</span><span class="p">(</span><span class="s2">", "</span><span class="p">));</span></code></pre></div> <p>This is the basic ideas behind Object Oriented Programming in JavaScript, I’ve only really scratched the surface in JavaScript OOP.</p> <img src="http://www.google-analytics.com/collect?v=1&t=pageview&dl=http%3A%2F%2Fjonrohan.codes%2Fatom%2Ffieldnotes%2Fclasses-and-inheritance&ul=en-us&de=UTF-8&dt=Classes%20and%20Inheritance&cid=198907588.1430708348&tid=UA-543420-18"> http://jonrohan.codes/fieldnotes/text-rotation Text Rotation 2010-10-10T00:00:00-07:00 2010-10-10T00:00:00-07:00 What I wanted to make was a clock. The basis of this project is using the -webkit-transform:rotate(0deg); css property. This allows you to rotate any object 360 degrees. I began to wonder, if I have a line, and I setup a javascript timer can I rotate it every second? &copy; Jon Rohan 2010. All rights reserved. <p>I recently saw an <a href="http://snook.ca/archives/html_and_css/css-text-rotation">article</a> on CSS text rotation on the internets and decided to try my own experiment.</p> <p>What I wanted to make was a clock. The basis of this project is using the -webkit-transform:rotate(0deg); css property. This allows you to rotate any object 360 degrees. I began to wonder, if I have a line, and I setup a javascript timer can I rotate it every second?</p> <p data&#45;height="309" data&#45;theme-id="14162" data&#45;slug-hash="VYoqwj" data&#45;default-tab="result" data&#45;user="jonrohan" class="codepen">See the Pen <a href="http://codepen.io/jonrohan/pen/VYoqwj/">VYoqwj</a> by Jon Rohan (<a href="http://codepen.io/jonrohan">@jonrohan</a>) on <a href="http://codepen.io">CodePen</a>.</p> <p>The design is inspired by @<a href="https://twitter.com/eston">eston</a>’s <a href="http://www.flickr.com/photos/eston/3799958463/">Sarai</a> desktop.</p> <p>This clock won’t work in IE. There is an IE rotate property, but it only rotates at 0, 90, 180, 270. That won’t work for this clock, because we need more than only four angles. Here’s the IE rotate property anyways</p> <div class="highlight"><pre><code class="language-css" data&#45;lang="css"><span class="nt">filter</span><span class="o">:</span> <span class="nt">progid</span><span class="nd">:DXImageTransform</span><span class="nc">.Microsoft.BasicImage</span><span class="o">(</span><span class="nt">rotation</span><span class="o">=</span><span class="nt">3</span><span class="o">);</span></code></pre></div> <h3>How did I do it?</h3> <p>I started with an external div for the clock. Giving it a width and height of 100px and position relative. This is to position the clock hands.</p> <div class="highlight"><pre><code class="language-css" data&#45;lang="css"><span class="nf">#clock</span> <span class="p">{</span> <span class="nl">width</span><span class="p">:</span><span class="m">208px</span><span class="p">;</span> <span class="nl">height</span><span class="p">:</span><span class="m">208px</span><span class="p">;</span> <span class="nl">position</span><span class="p">:</span><span class="nb">relative</span><span class="p">;</span> <span class="p">}</span></code></pre></div> <p>After getting the clock, I need a second hand, a minute hand and an hour hand. Originally I used a side border on the hands, but realized that the rotate property rotates the object at it’s center, and not at it’s end. To create the hands, I gave them a border top equal to the length of the hand, then a height to offset the border, and some margin to vertically align.</p> <div class="highlight"><pre><code class="language-html" data&#45;lang="html"><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"clock"</span><span class="nt">&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"ten_min"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(0deg);-webkit-transform:rotate(0deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"ten_min"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(30deg);-webkit-transform:rotate(30deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"ten_min"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(60deg);-webkit-transform:rotate(60deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"ten_min"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(90deg);-webkit-transform:rotate(90deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"ten_min"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(120deg);-webkit-transform:rotate(120deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"ten_min"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(150deg);-webkit-transform:rotate(150deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(0deg);-webkit-transform:rotate(0deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(6deg);-webkit-transform:rotate(6deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(12deg);-webkit-transform:rotate(12deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(18deg);-webkit-transform:rotate(18deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(24deg);-webkit-transform:rotate(24deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(36deg);-webkit-transform:rotate(36deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(42deg);-webkit-transform:rotate(42deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(48deg);-webkit-transform:rotate(48deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(54deg);-webkit-transform:rotate(54deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(66deg);-webkit-transform:rotate(66deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(72deg);-webkit-transform:rotate(72deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(78deg);-webkit-transform:rotate(78deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(84deg);-webkit-transform:rotate(84deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(96deg);-webkit-transform:rotate(96deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(102deg);-webkit-transform:rotate(102deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(108deg);-webkit-transform:rotate(108deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(114deg);-webkit-transform:rotate(114deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(126deg);-webkit-transform:rotate(126deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(132deg);-webkit-transform:rotate(132deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(138deg);-webkit-transform:rotate(138deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(144deg);-webkit-transform:rotate(144deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(156deg);-webkit-transform:rotate(156deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(162deg);-webkit-transform:rotate(162deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(168deg);-webkit-transform:rotate(168deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"min_mark"</span> <span class="na">style=</span><span class="s">"-moz-transform:rotate(174deg);-webkit-transform:rotate(174deg);"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"sec"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"min"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"hour"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="nt">&lt;/div&gt;</span></code></pre></div> <div class="highlight"><pre><code class="language-css" data&#45;lang="css"><span class="nf">#sec</span> <span class="p">{</span> <span class="nl">-moz-transform</span><span class="p">:</span> <span class="n">rotate</span><span class="p">(</span><span class="m">0deg</span><span class="p">);</span> <span class="nl">-webkit-transform</span><span class="p">:</span> <span class="n">rotate</span><span class="p">(</span><span class="m">0deg</span><span class="p">);</span> <span class="nl">border-top</span><span class="p">:</span><span class="m">104px</span> <span class="nb">solid</span> <span class="m">#353535</span><span class="p">;</span> <span class="nl">height</span><span class="p">:</span><span class="m">104px</span><span class="p">;</span> <span class="nl">left</span><span class="p">:</span> <span class="m">104px</span><span class="p">;</span> <span class="nl">position</span><span class="p">:</span><span class="nb">absolute</span><span class="p">;</span> <span class="nl">top</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span> <span class="nl">width</span><span class="p">:</span><span class="m">2px</span><span class="p">;</span> <span class="p">}</span> <span class="nf">#min</span> <span class="p">{</span> <span class="nl">-moz-transform</span><span class="p">:</span> <span class="n">rotate</span><span class="p">(</span><span class="m">45deg</span><span class="p">);</span> <span class="nl">-webkit-transform</span><span class="p">:</span> <span class="n">rotate</span><span class="p">(</span><span class="m">45deg</span><span class="p">);</span> <span class="nl">border-top</span><span class="p">:</span><span class="m">104px</span> <span class="nb">solid</span> <span class="m">#353535</span><span class="p">;</span> <span class="nl">height</span><span class="p">:</span><span class="m">104px</span><span class="p">;</span> <span class="nl">position</span><span class="p">:</span> <span class="nb">absolute</span><span class="p">;</span> <span class="nl">left</span><span class="p">:</span> <span class="m">102px</span><span class="p">;</span> <span class="nl">top</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span> <span class="nl">width</span><span class="p">:</span><span class="m">4px</span><span class="p">;</span> <span class="p">}</span> <span class="nf">#hour</span> <span class="p">{</span> <span class="nl">-moz-transform</span><span class="p">:</span><span class="n">rotate</span><span class="p">(</span><span class="m">180deg</span><span class="p">);</span> <span class="nl">-webkit-transform</span><span class="p">:</span><span class="n">rotate</span><span class="p">(</span><span class="m">180deg</span><span class="p">);</span> <span class="nl">border-top</span><span class="p">:</span> <span class="m">52px</span> <span class="nb">solid</span> <span class="nb">rgb</span><span class="p">(</span><span class="m">53</span><span class="p">,</span> <span class="m">53</span><span class="p">,</span> <span class="m">53</span><span class="p">);</span> <span class="nl">height</span><span class="p">:</span> <span class="m">52px</span><span class="p">;</span> <span class="nl">left</span><span class="p">:</span> <span class="m">104px</span><span class="p">;</span> <span class="nl">position</span><span class="p">:</span> <span class="nb">absolute</span><span class="p">;</span> <span class="nl">top</span><span class="p">:</span> <span class="m">52px</span><span class="p">;</span> <span class="nl">width</span><span class="p">:</span> <span class="m">5px</span><span class="p">;</span> <span class="p">}</span> <span class="nf">#clock</span> <span class="nc">.ten_min</span> <span class="p">{</span> <span class="nl">border-bottom</span><span class="p">:</span><span class="m">10px</span> <span class="nb">solid</span> <span class="m">#353535</span><span class="p">;</span> <span class="nl">border-top</span><span class="p">:</span><span class="m">10px</span> <span class="nb">solid</span> <span class="m">#353535</span><span class="p">;</span> <span class="nl">height</span><span class="p">:</span><span class="m">208px</span><span class="p">;</span> <span class="nl">left</span><span class="p">:</span><span class="m">104px</span><span class="p">;</span> <span class="nl">margin</span><span class="p">:</span><span class="m">0</span><span class="p">;</span> <span class="nl">position</span><span class="p">:</span><span class="nb">absolute</span><span class="p">;</span> <span class="nl">top</span><span class="p">:</span><span class="m">-9px</span><span class="p">;</span> <span class="nl">width</span><span class="p">:</span><span class="m">5px</span><span class="p">;</span> <span class="p">}</span> <span class="nf">#clock</span> <span class="nc">.min_mark</span> <span class="p">{</span> <span class="nl">border-bottom</span><span class="p">:</span><span class="m">5px</span> <span class="nb">solid</span> <span class="m">#353535</span><span class="p">;</span> <span class="nl">border-top</span><span class="p">:</span><span class="m">5px</span> <span class="nb">solid</span> <span class="m">#353535</span><span class="p">;</span> <span class="nl">height</span><span class="p">:</span><span class="m">208px</span><span class="p">;</span> <span class="nl">left</span><span class="p">:</span><span class="m">104px</span><span class="p">;</span> <span class="nl">margin</span><span class="p">:</span><span class="m">0</span><span class="p">;</span> <span class="nl">position</span><span class="p">:</span><span class="nb">absolute</span><span class="p">;</span> <span class="nl">top</span><span class="p">:</span><span class="m">-4px</span><span class="p">;</span> <span class="nl">width</span><span class="p">:</span><span class="m">1px</span><span class="p">;</span> <span class="p">}</span></code></pre></div> <p>The tick marks are also the lines, with a top and bottom border rotated 180 degrees.</p> <p>The javascript is a simple timer which updates the degrees of each hand based on the time.</p> <div class="highlight"><pre><code class="language-js" data&#45;lang="js"><span class="p">(</span><span class="kd">function</span><span class="p">(){</span> <span class="kd">var</span> <span class="nx">tick</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <span class="kd">var</span> <span class="nx">now</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">();</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#sec"</span><span class="p">).</span><span class="nx">css</span><span class="p">({</span><span class="s2">"-moz-transform"</span><span class="p">:</span><span class="s2">"rotate("</span> <span class="o">+</span> <span class="p">(</span><span class="nx">now</span><span class="p">.</span><span class="nx">getSeconds</span><span class="p">()</span> <span class="o">*</span> <span class="mi">6</span><span class="p">)</span> <span class="o">+</span> <span class="s2">"deg)"</span><span class="p">,</span> <span class="s2">"-webkit-transform"</span><span class="p">:</span><span class="s2">"rotate("</span> <span class="o">+</span> <span class="p">(</span><span class="nx">now</span><span class="p">.</span><span class="nx">getSeconds</span><span class="p">()</span> <span class="o">*</span> <span class="mi">6</span><span class="p">)</span> <span class="o">+</span> <span class="s2">"deg)"</span><span class="p">});</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#min"</span><span class="p">).</span><span class="nx">css</span><span class="p">({</span><span class="s2">"-moz-transform"</span><span class="p">:</span><span class="s2">"rotate("</span> <span class="o">+</span> <span class="p">(</span><span class="nx">now</span><span class="p">.</span><span class="nx">getMinutes</span><span class="p">()</span> <span class="o">*</span> <span class="mi">6</span><span class="p">)</span> <span class="o">+</span> <span class="s2">"deg)"</span><span class="p">,</span> <span class="s2">"-webkit-transform"</span><span class="p">:</span><span class="s2">"rotate("</span> <span class="o">+</span> <span class="p">(</span><span class="nx">now</span><span class="p">.</span><span class="nx">getMinutes</span><span class="p">()</span> <span class="o">*</span> <span class="mi">6</span><span class="p">)</span> <span class="o">+</span> <span class="s2">"deg)"</span><span class="p">});</span> <span class="nx">$</span><span class="p">(</span><span class="s2">"#hour"</span><span class="p">).</span><span class="nx">css</span><span class="p">({</span><span class="s2">"-moz-transform"</span><span class="p">:</span><span class="s2">"rotate("</span> <span class="o">+</span> <span class="p">(</span><span class="nx">now</span><span class="p">.</span><span class="nx">getHours</span><span class="p">()</span> <span class="o">*</span> <span class="mi">30</span><span class="p">)</span> <span class="o">+</span> <span class="s2">"deg)"</span><span class="p">,</span> <span class="s2">"-webkit-transform"</span><span class="p">:</span><span class="s2">"rotate("</span> <span class="o">+</span> <span class="p">(</span><span class="nx">now</span><span class="p">.</span><span class="nx">getHours</span><span class="p">()</span> <span class="o">*</span> <span class="mi">30</span><span class="p">)</span> <span class="o">+</span> <span class="s2">"deg)"</span><span class="p">});</span> <span class="p">};</span> <span class="nx">setInterval</span><span class="p">(</span><span class="nx">tick</span><span class="p">,</span><span class="mi">1000</span><span class="p">);</span> <span class="p">})();</span></code></pre></div> <img src="http://www.google-analytics.com/collect?v=1&t=pageview&dl=http%3A%2F%2Fjonrohan.codes%2Fatom%2Ffieldnotes%2Ftext-rotation&ul=en-us&de=UTF-8&dt=Text%20Rotation&cid=198907588.1430708348&tid=UA-543420-18"> http://jonrohan.codes/fieldnotes/dead-simple-git-workflow-for-agile-teams Dead Simple Git Workflow 2010-10-09T00:00:00-07:00 2010-10-09T00:00:00-07:00 Recently I have had the privilege to work with a few excellent small agile teams. With each team, they have their own process, which works best for them. And there's nothing wrong with that, a team should work in it's most effective way. But I came across a team recently that had a workflow that really impressed me. It is described as an extremely cool Git workflow. &copy; Jon Rohan 2010. All rights reserved. <p>Recently I have had the privilege to work with a few excellent small agile teams. With each team, they have their own process, which works best for them. And there’s nothing wrong with that, a team should work in it’s most effective way. But I came across a team recently that had a workflow that really impressed me. It is described as an extremely cool Git workflow.</p> <p>I can’t take credit for coming up with this workflow, but I’m gonna do my best to re-describe it here to be shared. The basis for this post comes from reinh.com’s posts <a href="http://reinh.com/blog/2009/03/02/a-git-workflow-for-agile-teams.html">A git workflow for Agile Teams</a> and <a href="http://reinh.com/blog/2008/08/27/hack-and-and-ship.html">Hack &amp;&amp; Ship</a>. Also this workflow pulls alot from Josh Susser’s post on the <a href="http://blog.hasmanythrough.com/2008/12/18/agile-git-and-the-story-branch-pattern">story branch pattern</a>.</p> <p>Let’s start by summarizing Josh’s post. In his post he describes a 7 step process that begins with <a href="http://www.pivotaltracker.com">Pivotal Tracker</a>. The idea being you locate a story on pivotal tracker, like a bug, or feature, or chore. Then you update your working master by pulling from the origin, and create a whole branch for that bug. Once you’ve fixed the bug, commited it to your branch, you then merge your branch with the master and push it all back up to the origin. Then remove the old branch and you’re done.</p> <p>That’s the basic workflow, but there is alot of automation that can be done. The first is the creation of the branch. This isn’t terribly long command ‘git checkout -b’ but I went ahead and created a shell alias ‘gcb’.</p> <div class="highlight"><pre><code class="language-sh" data&#45;lang="sh"><span class="nb">alias </span><span class="nv">gcb</span><span class="o">=</span><span class="s1">'git checkout -b'</span></code></pre></div> <p>Now when creating my branch for working on my bug I type</p> <div class="highlight"><pre><code class="language-sh" data&#45;lang="sh">gcb fix_ie_bug_Story123456</code></pre></div> <p>After creating my branch I would work on it normally doing ‘git commits’ when needed. Then when I’m ready comes the cool part. Hack &amp; Ship. Hack is what it’s called when you pull the lastest code from the origin and merge it with your branch. It’s a good idea to do this often, to keep everything up to date. To not have to type and remember the few commands for accomplishing this, I use a shell script.</p> <p>hack.sh</p> <div class="highlight"><pre><code class="language-sh" data&#45;lang="sh"><span class="c">#!/bin/sh -x</span> <span class="gp">\# </span>hack: Merge the latest changes from the master branch into your current branch <span class="nv">ref</span><span class="o">=</span><span class="k">$(</span>git symbolic-ref HEAD 2&gt; /dev/null<span class="k">)</span> <span class="o">||</span> <span class="nb">exit </span>0 <span class="nv">CURRENT</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">ref</span><span class="p">#refs/heads/</span><span class="k">}</span><span class="s2">"</span> git checkout master git pull origin master git checkout <span class="k">${</span><span class="nv">CURRENT</span><span class="k">}</span> git rebase master</code></pre></div> <p>When I am coding, I can at anytime type the command hack. And my branch is updated!</p> <p>Once I’ve finished my bug and I’m ready to send it back to the origin I do one more ‘hack’, make sure it’s all updated. And then I ship. This will checkout the master merge my branch with it, and then push it to the origin. Once again I use a shell script for this.</p> <p>ship.sh</p> <div class="highlight"><pre><code class="language-sh" data&#45;lang="sh"><span class="c">#!/bin/sh -x</span> <span class="gp">\# </span>Git workflow ship script from: http://reinh.com/blog/2008/08/27/hack-and-and-ship.html <span class="gp">\# </span>git name-rev is fail <span class="nv">ref</span><span class="o">=</span><span class="k">$(</span>git symbolic-ref HEAD 2&gt; /dev/null<span class="k">)</span> <span class="o">||</span> <span class="nb">exit </span>0 <span class="nv">CURRENT</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">ref</span><span class="p">#refs/heads/</span><span class="k">}</span><span class="s2">"</span> git checkout master git merge <span class="k">${</span><span class="nv">CURRENT</span><span class="k">}</span> git push origin master git checkout <span class="k">${</span><span class="nv">CURRENT</span><span class="k">}</span></code></pre></div> <p>Now I’m done with my bug, and there’s a script for that ‘dwf’. This will move me back to the master, and delete my old branch.</p> <p>dwf.sh</p> <div class="highlight"><pre><code class="language-sh" data&#45;lang="sh"><span class="c">#!/bin/sh -x</span> <span class="gp">\# </span>dwf, aka <span class="s2">"Done With Feature"</span> script: deletes current branch and puts you back on master <span class="nv">ref</span><span class="o">=</span><span class="k">$(</span>git symbolic-ref HEAD 2&gt; /dev/null<span class="k">)</span> <span class="o">||</span> <span class="nb">exit </span>0 <span class="nv">CURRENT</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">ref</span><span class="p">#refs/heads/</span><span class="k">}</span><span class="s2">"</span> git checkout master git branch -d <span class="k">${</span><span class="nv">CURRENT</span><span class="k">}</span></code></pre></div> <p>And we’re ready to repeat the whole process on a new bug/feature/chore.</p> <p>You can even take this a bit farther, and create an alias for the last three commands ‘hsd’ (hack ship done)</p> <div class="highlight"><pre><code class="language-sh" data&#45;lang="sh"><span class="nb">alias </span><span class="nv">hsd</span><span class="o">=</span><span class="s2">"hack &amp;&amp; ship &amp;&amp; dwf"</span></code></pre></div> <p>Pretty awesome! I’m sure there are hundreds of awesome workflows out there. What do you guys use on your projects?</p> <img src="http://www.google-analytics.com/collect?v=1&t=pageview&dl=http%3A%2F%2Fjonrohan.codes%2Fatom%2Ffieldnotes%2Fdead-simple-git-workflow-for-agile-teams&ul=en-us&de=UTF-8&dt=Dead%20Simple%20Git%20Workflow&cid=198907588.1430708348&tid=UA-543420-18"> http://jonrohan.codes/fieldnotes/8-bit-kill-screen 8-bit Kill Screen 2010-10-04T00:00:00-07:00 2010-10-04T00:00:00-07:00 Using paralax scrolling and canvas to create a 'kill screen' effect. &copy; Jon Rohan 2010. All rights reserved. <p>Drawing some 8-bit stars in canvas and using a paralax technique to make it look like a kill screen. Check out the <a href="http://codepen.io/jonrohan/full/BNyWRW/">demo</a>.</p> <figure class="post-image image-style-full"> <img class="zoom-image js-zoom-image" src="http://jonrohan.codes/assets/images/posts/space.gif" /> <figcaption class="image-caption">Your game is over</figcaption> </figure> <p><a href="http://codepen.io/jonrohan/full/BNyWRW/">Demo</a></p> <img src="http://www.google-analytics.com/collect?v=1&t=pageview&dl=http%3A%2F%2Fjonrohan.codes%2Fatom%2Ffieldnotes%2F8-bit-kill-screen&ul=en-us&de=UTF-8&dt=8-bit%20Kill%20Screen&cid=198907588.1430708348&tid=UA-543420-18"> http://jonrohan.codes/fieldnotes/deck-of-cards Building a deck of 20 cards and shuffling them 2010-06-16T00:00:00-07:00 2010-06-16T00:00:00-07:00 Was playing with making some cards, without using any images or such. &copy; Jon Rohan 2010. All rights reserved. <p>Working on my card tricks. I built a page to shuffle out a deck of cards, and then discard the top card. Doing it without any images. Check out the <a href="http://codepen.io/jonrohan/full/vOEJMy/">demo</a></p> <figure class="post-image image-style-full"> <img class="zoom-image js-zoom-image" src="http://jonrohan.codes/assets/images/posts/cards.gif" /> <figcaption class="image-caption">The cards get dealt, then you can shuffle them or discard one.</figcaption> </figure> <p><a href="http://codepen.io/jonrohan/full/vOEJMy/">Demo</a></p> <img src="http://www.google-analytics.com/collect?v=1&t=pageview&dl=http%3A%2F%2Fjonrohan.codes%2Fatom%2Ffieldnotes%2Fdeck-of-cards&ul=en-us&de=UTF-8&dt=Building%20a%20deck%20of%2020%20cards%20and%20shuffling%20them&cid=198907588.1430708348&tid=UA-543420-18"> github-integrations-directory GitHub Integrations Directory Thu, 01 Oct 2015 00:00:00 -0500 Thu, 01 Oct 2015 00:00:00 -0500 <p>We shipped an Integrations directory for application makers on GitHub.</p> updated-syntax-highlighting-theme Updated syntax highlighting theme Tue, 09 Dec 2014 00:00:00 -0500 Tue, 09 Dec 2014 00:00:00 -0500 <p>When we launched syntax highlighted diffs, we needed to rewrite our pygments processor because of the extra processing power that it required. This gave us the opportunity to rethink the theme. We redesigned the colors with readability in mind for red/green highlighted lines in diffs.</p> github-s-explore-email GitHub's Explore Email Mon, 11 Nov 2013 00:00:00 -0500 Mon, 11 Nov 2013 00:00:00 -0500 <p>After shipping <a href="/appearances/#github-trending">GitHub Trending</a>, I had a lot of developers asking to be able to subscribe to the trending list. I created the explore email to give developers snapshots of activity daily, weekly or monthly.</p> github-trending GitHub Trending Tue, 13 Aug 2013 00:00:00 -0500 Tue, 13 Aug 2013 00:00:00 -0500 <p>I shipped GitHub’s <a href="https://github.com/trending">trending</a> section designing and developing it. The trending section was the first of a number of improvement’s to GitHub’s explore sections of the site.</p> github-repository-search GitHub Repository Search Mon, 06 May 2013 00:00:00 -0500 Mon, 06 May 2013 00:00:00 -0500 <p>After launching <a href="#global-github-search">Global GitHub search</a>, we focused our attention on updating repostory search, adding code search and issues search. I was the lead designer and front-end developer for this project.</p> non-breaking-space-show-30 Non Breaking Space Show #30 Thu, 14 Mar 2013 00:00:00 -0500 Thu, 14 Mar 2013 00:00:00 -0500 <p>I was invited to speak on the <a href="https://twitter.com/nbsptv">Non Breaking Space</a> show about CSS performance. I was prompted because of a <a href="#github-s-css-performance">talk</a> I gave on the subject.</p> global-github-search Global GitHub search Wed, 23 Jan 2013 00:00:00 -0500 Wed, 23 Jan 2013 00:00:00 -0500 <p>This was a complete update to GitHub’s global search page. We updated the backend to elastic search, and updated the UI including creating an advanced search page. I was the lead designer on all of these changes.</p> github-s-css-performance GitHub's CSS Performance Wed, 05 Dec 2012 00:00:00 -0500 Wed, 05 Dec 2012 00:00:00 -0500 <p>A talk I gave at the 2012 <a href="http://2012.cssdevconf.com/">CSS Dev conference</a> about monitoring and fixing some performance problems on GitHub’s diff pages. I talked about lessons learned, tools used and rules for the future. The talk was also <a href="https://vimeo.com/54990931">recorded</a>.</p> github-notifications-2-0 GitHub Notifications 2.0 Mon, 06 Aug 2012 00:00:00 -0500 Mon, 06 Aug 2012 00:00:00 -0500 <p>I helped ship what was the second iteration of GitHub notifications. The focus of a lot of the work was around subscribing to threads and the web notifications view.</p> the-making-of-octicons The making of octicons Sat, 21 Jul 2012 00:00:00 -0500 Sat, 21 Jul 2012 00:00:00 -0500 <p>Gave a joint talk with <a href="http://cameronmcefee.com/">Cameron McEfee</a> about octicons at a <a href="http://cascadesf.com/">cascade sf</a> event. This was a talk focused specifically after we <a href="#say-hello-to-octicons">launched octicons</a>.</p> say-hello-to-octicons Say hello to octicons Wed, 09 May 2012 00:00:00 -0500 Wed, 09 May 2012 00:00:00 -0500 <p>This was a blog post introducing GitHub’s new icon font, <a href="https://octicons.github.com/">Octicons</a>. We did this because we wanted to make our site as HDpi as we could. Replacing the previous icon set with scallable ones was a win win.</p> search-itunes-hubot-script Search iTunes hubot script Tue, 25 Aug 2015 00:30:23 -0500 Tue, 25 Aug 2015 00:30:23 -0500 <p>A hubot script that searches iTunes for a song and returns a preview.</p> search-for-a-ruby-gem-with-hubot Search for a ruby gem with hubot Sun, 23 Aug 2015 00:30:23 -0500 Sun, 23 Aug 2015 00:30:23 -0500 <p>A hubot script that searches rubygems.org for a gem and returns latest info.</p> slack-react-me-for-hubot Slack react me for hubot Wed, 19 Aug 2015 00:30:23 -0500 Wed, 19 Aug 2015 00:30:23 -0500 <p>A hubot script for Slack that will search the API for messages with reactions.</p> primer Primer Thu, 19 Mar 2015 19:31:21 -0400 Thu, 19 Mar 2015 19:31:21 -0400 <p>The CSS toolkit and guidelines that power GitHub.</p> atom-docs-snippets Atom docs snippets Thu, 27 Feb 2014 00:30:23 -0500 Thu, 27 Feb 2014 00:30:23 -0500 <p>Atom snippets for writing documentation.</p> github-pages-time-machine-theme GitHub Pages time machine theme Mon, 08 Oct 2012 00:30:23 -0500 Mon, 08 Oct 2012 00:30:23 -0500 <p>Created an official theme for the <a href="https://help.github.com/articles/creating-pages-with-the-automatic-generator/">GitHub pages automatic generator</a></p> zeroclipboard ZeroClipboard Thu, 12 Apr 2012 23:59:44 -0400 Thu, 12 Apr 2012 23:59:44 -0400 <p>Copy to clipboard functionality.</p> 1149268 Following listing Tue, 09 Jul 2013 23:39:30 -0000 Tue, 09 Jul 2013 23:39:30 -0000 <p>I updated the following/followers pages on GitHub. Was trying to get them to be more enticing.</p>

I updated the following/followers pages on GitHub. Was trying to get them to be more enticing.

2016018 Commits listing Sun, 12 Apr 2015 19:31:33 -0000 Sun, 12 Apr 2015 19:31:33 -0000 <p>Posting this after updating it a few months ago, but I thought I'd share.</p>

Posting this after updating it a few months ago, but I thought I'd share.

702065 Heisencat Fri, 24 Aug 2012 21:04:50 -0000 Fri, 24 Aug 2012 21:04:50 -0000 <p>#laterdribbble I don't know how I didn't dribbble this before. full size here <a href="http://octodex.github.com/heisencat/" rel="noreferrer">http://octodex.github.com/heisencat/</a></p>

#laterdribbble I don't know how I didn't dribbble this before. full size here http://octodex.github.com/heisencat/

2097371 Personal styleguide Mon, 08 Jun 2015 12:30:37 -0000 Mon, 08 Jun 2015 12:30:37 -0000 <p>This is my personal coding styleguide. I try to cover how I write HTML, CSS, JavaScript and Ruby.</p> <p>I'm still writing out more docs, but I think I've pretty much nailed the design down.</p> <p>Full site - <a href="http://jonrohan.codes/styleguide/" rel="noreferrer">http://jonrohan.codes/styleguide/</a></p>

This is my personal coding styleguide. I try to cover how I write HTML, CSS, JavaScript and Ruby.

I'm still writing out more docs, but I think I've pretty much nailed the design down.

Full site - http://jonrohan.codes/styleguide/

249009 More input, more input Sat, 27 Aug 2011 14:54:19 -0000 Sat, 27 Aug 2011 14:54:19 -0000 <p>We're using these awesome bot avatars as default avatars on botriot.</p>

We're using these awesome bot avatars as default avatars on botriot.

2046512 Personal site redesign Sun, 03 May 2015 14:13:10 -0000 Sun, 03 May 2015 14:13:10 -0000 <p>Decided to give my site <a href="http://jonrohan.codes/" rel="noreferrer">http://jonrohan.codes/</a> a little bit of a design update. More details here <a href="http://jonrohan.codes/fieldnotes/a-big-update-to-this-site/#post" rel="noreferrer">http://jonrohan.codes/fieldnotes/a-big-update-to-this-site/#post</a></p>

Decided to give my site http://jonrohan.codes/ a little bit of a design update. More details here http://jonrohan.codes/fieldnotes/a-big-update-to-this-site/#post

431890 2012 Workspace Fri, 17 Feb 2012 22:05:55 -0000 Fri, 17 Feb 2012 22:05:55 -0000 <p>My GitHub Desk</p>

My GitHub Desk

319062 Total Bots Mon, 14 Nov 2011 19:35:23 -0000 Mon, 14 Nov 2011 19:35:23 -0000 <p>I love stats dashboards.</p>

I love stats dashboards.