Tuesday, February 15, 2011

"Nested" CSS

I really don't know why this hasn't been implemented but it surely seems simple and would have a HUGE impact on the CSS coders everywhere.

So instead of doing this...
.selector .subselector{property:attribute;}
.selector .anothersubselector{property:attribute;}

Why not this?
.selector{{
      .subselector{property:attribute;}
      .anothersubselector{property:attribute;}
}}

Pure. Simple. And it will increase CSS readability and cut down of file size because you wont have to repeat the lead selector 100 times...

Thursday, September 2, 2010

jQuery Random Color

This is a simple example of how to assign a random color to any html element:

$(this).css("color", 'rgb('+Math.floor(Math.random()*255)+','+Math.floor(Math.random()*255)+','+Math.floor(Math.random()*255)+')');

Tuesday, May 4, 2010

Rounded Corners on Floating Images of Variable Sizes

Recently I have been working on a site that uses the awesome jQuery Corners plugin. The plugin does not support rounded corners on images. So I am dynamically wrapping all the images in the content area with a span so that the image can a border with rounded corners. I thought this would be rather simple but as it always turns out things are a little more complicated than I imagined.

First off these are images coming from a client via a CMS and can be any size or shape. No big deal. I'll just use the inline-block display attribute and move along. Well, not so fast. IE7 has issues with that. It will display at 100% of the parents width. So I need to use jQuery to find the width of our images and set the parent span to the same width. While working through this issue I found out that webkit browsers (Chrome and Safari) do not actually know any DOM element dimensions during $(document).ready. You have to wait a little longer and let the page be drawn out by using $(window).load. That makes sense to me, but I am curious why this is not the same across the board.

Lastly, we have to account for the client setting the image to float left or right in the CMS and transfer those values to the parent. I decided to do that by passing the float value as a class. I have basic styling like float direction and corresponding margin values.

So enough talk. Here is the code:

<script type="text/javascript">
$(window).load(function(){
$('#content img').each(function(index,item){
        var f=$(this).css('float');
        var w=$(item).width();
        $(item).wrap("<span class='img "+f+"'style='width:"+w+"'></span>");
        $(item).parent().corner("10px cc:#AEE1FE");
    });
});
</script>

Thursday, November 12, 2009

Access Yahoo's Weather API via YQL and jQuery

Let me start off by saying that if you want a basic demo of YQL by grabbing an RSS feed check out my first blog post on YQL. In this post I am going to make a little weather widget that grabs the current temperature, weather condition, wind speed and direction, create a link to the full forecast and lastly drop a pretty weather condition graphic as the background of the widget. Then, once I have all that data I am going to display it via jQuery.

So let's get started! Pull up the YQL developer console: https://developer.yahoo.com/yql/console/ and type in:

select * from weather.forecast where location=29201

Select JSON and click test. This shows you the weather data for Columbia, SC in JSON format. The good stuff is located in the within data.query.results.channel. In there you have access to the current temperature, humidity, wind, wind direction and even sunrise and sunset times. So let's start off simple.

Notice the rest query url in YQL console? It reads:
http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20location%3D29201&format=json&callback=cbfunc

That is a little tough to work with if you ask me so I like to bring in a little jquery to make this JSON url a little easier to work with and read. Here is a little piece of jquery that does just that for you:

$.YQL = function(query, callback) {
    var encodedQuery = encodeURIComponent(query.toLowerCase()),
        url = 'http://query.yahooapis.com/v1/public/yql?q='
            + encodedQuery + '&format=json&callback=?';
    $.getJSON(url, callback);
};


I generally include this little snippet in a file called jquery.yql.js. After that we can place our YQL query just like in the console. Here is our sample query:

$.YQL("select * from weather.forecast where location=29201",function(data){
            var w=data.query.results.channel;
            $('#weatherTemp').html(w.item.condition.temp+"&deg;");
            $('#weatherText').html(w.item.condition.text);
       });  

