<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tech Blog &#187; CSS</title>
	<atom:link href="http://assanka.net/content/tech/tag/css/feed/" rel="self" type="application/rss+xml" />
	<link>http://assanka.net/content/tech</link>
	<description>Just another Arb-assk2009003.turmeric.assanka.com Blogs weblog</description>
	<lastBuildDate>Mon, 29 Aug 2011 19:00:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Thoughts on CSS transitions in Firefox</title>
		<link>http://assanka.net/content/tech/2010/05/20/thoughts-on-css-transitions-in-firefox/</link>
		<comments>http://assanka.net/content/tech/2010/05/20/thoughts-on-css-transitions-in-firefox/#comments</comments>
		<pubDate>Thu, 20 May 2010 14:36:05 +0000</pubDate>
		<dc:creator>Andrew Betts</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[Animation]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Future Tech]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://assanka.net/content/tech/?p=129</guid>
		<description><![CDATA[To produce the CSS3 ticker plugin for jQuery that I&#8217;ve been working on recently, I used CSS3 transitions.  These are the magic new properties in CSS that make a browser animate elements without using JavaScript.
The logic for implementing native animations in the browser is a no-brainer, particularly if you try and use a site [...]]]></description>
			<content:encoded><![CDATA[<p>To produce the <a href="/content/tech/2010/03/14/smooth-css3-ticker-jquery-plugin/">CSS3 ticker plugin for jQuery</a> that I&#8217;ve been working on recently, I used <a href="http://webkit.org/blog/138/css-animation/">CSS3 transitions</a>.  These are the magic new properties in CSS that make a browser animate elements without using JavaScript.</p>
<p>The logic for implementing native animations in the browser is a no-brainer, particularly if you try and use a site that implements scrolling tickers by incrementing an element&#8217;s <code>left</code> or <code>margin-left</code> properties every few milliseconds.   Watch your interactions with the rest of the page slow down to a sluggish crawl and realise that animating the positioning of DOM elements in JavaScript can sometimes be pretty slow.</p>
<p>With animation increasingly important to creating rich and usable user interfaces, the chance to start optimising the performance of animation in the browser via native implementation is a great step forward.  Unfortunately, this is currently only supported by Webkit based browsers.  In developing the ticker, I wanted to see if support in Firefox would be possible.</p>
<p>From version 1.9.3 of Gecko, the <code>-moz-transition</code> family of CSS properties have been added, so I tried grabbing the latest version of <a href='http://www.mozilla.org/projects/minefield/'>Minefield</a> (the pre-release codename for Firefox) and running the ticker plugin.</p>
<p>It doesn&#8217;t work.  Specifically, it doesn&#8217;t work for these reasons:</p>
<ol>
<li>It doesn&#8217;t seem to be possible to act on position properties.  <code>left</code>, <code>right</code>, <code>top</code> and <code>bottom</code> do not appear to animate.  It might be possible to work around this by switching to animating margins rather than absolute positioning, but hopefully it will be possible to animate these before the Firefox 3.7 release.</li>
<li>It doesn&#8217;t appear to fire the <code>mozTransitionEnd</code> event, which you&#8217;d expect from a full implementation of the standard.  As a result, my ticker can&#8217;t loop.</li>
<li>It doesn&#8217;t seem to be possible to change animation properties (such as the duration) from JavaScript.  I need this to disable animation while repositioning the ticker for the next loop.</li>
</ol>
<p>This is clearly an early pre-release version, and it&#8217;s encouraging to see support starting to emerge from the Firefox camp.  I think I might have retired by the time this kind of feature hits Internet Explorer!</p>
]]></content:encoded>
			<wfw:commentRss>http://assanka.net/content/tech/2010/05/20/thoughts-on-css-transitions-in-firefox/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Smooth CSS3 ticker jQuery plugin</title>
		<link>http://assanka.net/content/tech/2010/03/14/smooth-css3-ticker-jquery-plugin/</link>
		<comments>http://assanka.net/content/tech/2010/03/14/smooth-css3-ticker-jquery-plugin/#comments</comments>
		<pubDate>Sun, 14 Mar 2010 11:50:26 +0000</pubDate>
		<dc:creator>Andrew Betts</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Tickers]]></category>
		<category><![CDATA[UI Design]]></category>

		<guid isPermaLink="false">http://assanka.net/content/tech/?p=105</guid>
		<description><![CDATA[I&#8217;ve recently been building a status display for the Assanka office, which shows us information like current Zabbix monitoring triggers, support requests from clients, Pingdom status alerts, and even naming and shaming Assankans who&#8217;ve failed to file their time-sheets on time.
In the process, I was pointed at the gorgeous Panic status board.  Our objectives [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently been building a status display for the Assanka office, which shows us information like current Zabbix monitoring triggers, support requests from clients, Pingdom status alerts, and even naming and shaming Assankans who&#8217;ve failed to file their time-sheets on time.</p>
<p>In the process, I was pointed at the gorgeous <a href="http://www.panic.com/blog/2010/03/the-panic-status-board/">Panic status board</a>.  Our objectives were similar and I was attracted to the idea of adding the scrolling tickers (at least, we assume they are scrolling from Panic&#8217;s photograph), which run along the bottom of their board.  I was reminded of the kind of tickers you get on 24 hour news channels (here&#8217;s one from BBC World):</p>
<p><img src="/content/tech/files/2010/03/bbcworldcap42.jpg" alt="BBC World screen capture showing scrolling ticker" /></p>
<p>Tickers in web browsers are difficult for a number of reasons.  First, continuously animating the <code>left</code> or <code>margin-left</code> properties of an element in JavaScript is computationally expensive, particularly if you want to reposition the element often enough to create a properly smooth animation.  Sites that use Javascript for tickers in this manner tend to hog your computer&#8217;s CPU and feel slow and laggy as a result.  Many sites give up on the traditional ticker and go for something that&#8217;s easier for the browser to animate, like a &#8216;type in&#8217; reveal (eg the BBC News homepage ticker), or a vertical &#8217;scroll up&#8217; ticker.</p>
<p><img src="/content/tech/files/2010/05/Capture.jpg" alt="BBC News online ticker" /></p>
<p>Another issue with continuous tickers is making them loop properly.  When your animation reaches the end of the text, you have to scroll it all the way off the left edge of the screen before it can be repositioned and re-enter the frame from the right.  This leaves an ugly gap in your ticker.</p>
<p>Finally, if your ticker is updating with new information in real time, making changes that are noticeable in the visible portion of the ticker is amateur hour stuff.  You rarely see TV tickers suddenly change mid-scroll, and yet stories are seamlessly added and removed as necessary, <em>outside of the visible frame</em>.</p>
<p>Since Panic didn&#8217;t release any code (boo), I set out to produce a jQuery plugin that would enable news tickers to be easily added to a page, using CSS3 animation effects.  If it&#8217;s working for you, you should see a couple of tickers scrolling away right here:</p>
<div class="iframe-wrapper">
  <iframe src="/content/tech/files/2010/05/webkitscroller.html" frameborder="0" style="height:85px;width:590px;">Please upgrade your browser</iframe>
</div>
<p>If it&#8217;s not working, you&#8217;re probably not using a browser that supports CSS3 transitions.  Try it in Chrome, or Safari.  Support should be added to Firefox pretty soon.  But the objective here is not to get universal compatibility, since I can easily dictate which browser our status board will use.</p>
<p>With CSS3 transitions, we substantially improve the performance issue of tickers.  And this will improve further with browsers implementing these effects at an increasingly lower level.  This leaves the looping and updating issues to resolve before we can claim a properly news-grade ticker.</p>
<h2>Looping</h2>
<p>There are two possible solutions to the looping problem.  The first is to target segments of the ticker just after they have left the frame on the left, and move them to the end of the ticker on the right.  The second is to make several copies of your ticker content, and when you get to the end of the second copy, reposition the entire ticker element so that the first copy lines up with where the second copy had got to, then scroll on into the second copy again and repeat.</p>
<p>I chose the second approach, because you need several copies of the ticker anyway if it&#8217;s too short to fill the width of the frame with enough left over to sort the looping out.</p>
<h2>Updates</h2>
<p>In order to enable the ticker to be updated dynamically, and yet not suffer any noticeable changes in the visible portion, I added some public methods &#8211; addMessage() and removeMessage(), which allow you to pass a list element and have it queued for addition or removal at an appropriate moment.</p>
<p>This does require breaking a rather holy tenet of jQuery, namely returning a reference to the ticker rather than returning the jQuery chain, so you have an object on which you can call the public methods.</p>
<p>Every time the ticker hits the end of the text, it is  repositioned with the penultimate copy in view, all copies of the ticker text are updated to match the copy to their right, and the final copy (the original set of elements) is updated with the queued additions and removals (out of view).   As a result, when you call the add or remove methods, you may have to wait some time before you see the effect, but the ticker will never judder or change while it is visible to the user.</p>
<h2>How to use</h2>
<p>Your ticker must be a block element containing a UL.  This is because the ticker needs a frame to mask the content as it slides through.</p>
<pre class="brush: xml;">
&lt;div id='ticker1'&gt;
  &lt;ul&gt;
    &lt;li&gt;Headline one&lt;/li&gt;
    &lt;li&gt;Headline two&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
  var ticker = $('#ticker1').ticker();
  var newid = ticker.addMsg('Headline three');
  setTimeout(function() {
    ticker.removeMsg(newid);
  }, 60000);
&lt;/script&gt;
</pre>
<h2>Settings and methods</h2>
<p>The following settings are available, which can be passed to the <code>ticker()</code> function in a standard json object:</p>
<ul>
<li><strong>pxpersec</strong>: Speed of the ticker in pixels per second (optional; default is 30)</li>
</ul>
<p>Calls to the <code>ticker()</code> function return a reference to the ticker, not the jQuery chain.  The ticker reference exposes the following methods:</p>
<ul>
<li><strong>string addMsg(<em>msg</em>)</strong>: Add a new message to the ticker.  Can be a jQuery object or raw list item element (which will be moved from its current location in the DOM), or a plain text string.  Returns a string identifier for the message (to enable you to remove it later).  If you pass an element that already has an ID attribute, that ID is used (and returned).</li>
<li><strong>void removeMsg(<em>msg</em>)</strong>: Remove a message from the ticker.  Can be a jQuery object or raw list item element (which must be in the ticker already), or a string identifier returned from the addMsg call that added the message to the ticker. Returns nothing.</li>
</ul>
<h2>Get the code</h2>
<ul>
<li><a href="/content/tech/files/2010/05/jquery.ticker.js">Download development</a> (commented, 7KB)</li>
<li><a href="/content/tech/files/2010/05/jquery.ticker.min.js">Download production</a> (minified, 4KB)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://assanka.net/content/tech/2010/03/14/smooth-css3-ticker-jquery-plugin/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Auto growing textareas</title>
		<link>http://assanka.net/content/tech/2009/05/04/auto-growing-textareas/</link>
		<comments>http://assanka.net/content/tech/2009/05/04/auto-growing-textareas/#comments</comments>
		<pubDate>Mon, 04 May 2009 16:24:52 +0000</pubDate>
		<dc:creator>Andrew Betts</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[UI]]></category>
		<category><![CDATA[User experience]]></category>
		<category><![CDATA[User input]]></category>

		<guid isPermaLink="false">http://assanka.net/content/tech/?p=3</guid>
		<description><![CDATA[This feels like a topic that&#8217;s been explored to death already, but I really don&#8217;t like most implementations of this technique, so here&#8217;s how we do it.
First, in case anyone has just arrived from Mars, or even more unlikely, isn&#8217;t familiar with Facebook, the auto-growing textarea is a text box that gets bigger as you [...]]]></description>
			<content:encoded><![CDATA[<p>This feels like a topic that&#8217;s been explored to death already, but I really don&#8217;t like most implementations of this technique, so here&#8217;s how we do it.</p>
<p>First, in case anyone has just arrived from Mars, or even more unlikely, isn&#8217;t familiar with Facebook, the auto-growing textarea is a text box that gets bigger as you type into it, so that you never see a scroll bar (unless you&#8217;re typing war and peace).</p>
<p>There are lots of ways of doing each part of this.  The parts I&#8217;ll look at are (a) what triggers a review of the text box&#8217;s size, (b) how to determine whether a resize is required, and (c) how to perform a resize.</p>
<h2>Triggering a review</h2>
<p>There are four ways this is typically done:</p>
<ol>
<li> On an interval, say every 50ms</li>
<li> On keypress</li>
<li> On change</li>
<li> On keyup</li>
</ol>
<p>I&#8217;m staggered by how many scripts insist on doing this kind of thing on an interval.  Setting up interval timers for no good reason is a shortcut to terrible performance and memory leaks galore.  So we won&#8217;t be doing that.  onkeypress and onchange events are triggered before the box is updated with the latest keypress, so we want to avoid those, as the latest keypress might have been the one to bring us onto a new line.  That leaves onkeyup, which is fired after the box is updated with the new character, and allows us to inspect it and decide whether to increase its size.</p>
<h2>To resize or not to resize</h2>
<p>How to determine whether to resize the box comes in three flavours:</p>
<ol>
<li> Count the number of newline characters in the textarea&#8217;s value, and see if that matches the number of rows the textarea has.</li>
<li> Create a &#8217;shadow&#8217; DIV which is off screen (eg. margin-left: -10000px) and has no height declared, but otherwise has the same style properties as the textarea, fill it with the textarea&#8217;s content, measure the subsequent height of the DIV, then see if that height matches the current height of the textarea.</li>
<li> Check whether scrollHeight (the height of the scollable content of the box) &gt; clientHeight (the height of the box itself).</li>
</ol>
<p>In this case I was suprised at the number of implementations that favoured counting newlines.  This only works if combined with counting the number of characters in the textarea&#8217;s value, AND a monospaced font, AND knowing the number of columns in the textarea.  In short, er, it&#8217;s mad.</p>
<p>Second option, and the one favoured by a lot of the framework plugins due to the ease with which you can create shadow elements in the likes of jQuery, is to create a shadow DIV. This has the advantage of telling you the actual pixel height of the text, even where it is LESS than the height of the textarea box.  Otherwise, you&#8217;re limited to measuring clientHeight and scrollHeight, which are exactly the same if the textarea isn&#8217;t scrolling, regardless of how much space you&#8217;ve got to spare at the bottom.  My issue with this method is that it basically requires use of a framework to not be painful, and even then it&#8217;s non-trivial amounts of code, and adds needless pollution to the DOM.</p>
<p>So that leaves relying on scrollHeight and clientHeight.  These are well supported and efficient to read, so provided that you work around the issue of scrollHeight always being at least equal to clientHeight, this offers a very lightweight solution.  The features that you can achieve with a shadow DIV that you can&#8217;t do by simply reading scrollHeight and clientHeight are (a) you can ensure there is always a blank line at the bottom of your textarea, and (b) you can shrink the textarea if the user deletes text from it.  I&#8217;m personally of the view that neither of these is actually particularly desirable.  There&#8217;s potentially an argument for leaving a blank line at the bottom, but equally the uer might feel like they&#8217;re just being pressured to write more.</p>
<h2>How to resize the box</h2>
<p>OK, so if you&#8217;ve concluded that the user is writing chapter and verse and the textarea is in need of a bit more space, how do we go about doing it?</p>
<ol>
<li> Animate the CSS height property</li>
<li> Add some height via the CSS height property</li>
<li> Add 1 to the rows attribute</li>
</ol>
<p>A fair few of the framework plugins use their framework&#8217;s animation capabilities to animate the grow effect.  I don&#8217;t like this.  Just because you have an animation effect available doesn&#8217;t mean it&#8217;s appropriate to use it, and there are many situations where the end user just doesn&#8217;t want to wait 300ms for the privilege of using a fresh line.</p>
<p>Simply adding height to the CSS property is a fair way of doing it, but unless you do some maths on the user&#8217;s line height (or hard code some magic numbers), you can&#8217;t necessarily guarantee that the resulting height will be a multiple of the textarea&#8217;s line height.</p>
<p>Easiest, most efficient solution: add one to the rows attribute of the textarea.  rows is part of XHTML as well as HTML 4.01, and has universal support going back yonks.</p>
<h2>Pasting</h2>
<p>Watch out for pastes.  If the user pastes in a large quantity of text, they will trigger only one keyup event, but will have added many lines to the textarea.  Make sure that if a resize is required, you trigger another review after the resize is complete.</p>
<h2>Max height: the war and peace scenario</h2>
<p>If the user really does seem to be writing a novel, we probably should call it a day on growing the textarea at some stage, and certainly <strong>before it gets to be taller than the viewport</strong>.  You can check the height against the viewport height, though I typically just restrict it to an arbitrary height, say 30 rows.</p>
<h2>The code</h2>
<p>You&#8217;ll need a textarea element with an ID of <code>mytextarea</code> to make this code sample work, and obviously you can easily modify it to use selectors from your favourite framework rather than the native <code>document.getElementById</code>.</p>
<pre class="brush: jscript;">
document.getElementById('mytextarea').onkeyup = function() {
	var ta = document.getElementById('mytextarea');
	var maxrows = 30;
	var lh = ta.clientHeight / ta.rows;
	while (ta.scrollHeight &amp;gt; ta.clientHeight &amp;amp;&amp;amp; !window.opera &amp;amp;&amp;amp; ta.rows &amp;lt; maxrows) {
		ta.style.overflow = 'hidden';
		ta.rows += 1;
	}
	if (ta.scrollHeight &amp;gt; ta.clientHeight) ta.style.overflow = 'auto';
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://assanka.net/content/tech/2009/05/04/auto-growing-textareas/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

