

Developing a responsive, Retina-friendly site (Part 2) - PStamatiou
http://paulstamatiou.com/responsive-retina-blog-development-part-2

======
mddw
I feel always a little lost when I read tutorials which use SASSy/LESSy CSS.
Illustrating exemples with a preprocessor means lots of web developers won't
be able to read you.

Moreover these developers are not in the hype bandwagon (or they would be able
to read SASSy/LESSy/whatever fashionable now), so they may need the most the
said tutorials.

~~~
aaronbrethorst
You should learn one of them. It'll make your life _so_ much easier that it's
not even funny. They're also really straightforward (for the most part).

So you know that Sass and Less allow you to nest rules, right? e.g.:

    
    
        .foo {
            p {
                // rules go here
            }
        }
    

translates into .foo p { _rules go here_ }

Here are the examples from the article:

    
    
        &:hover { opacity: 1; }
    

The ampersand simply means 'I am applied in the context of whatever rule I
happen to be in'. So, .home { &:hover { } } is equivalent to writing this
normal CSS:

    
    
        .home:hover {
        }
    

@include is like #include in C. It literally _includes_ the referenced content
in the rules you're writing. That means that

    
    
        .home {
            @include bg-size(60px,auto);
        }
    

is including something that (inferring from the name, here) sets the
background size for the element. Given the parameters, it probably expands
into:

    
    
        .home {
            background-size: 60px auto;
        }
    

plus another rule for handling 2x images in Webkit.

This is a variable. Nuff said.

    
    
        $sprite_url_2x: "http://turbo.paulstamatiou.com/assets/pstam-sprite-v2-@2x.png";
    

make sense?

~~~
CJefferson
Given I don't understand SASS and Less, you seem to have, in each case,
replaced some CSS with something which is longer, and less easy to understand.

I am sure these is some extra magic you are not telling us, but given that you
are assuming we don't know about SASS and Less, you are obviously missing
something important :)

~~~
Recoil42
You're actually the one missing something important: complexity.

His examples are simple, meant to give you an idea of how sass/less work on a
basic level. But I'm currently working on site that is several thousand lines
of CSS, employing enormously complex css structures. Pseudo-selectors are in
use everywhere. As are complex gradients, shadows, sprites...

It's imperative to have some sort of organization in your code. Working with
really long class names or IDs isn't an option.

For instance, on this project, we have a defined color set of colours. The red
we're using is #c03838. The blue is #2767d1. A shadow used throughout the site
is 1px 1px 3px rgba(0,0,0,0.2), and one of the gradients (used in a few
places) looks like this when written out fully:
<http://i.imgur.com/YZi3f0B.png>

It wouldn't make sense to memorize those values/strings. Not only that, but it
would become a pain in the ass to change them in specific places over dozens
of iterations if that becomes necessary. Instead, if I define things like
$headline-color and $highlight-color, I can refer back to those in my header
file, and change them throughout the site simply.

In the case of complex selectors, it becomes vastly more simple. Not only is
your style sheet organized analogously to your dom tree, but it's infinitely
more flexible, and doesn't require duplicate writing in the case of long
chains.

Less/sass are a huge boon to front end development because they help you
manage complexity. That won't come through in simple examples, but it should
be obvious if you've ever written a stylesheet more than a few hundred lines
long.

~~~
Kiro
"Working with really long class names or IDs isn't an option."

How does SASS/LESS solve this? Don't you still need the class names and IDs to
hook it up with the DOM?

~~~
Recoil42
Yes. My point is that you avoid namespace conflicts.

Say you're building a windows-style scrollbar:

    
    
                    |-> up arrow button
        scrollbar --|-> track -> drag button
                    |-> down arrow button
    

Rather than having a CSS file (1) full of long, convoluted global class names:

    
    
        .scrollbar-frame{}
        .scrollbar-button-up{}
        .scrollbar-button-down{}
        .scrollbar-track{}
        .scroolbar-track-drag-button{}
    