This call grabs the weather information for Columbia, SC and injects the temperature and condition text to their corresponding divs. So data.query.results.channel.item.condition.temp = current temperature. and data.query.results.channel.item.condition.text = current condition.

So that was easy, let's grab all the information we want for this demo!

$.YQL("select * from weather.forecast where location=29406",function(data){
            var w=data.query.results.channel;
            var weatherImage="url(http://l.yimg.com/a/i/us/nws/weather/gr/"+w.item.condition.code+"d.png)";
            var wd=w.wind.direction;
            if(wd>=348.75&&wd<=360){wd="N"};if(wd>=0&&wd<11.25){wd="N"};if(wd>=11.25&&wd<33.75){wd="NNE"};if(wd>=33.75&&wd<56.25){wd="NE"};if(wd>=56.25&&wd<78.75){wd="ENE"};if(wd>=78.75&&wd<101.25){wd="E"};if(wd>=101.25&&wd<123.75){wd="ESE"};if(wd>=123.75&&wd<146.25){wd="SE"};if(wd>=146.25&&wd<168.75){wd="SSE"};if(wd>=168.75&&wd<191.25){wd="S"};if(wd>=191.25 && wd<213.75){wd="SSW"};if(wd>=213.75&&wd<236.25){wd="SW"};if(wd>=236.25&&wd<258.75){wd="WSW"};if(wd>=258.75 && wd<281.25){wd="W"};if(wd>=281.25&&wd<303.75){wd="WNW"};if(wd>=303.75&&wd<326.25){wd="NW"};if(wd>=326.25&&wd<348.75){wd="NNW"};
            $('#weatherWidget').css("background-image",weatherImage);
            $('#weatherTemp').html(w.item.condition.temp+"&deg;");
            $('#weatherText').html(w.item.condition.text);
            $('#weatherWind').html(wd +" "+w.wind.speed+"mph");
            $('#weatherLink').html("<a href='"+w.item.link+"'>Full Forecast</a>");
        });

OK, let's go line by line. First off you wil notice that I created weatherImage variable. Yahoo does not give you the full url to the image. I have to build the url and insert the condition code to display the right image. So to make the weatherImage I take the string "http://l.yimg.com/a/i/us/nws/weather/gr/" and add the condition code "30" to it and append the string ".png" to that you get: http://l.yimg.com/a/i/us/nws/weather/gr/30d.png

Yahoo does not give you the text wind direction. It gives you the degree. So if w.wind.direction might equal "90" which equals East. But I actually want to display E or NE. etc... So I wrote a series of if statements to check the direction number and output a string. I know, I know. I could have written a regular expression, but hey, I am a designer. Cut me some slack!

The rest of it just injects all the data into the corresponding divs. So here is a working example:


Please note there is NO server side coding going on. This is just javascript, HTML, and a little css. Speaking of which, here is the html as well:

<div id="weatherWidget" style="background: rgb(51, 51, 51) none no-repeat scroll 0% 0%; border: 10px solid rgb(17, 17, 17); height: 150px; position: relative;">
<div id="weatherDescription" style="left: 200px; position: absolute; top: 40px;">
<div id="weatherTemp" style="font-size: 200%; font-weight: bold;"></div>
<div id="weatherText"></div>
<div id="weatherWind"></div>
<div id="weatherLink"></div>
</div>
</div>

Pretty simple stuff if you ask me. I am going to post some flickr, youTube, upcoming.org, and twitter YQL widgets in the near future. So stay tuned!

Friday, October 23, 2009

YQL allows you to query the entire web

Leave no RSS, XML document, or web 2.0 api untouched! You literally can grab content from anywhere, turn it into JSON data and display the desired information using my old fiend jQuery.
First off check out the YQL developer console: https://developer.yahoo.com/yql/console/
There you can run test queries and view many community tables using popular api's and file formats doing very useful things. For example, if I want to grab the latest 3 posts from my blog I would just put in:
select * from atom where url='http://graphicallyherdingthemasses.blogspot.com/feeds/posts/default' limit 3