or (2) full of overly-verbose endless trails (imagine how this gets when
you're working with a complex object 5-6 levels deep)

    
    
        .scrollbar-frame{}
        .scrollbar-frame > .button-up{}
        .scrollbar-frame > .button-down{}
        .scrollbar-frame > .track{}
        .scrollbar-frame > .track > .drag-button{}
    
    

you can do this:

    
    
        .scrollbar-frame{
            .button-up{}
            .button-down{}
            .track{
                .drag-button{}
            }
        }
    

On compilation, you'll end up with a final result somewhat like example 2 --
but you weren't forced to write your first-level selector over and over the
whole time. Your code also resembles the structure logic much closer at write
time.

It gets better, too. Let's say we wanted to define our buttons in the classic
windows 95/98 style -- grey, with a 1px relief border. In the classic CSS
style, using example 2 as a pattern, we'd have to do it this way, duplicating
our definitions the whole way:

    
    
        .scrollbar-frame{}
        .scrollbar-frame > .button-up{
            height: 20px; 
            width: 20px;
            background: #ccc;
            border-top: 1px solid #ddd; 
            border-left: 1px solid #ddd;
            border-bottom: 1px solid #888;
            border-right: 1px solid #888;    
        }
        .scrollbar-frame > .button-down{
            height: 20px;
            width: 20px;
            background: #ccc;
            border-top: 1px solid #ddd; 
            border-left: 1px solid #ddd;
            border-bottom: 1px solid #888;
            border-right: 1px solid #888;
        }
        .scrollbar-frame > .track{}
        .scrollbar-frame > .track > .drag-button{
            width: 20px;
            background: #ccc;
            border-top: 1px solid #ddd; 
            border-left: 1px solid #ddd;
            border-bottom: 1px solid #888;
            border-right: 1px solid #888;    
        }
    

However, using SASS/LESS, we could define a mixin. Using SASS, here's how
you'd achieve the exact same thing:

    
    
        //Define a mixin
        @mixin greybtn{
            width: 20px;
            background: #ccc;
            border-top: 1px solid #ddd; 
            border-left: 1px solid #ddd;
            border-bottom: 1px solid #888;
            border-right: 1px solid #888;
        }
    
        .scrollbar-frame{
            .button-up{
                height: 20px
                @include greybtn; //Include our mixin.
            }
            .button-down{
                height: 20px
                @include greybtn;
            }
            .track{
                .drag-button{
                    @include greybtn;
                }
            }
        }
    
    

The resultant code will be almost exactly the same, but you just wrote a lot
less to get there, and will have an easier time of modifying it in the future.
You can see the massive benefit in both speed and organization this allows,
especially on large projects.

~~~
Kiro
This is actually a great argument. I'm almost convinced. However, in the
second example, wouldn't it be better to just have a .scrollbar-frame >
.button with all the styles and then just do class="button up" and
class="button down"?

~~~
coldtea
Yes, but this enables it to be reused in other contexts, where the names "up"
and "down" would not make much sense, but you would like to have the same
border style for some reason.

Plus, you could turn this into a mixin "function", with the actual colors of
the states changed depending on where you include it.

So the way he writes it, you could have a green, blue, whatever version of
those borders, with the same one line (plus a parameter), whereas in CSS you
would have to do:

up-blue, up-red, up-green, down-blue, down-red, down-green etc classes.

------
crazygringo
This level of complexity for images (1x and 2x) is _madness_. And the real
kicker is, it doesn't even account for the kind of variable zooming people do
on their phones, which can result in 1.73x, 2.79x, 4.23x, etc.

I've found it vastly simpler to adopt a much more flexible and simpler
approach. Just include single images (not multiple versions), and pick
resolutions that are appropriate for the image -- that convey the level of
detail the image deserves. And when you up the resolution, knock down the JPEG
quality.

Sometimes this means 3x or 4x for bullets or icons mixed in with body text.
Sometimes it means 1x for photographs. Sometimes it means 3x for small
illustrations and 1.5 for larger ones.

Don't worry about things being pixel-perfect, because pixels don't exist
anymore. Just aim for whatever resolution communicates the necessary meaning
of each element. Good judgment is your friend.

------
kadavy
I realize Paul is doing it for the sake of learning, but that seems like an
insane amount of consideration to display and bandwidth.

I remember seeing an article that argued that you should just serve up big
images, and that slow cellular data networks scale down and optimize images
pretty well already.

Basically it argued that it wasn't worth the trouble. Even with some Googling
I can't seem to dig it up.

Thoughts on this, anyone?

~~~
kalid
I began retina-ifying my website (<http://betterexplained.com>). I'm serving
up the high-res images. Something like a logo should be downloaded once and
cached for a long time.

I have a lot of LaTeX-generated images, which is too painful to set using CSS
rules. Also, for RSS/email readers, they don't have the full stylesheet
available (feed-to-email service), so I want the image dimensions specified
via attributes, not CSS.

~~~
papsosouid
>Something like a logo should be downloaded once and cached for a long time.

The cache on mobile browsers is tiny (4-85MB), your logo will likely only be
cached for that visit. I'm finding sites claiming IOS didn't even have a disk
cache for safari until IOS 6? So in that case it is certainly only getting
cached for one visit.

~~~
kalid
Interesting point, thanks for sharing. I might do CSS targeting for site-wide
images, and leave the in-post images (i.e., the ones coming via email & rss)
with the high-res versions.

------
WickyNilliams
Despite the advice in the article, never use an <img> tag with an empty src
attribute - it causes the page itself to be requested, which is probably a
larger request than just serving up a low res image in the first place.

Otherwise lots of interesting points here, and a lot of thought given to the
fine details a lot of us would otherwise skip over. Good work mate

~~~
PStamatiou
Wicky and I chatted on Twitter -- I think this is only a case for certain
older browsers. Haven't seen an issue with anything like this in recent
browsers in the last few years

~~~
WickyNilliams
I've done some investigation and you're right, it seems that it's been fixed
in the majority of modern desktop browsers. As far as I can tell Chrome, FF,
Opera, Safari and IE (9+) have resolved this issue [1][2][3][4]. Can't find
any data on mobile browsers, haven't got the patience.

[1] [http://www.nczonline.net/blog/2009/11/30/empty-image-src-
can...](http://www.nczonline.net/blog/2009/11/30/empty-image-src-can-destroy-
your-site/)

[2] [http://www.nczonline.net/blog/2010/03/16/empty-string-
urls-i...](http://www.nczonline.net/blog/2010/03/16/empty-string-urls-in-html-
a-followup/)

[3] [http://www.nczonline.net/blog/2010/07/13/empty-string-
urls-b...](http://www.nczonline.net/blog/2010/07/13/empty-string-urls-browser-
update/)

[4] <https://code.google.com/p/chromium/issues/detail?id=38144>

------
danso
I've loved this series, it shows how complex web-design has become but has a
considerable amount of actionable information on what the latest
libraries/hacks available are.

It's also a bit deflating. Just when you thought the kind of arcane knowledge
needed to survive the IE-compatibility-era was over, the explosion of new
resolution and screen types have made web dev -- even just the design and
display side -- something with considerably more moving parts than I remember
from ten years ago.

------
niggler
Do people just scale down the 2x icons to create the 1x series or actually
change the icons (emphasizing certain aspects in the 1x version)? Based on my
experience on the rMBP, it seems as if the icons are actually different.

~~~
roc
The people who currently care about retina-friendly graphics tend to be those
who have long cared about carefully hand-tweaking every variant-scaled version
of every graphic they produce.

But as hi-dpi concerns become more mainstream, I doubt there will as much
overlap and we'll see a lot more naive scaling.