And BAM. Right there in the console you can see the feed. If you select JSON and run the test again and copy the generated url you get this...
https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20atom%20where%20url%3D'http%3A%2F%2Fgraphicallyherdingthemasses.blogspot.com%2Ffeeds%2Fposts%2Fdefault'%20limit%203&amp;format=json&amp;callback=cbfunc
That's great but how can I put that on MY site? Well, first we need to bring in a little jquery to make this JSON url a little easier to work with and read. Here is a little piece of jquery that does just that for you:

$.YQL = function(query, callback) {
    var encodedQuery = encodeURIComponent(query.toLowerCase()),
        url = 'http://query.yahooapis.com/v1/public/yql?q='
            + encodedQuery + '&format=json&callback=?';
    $.getJSON(url, callback);
};

So now all we need to do is grab the data and display it using a little jquery. First we grab the first 3 posts by our YQL call. Once we get the data we are going to find the individual blog posts and grab the title and the link and append it to the called bloggerWidget.

$.YQL("select * from atom where url='http://graphicallyherdingthemasses.blogspot.com/feeds/posts/default' limit 3",function(data){
            var blogPost=data.query.results.entry;
            $.each(blogPost,function(index, blogPost){
                $('#bloggerWidget').append("<li><a href='"+blogPost.link[4].href+"'>"+blogPost.title.content+"</a></li>");
            });    
        });

Here is it in action:


    No ASP, PHP, JSP, proxies, or cross domain errors... You can do this with ANY feed on ANY site. I am currently working on a site that pulls in data from the yahoo weather api, the flickr api, blogger atom feeds, twitter rss 2.0 feeds, and the youtube api.

    Thursday, October 8, 2009

    As the page folds

    Found a great article that talks a problem that I run into all the time. Clients, especially older ones, want everything to fit on one page with no scrolling or to use a print term, "above the fold". Everytime I explain that they have too much information to fit into that space and that it many extremely successful brands have pages with content way below the fold.

    This artcle not only addresses the "popular brands approach:


    It also takes hundreds of hours of eye tracking user testing. Here is a heat map of a site with content mainly above the fold and another with less content above the fold, think large rotating banner image at the top.

    The article also has an example of how to encourage users to explore below the fold. Simple things like don't make a large header that is 100% of the content area's width and "chop off" the page. Also, I would suggest using a subtle vertical gradient to draw the eye naturally downward.

    Another thing to think about to cut down on page scrolling is using columns. Not only does it help with the page height, but it also reduces wasted space and extremely wide copy. Everyone knows 72 characters is the "perfect" width so at 11px font size at 900px width. Two columns is almost perfect for real body text. You can even go to 3 columns on the homepage with short news headlines, event names and announcements.

    Check out the full article "The myth of the page fold":
    http://www.cxpartners.co.uk/thoughts/the_myth_of_the_page_fold_evidence_from_user_testing.htm

    Tuesday, September 29, 2009

    Need a quick quote?

    I found a great article by Brian Fling, although it is kind of old, about pricing design based projects. Please adjust the dollar amounts for inflation ;)
    Here are some interesting excepts from the article...

    1 mockup x time(1×10 hours) x $100 = $1,000
    Three mockups would look like this:
    3 mockups x time(1×10 hours) x $100 = $3,000
    A slightly more complex mockup might look like this:
    3 mockup x time(1.5×10 hours) x $100 = $4,500
    And a complex or challenging mockup might look like this:
    3 mockups x time(2×10 hours) x $100 = $6,000
    And so on. Start with a three-point complexity scale using the quarter points if necessary (e.g. 1.25, 1.5, 1.75 etc). If you feel you need to use a five-point scale or even a ten-point scale I would imagine you haven’t figured out your hourly rate.
    He even answers an often asked question...What is my hourly rate?

    (expenses + salary) ÷ hrs worked per yr. + margin = hourly rate
    Liked what you saw? Check out the full article here:
    http://www.blueflavor.com/blog/2006/apr/25/pricing-project/