Transcript
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Silence ]
>> Good morning, everyone.
>> Good morning.
>> Hey, [applause] it's great
to see some hardcore web people
here, especially on, you know,
the morning after the beer bash.
So I know you're all
hardcore if you're here.
And welcome to the
Designing Responsive Web
Experiences session.
My name is Casey.
>> And I'm Ted.
>> And today we're going to
show you how you can build one
website that's going to
look great everywhere.
And by the way, any
time that we say
"website" during this
session, we mean any web media.
I'm on the iBooks team.
>> And I'm on the WebKit team.
>> And we want both your
digital books and your websites
to look great everywhere.
So we don't have to tell you
that your website is being
viewed on a whole variety
of different devices
and screen sizes.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of different devices
and screen sizes.
What we can do, though, is teach
you some really easy techniques
that you can use to ensure
that your website looks
great on all of these.
I want to be very clear, though.
What we are not going to talk
about today is building
multiple versions
for each of these devices.
In fact, today's session,
it is the antithesis
of the mobile-specific site.
There will be no
m.domainname here.
So instead, we're going
to build one website
that looks great
on all of these.
And a site that has a design
that can adapt and adjust
to always look good on all
of these different devices is
usually referred to as a website
that has a responsive design.
A responsive design, it's
just-it's just a buzzword.
It just means that your website
is sensitive to its environment,
which will allow it
to adapt and change
and just simply always
look good.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and just simply always
look good.
And so today, Ted
and I are going
to show you not only what a
simple idea a responsive design
is, but really how
simple it is to implement.
We're going to look
at responsive columns.
Columns are a really great way
to both add some visual interest
to your website as well
as improve the legibility
of your site.
We'll also teach you
about font-relative units
and how you can use
them to make sure
that your layout has
fidelity at every font size.
And then Ted's going to show
you how you can use CSS Shapes
to wrap text around
images, and we'll make sure
that those images
are Retina ready.
And for the larger design
changes that we need to make,
we'll use media queries.
And finally, the finishing
touch will be hairlines,
where we can really dive
in deep and make use
of those beautiful
Retina screens.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So why are we talking
about this anyway?
You know, WebKit does a really
great job of making sure
that your website looks
just as great on the iPhone
as it does on the desktop.
It just shrinks your site down
and makes it fit on
the phone screen.
And then the user can double tap
or pinch to zoom in to make sure
that they can read that text.
The text becomes
larger that way.
And it looks great.
It's not a lot of work for you.
And WebKit does the same
thing for more complex sites,
like this one that
Ted and I made.
It just shrinks all
that formatting
and layout down into one screen.
And that seems great, right?
Can you read that text?
Barely? At all?
Not really, and many
mobile designers
or website designers have
looked at this and said,
"Pshht, I can't have that.
I'm going to have to make
a mobile-specific site."
You know, we get it.
You want your website to
look great, and you want it
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
You want your website to
look great, and you want it
to be clear and easy to read
without your users having
to double-tap and pinch
to zoom in and pan around.
And some of you may
be thinking, "Well,
of course it doesn't look great.
You need to add a
meta viewport," right.
And that's a great first step.
A meta viewport's going
to make your text larger
in relation to the screen size.
But the thing is is that
your layout is still all tiny
and shrunk down.
So now you've got these big
words in a shrunk down layout,
and it just -- it
looks awful, right.
So lest you think, "OK, Casey,
no, really, we're going to have
to make a mobile-specific
site now," please keep in mind
that we're not building
websites for just the iPhone,
the iPad, the desktop.
And to prove this, if you
were to look at our website
on the desktop, looks
great, right?
We designed it for this
window size basically.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
But if I shrink down
the window, ooh,
I've got the same problem
here that I do on the phone.
So we need to make sure
that we're building a site
that looks great no matter
what our window size.
So, so far I've laid out
just a whole lot of no's.
I've said, "Well, you can't
make a mobile-specific site.
Using a meta viewport
isn't going
to get you all the way there.
And you have to build
a website that works
for every single possible
permutation on the desktop."
So what can we do?
>> Well, hold on.
Our goal here is to use
some simple responsive
design techniques.
And it seems like the
best way forward is just
to identify specific problems
that we're seeing right now
and just work through
them one at a time.
>> Sounds good.
>> I mean, the first one that's
obvious to me is that masthead
up top becomes so tall
on the phone that I have
to scroll to see any content.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to scroll to see any content.
>> And the other thing is is
those columns are just really
skinny like so it's
completely illegible.
>> And that caption on our
galaxy is blowing right
out of the image and covering
our initial text there.
>> Yeah, that's pretty horrible.
Where do you think
we should start?
>> I think we should
start with the columns.
Those look really terrible.
>> OK, let's start with columns
'cause I personally really
like columns.
I love that they add both a
visual interest to my website
and that they improve
the legibility.
It's really the perfect
combination
of form and function.
And columns are great for this
because they're able to divide
up big blocks of text
into more legible chunks.
So where I might've had a big
block or really long lines
of text, I'm now able to have
very consumable size, right.
Now, the problem we ran
into with our website
and why those columns
weren't looking good is
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and why those columns
weren't looking good is
because we defined a set number
of columns that had to be there
for every screen size, right.
So when our windows shrunk
down, those columns had
to become really narrow
and we were only able
to have a few words per line.
So to make your columns
responsive,
all we have to do is instead
of defining a column count
or a set number of
columns on our page,
we just define the column width.
So to give you an example of
this, I have two web pages here,
very simplified, of where
one has the columns defined
in column width, one
has the columns defined
by the column count,
like Ted's and my site.
Now when I resize that window
-- resize that window --
the page that we defined
the column width we have
two columns.
And we've maintained
that legible width,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And we've maintained
that legible width,
whereas the column count had to
shrink down like we saw before.
So responsive columns
are really great,
defining the column
width is really great
because WebKit will
automatically add
or eliminate columns as room
becomes available or is removed.
And we recommend when you are
defining your column width
that you use a font-relative
unit.
Font-relative units
are really great
because if your user
resizes their text,
the column's width will
also resize to match that.
So give you a simplified
example.
Here we have the
alphabet, right.
There's five letters
on that first line
of the first column:
A, B, C, D, and E.
Now, because my column's
width is defined
in a font-relative unit,
when I make my text smaller,
I will maintain those five
letters across the top.
And the same thing goes with the
number of words on your column.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And the same thing goes with the
number of words on your column.
You'll maintain a
legible link of words.
So all of this great
functionality,
these responsive columns,
it seems like you're
getting a lot here, right?
It's just one CSS property.
You just define column
width and define it
with the font-relative unit.
In this case we're using 15 rem.
So to show you how great
columns are in real time,
here's Ted with a demo.
>> OK, thanks, Casey.
Here we are.
So here's this website
that Casey and I built,
and it's looking pretty
great at this-wow,
that scrolls really
fast-at this window width.
But as you saw, when we
make it more narrower,
the columns start getting harder
and harder to read until a point
where you hit here and
it's just very illegible.
So you can see up in the
corner I have a little bit
of JavaScript showing you
what the window width is
so I can make adjustments
as necessary.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
so I can make adjustments
as necessary.
So as Casey suggested, let's try
setting our column width instead
of our column count.
So over here in Xcode, you can
see I have the column count
of 3.
Just kill that and replace that
with setting the column width
to 15 rem like Casey suggested.
We'll save that, we'll hit
reload and nothing's changed.
Our window width is
still wide enough
to accommodate three
columns like we had before.
But this time as
we get more narrow,
we'll hit a point-let's see
where it happens-right,
OK, here.
Right around 1100 pixels we
drop down to two columns.
It's still really legible.
And, again, as we get even
smaller, we'll hit a point right
around 700 and some odd pixels
where we go down to one column,
which, even at the
narrowest window width,
is still a very legible
amount of text.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
is still a very legible
amount of text.
I mean, we're not done; that
sidebar still looks terrible.
But that's really
all you have to do
to get simple responsive columns
with just a single property.
Let's dive a little bit
more into the features
of the CSS columns
column module.
OK, so you've seen
the column count
and column width properties,
which are pretty
straightforward.
When you are laying out
a page with columns,
it's best to have some white
space between the columns.
If you don't, the
lines can run together
and it can be really
hard to read.
And this is controlled with
the column-gap property.
You might want a decorative
line inside that gap.
You can define such a line
with the column-rule property,
whose syntax is just like the
border properties you're used
to using already.
And finally, if you'd
like an element to pop
out of your columns
and span across them,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
out of your columns
and span across them,
you can easily do this with
the column-span property,
which looks really great.
So to sum up, making
responsive columns that adjust
to a different environment
is super easy.
CSS gets you a lot
of that for free
by using the column
width property.
I want to expand a bit,
though, on why we chose
to use a font-relative
unit there.
Font-relative units are
exactly what they sound like.
They're CSS units that
are defined in terms
of your current font size
or some other text metric
that's related to font size.
And it's very common
to use these
to set the font size itself,
but you could also use them
for any part of your
layout whose size should be
proportional to the
current text size.
An obvious example would be the
margins around your paragraphs.
As font size increases,
you'd like those margins
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
As font size increases,
you'd like those margins
to also increase in
proportion to that.
And the big benefit here is
that by using these units,
your layout will automatically
adjust to different font sizes.
Now, you set a font size, but
your user might change it.
They could use Cmd+ and Cmd-
or perhaps they've changed
the minimum font size setting,
which is very common
for low-vision users.
So you should always make your
layout adjust to a font size
that you're not expecting.
There are four font-relative
units in CSS.
There's the em, which I'm sure
you're all very familiar with;
it's very popular,
very common on the web.
And an em is defined in
terms of the font size
of the current element,
which may be inherited
from its ancestors.
Less common is the ex, which
is approximately half an em.
It's really supposed to
be basically the height
of a lowercase letter.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of a lowercase letter.
This is very useful
when you're trying
to size an element
inside a line of text
so that it looks
natural next to the rest
of the text in the line.
The ch is based on the
width of the numeral 0,
which may seem random.
That is a typical character
width, and so you can use it
for sizing an input element
where you're expecting,
say, 30 characters.
You can say 30 ch and it'll be
approximately the right size.
And finally we come to the rem,
which is the unit
that Casey was using.
The rem is just like the em that
you're already familiar with,
but instead of being
based on the font size
of the current element, it's
always based on the font size
of the body, or the
root element.
So why would you want to
use rems instead of ems?
You're already using ems;
they're great for you.
So here's a simple example.
I've got a simple website
with a header, "Hello,"
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I've got a simple website
with a header, "Hello,"
and on the left I've
sized it with ems
and on the right I've
sized it with rems.
OK, so far they're identical,
everything works the same.
Well, a few months from now,
I've made a change
to my website.
I've added a container
element that happens
to have this header
inside of it.
And because someone told me
to use font-relative units,
I went ahead and sized that
font size with ems as well.
So what I expect to happen is
this: I want nothing to change.
But if I had used ems for
my header, what happens?
The browser says, "Oh,
this font size is in ems.
OK, well, what's the
parent font size?
Oh, that's in ems."
And it keeps looking up until
it finds a concrete font size
and then computes this
sort of compound font size.
And so the result is something
way bigger than I intended
when I first sized that
header a few months ago.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Unlike that, in the
case of rems,
it's always looking back
to the body element.
It's skipping its
whole ancestor chain,
so I never have a different
font size than I expected.
OK, so we've taken a quick
look at font-relative units
and why I think the
rem is pretty great.
Let's take a look at our
website and see where we are.
OK, it's looking pretty good.
>> Yeah, that's definitely
better.
We definitely still
have the sidebar there
that is a significant issue.
But I think let's
tackle that one later.
>> All right.
What do you want to do next?
>> Well, so what's kind
of bothering me is all
that white text around
the moon, right,
all that extra white space.
I just-I feel like we're
not making a good use
of the screen real estate, and
it just feels kind of clunky.
>> Yeah, I mean, the whole point
of adjusting our column width
in the first place was to
have nice, readable lines.
And our moon is really
interfering with that.
We have these really narrow
lines of text next to it.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We have these really narrow
lines of text next to it.
>> Definitely.
>> So let's take a look at that.
So to simplify, here's our moon.
We've floated it in our column.
And those lines next
to it, they're floating
around the image element
and they look really narrow.
Well, I don't have a whole
lot of time to fix this,
so the easiest thing
is, you know,
we could just not float the moon
and that way there's no
narrow lines next to it.
It looks pretty good, right?
>> OK, yeah, Ted,
you could do that.
I have a feeling, though,
that you have a much cleverer,
easy solution to that.
And this just kind of
feels like a copout.
>> OK, fair enough.
So with a new feature called
CSS Shapes, which is available
in Yosemite and iOS 8, we
can actually flow that text
around the curvature
of the moon.
It'll look really great.
So what's going on here?
CSS Shapes, it's a simple
feature that allows you
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
CSS Shapes, it's a simple
feature that allows you
to flow text around
a floated element
with an interesting
shape or geometry.
So in this case a triangle
or a circle, like our moon,
or Casey's favorite, Mr. Pacman.
>> Go, Mr. Pacman.
>> So how can we use
this for our moon?
So like we saw before,
we have our moon element.
It's just an image
element of course.
And we've floated it
within our column.
Now, it just so happens that
this image of the moon is
on a transparent background.
And CSS Shapes has a great
feature where you can provide it
with an image and it will
use the visible, or opaque,
part of that image
to define the shape.
You do this with one property.
The property is called
shape-outside,
and in this case we're providing
it the image of the moon.
It'll look into the
image data and say, OK,
here's the opaque part.
And as you can see, our
lines of text are now flowing
around the edge of the moon.
It's that easy.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
It's that easy.
>> Pretty cool, right?
>> Of course.
It's that easy.
[ Applause ]
Of course it's that easy
because I lucked out.
My moon is on a transparent
background already.
But a lot of times it's not.
You have an image
that's entirely opaque
and you don't have the
Photoshop skills to go in
and fix it up; I
certainly don't.
Actually, a lot of
you do, I'm sure.
So what do I do now?
So as you can see, I still have
that shape-outside property,
but this is an opaque moon,
so Shapes doesn't have
anything to go on here.
Fortunately, we can also, in
addition to using an image
of a source of the shape data,
we can simply use some basic
geometric shapes as well.
And of course the moon,
luckily for me, is a circle.
So what I want to do is somehow
tell the CSS Shapes module
to use this circle to
flow the text around.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to use this circle to
flow the text around.
And I do that using
the circle() function.
Pretty straightforward.
It takes one argument,
the radius.
In this case, I used 50 percent
because I wanted the diameter
of the circle to be the full
width of the image element.
And that's looking pretty good.
There are other predefined
shapes.
Just to take one example,
you can use an ellipse.
Of course, an ellipse with
the same dimensions in x
and y is just a circle, so I
really haven't changed anything.
But you can get really
interesting with this too.
There is a polygon function
which allows you define
a fairly arbitrary shape.
So as an example, I drew
an octagon around my moon.
The polygon function takes
just a sequence of x,
y coordinates and, hey, that
looks pretty great actually.
And all of this was
still, again,
with just one CSS property.
OK, cool. We see how easy
it is to use CSS Shapes
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
OK, cool. We see how easy
it is to use CSS Shapes
to get a really great
visual effect
that was basically
impossible to do before.
What do you want to do next?
>> Well, let's take a
look back at our website.
So now we have the text flowing
around our moon really well,
which I think looks much better.
The one thing that
I'm seeing, though,
is those images look
a little fuzzy
on the phone, don't you think?
>> I agree.
I mean, look at that galaxy.
>> Yeah. I definitely
think that we need
to make our site Retina-ready.
>> Yeah. It's all pixelated.
>> Yeah. That's not just
having too many beers
at the beer bash last night.
So let's provide a higher
resolution image for this.
You know, in the past, at
previous WWDCs, we've talked
about how to Retinafy-I think
that's a word, right, Retinafy?
>> Sure.
>> It's a word now;
you can write it down.
We're going to talk about
how to Retinafy your website
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We're going to talk about
how to Retinafy your website
so that you have some
brilliant, clear images
on all of your websites.
And in the past when we've
talked about it, we've talked
about how to use kind of
alternatives to images, so,
you know, one example
of that was like instead
of using an image for a gradient
you should use a CSS gradient,
right?
The one thing we haven't
talked about, though, is how --
like what do I do with
just -- just my photos?
Like if I have a website
with all my photography,
what do I do with that?
We haven't tackled
the image element yet.
What the heck, right?
So new to OS X and iOS 8
we have Image Source Sets.
Image Source Sets let you really
easily add both a standard
resolution image and a
Retina resolution image,
and then WebKit will just
magically pick the right one,
depending on what type of screen
your website's being viewed on.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
depending on what type of screen
your website's being viewed on.
And it looks kind of like this.
So here's my galaxy image
on a standard screen.
It looks pretty good, but
here it is on a Retina screen.
It's pretty pixelated.
So fortunately, it's very,
very easy to fix this.
And all you have to do is just
start with the image element.
So here's my image element.
It should look pretty
familiar to most of you.
It hasn't really changed
since the '90s, right?
But because I'm always look
for an opportunity to text,
I'm going to go ahead
and walk you through it.
So our first attribute in
there is our alt attribute.
Please always include it because
anyone who's using a screen
reader needs to understand
what is going on in this big,
beautiful image you've provided.
And then second, I have
my source attribute,
which is just the
location of the image.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So to make this standard
image element
into an Image Source Set,
all we have to do is add the
source set attribute: srcset.
So inside my source set
attribute is literally a set
of images.
I have my standard galaxy.jpeg
and my super-galaxy.jpeg
for my Retina screens.
And the difference between
those is this modifier of 1x
for standard and 2x
for Retina, right.
So then WebKit can then
automatically understand
which image is for which screen.
Now, some of who you
are actually reading
through my syntax might
have noticed some redundancy
in there.
>> Yeah. You're saying
galaxy JPEG twice.
>> Yeah. So galaxy.jpeg, my
standard resolution image,
is in there two times.
And you might think, "Well,
let's just ditch
the source," right.
But browsers that do not
understand srcset are not going
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
But browsers that do not
understand srcset are not going
to know what to do with that.
So for backwards compatibility,
let's keep the src
and instead we will
back out or remove
that 1x resolution image
from the source set.
So that's like very little
amount of markup, right.
With just this small amount of
markup, we've made our website
and our image element
Retina-ready.
Image source sets
are really great.
They load only the right
image, so you're going
to avoid that double download.
There's no additional CSS.
You don't have to
go in there and muck
around with your dimensions
or anything like that.
And it's backwards compatible
with just this little amount
of syntax, this one attribute.
So, so far I've talked to you
about image source
sets in your HTML.
It just so happens that there is
another feature that we talked
about at WWDC in the past that
has an incredibly similar name
and an incredibly
similar function.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and an incredibly
similar function.
So we're going to go over
that real quick, too,
so that you can understand
when you use which and why.
So image source sets, which we
just covered, are in your HTML,
but image sets live in your CSS.
And they are intended
for styling your website,
like borders or background
images.
So image sets, let's
say I do have one
of those background images that
I want to make Retina-ready.
I'll just start with
my background image.
You'll see I have my
URL with my galaxy.jpeg.
And to make it into
an image set,
I add a second background
image property.
And within it is the
image-set() function.
And that function then
contains both of my images.
It contains the galaxy
JPEG modified with 1x
and my super-galaxy
JPEG with 2x.
And then WebKit from here
will automatically select the
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And then WebKit from here
will automatically select the
right one.
And I'd like to point out
that you do need to have both
of your background
image properties there
for backwards compatibility.
So image sets, image
source sets.
They're great, they're easy.
They make it super easy
for adding both standard
and Retina images.
WebKit will pick the right one.
Just remember that your
HTML image source sets are
for your content-those big,
beautiful photographs we talked
about-and your CSS image sets
are for your style, so your
background images, your borders.
So I think both are going
to be a really great
solution for your websites.
Should we see where we're at?
>> Yeah. Let's-well,
that looks way better.
Really happy about that.
I was worried that
maybe I had too much fun
at the beer bash last night.
OK, so where are we now?
We've got our Retina image.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And we still have a bunch
of basic layout problems
on this page that we
haven't addressed yet.
>> Yeah. Our Retina
image looks nice,
except that you can't
really see it.
>> Right.
>> It's got that
giant caption over it.
>> It's ridiculous.
>> Yeah.
>> So let's fix up some of
our remaining layout problems
by using CSS media queries.
And I'm sure a lot of you
use these all the time.
So let's just jump
right in and take care
of these remaining issues.
OK, here we are again;
this should look familiar.
You can see the text
loading around that moon now.
It's looking pretty good.
I'm a big fan of that.
OK, let's see, and as you know,
as we make our page narrower,
the layout gets more
and more crazy.
In particular, I don't
like how the masthead
of my page here is taking
up so much vertical space.
This caption is really
awkwardly overlapping my image.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
This caption is really
awkwardly overlapping my image.
In fact, it's blowing
right out of it
and overlapping the
heading below it.
And then the sidebar is really,
really narrow and hard to read.
So let's fix each of these.
I'll start with the header.
So as you can see up in the
corner, like I mentioned,
I have that handy
bit of JavaScript
to show me how wide
my window is.
So where does the
header start to go off?
It seems like between
650 and 700 pixels,
somewhere around there,
we hit multiple lines.
And as you saw earlier on
the phone, we end up with
like four lines of text.
So I want to adjust the size
of my header somewhere around,
what, 690 pixels or something.
OK, so let's do that.
To do this, I'm going
to use the @media rule.
So here I have an @media rule.
This is the part of CSS where
you can provide a media query,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
This is the part of CSS where
you can provide a media query,
in this case a max-width
of 675 pixels.
And then inside of braces you
basically provide a whole style
sheet of things you'd like
to change at that point.
In this case, I'm finding
that masthead header
and adjusting its
font size down.
OK, so we've made that change.
Let's refresh.
Nothing changed because
this is wider
than that breakpoint
of 675 pixels.
So let's make our site more
narrow, and there we go.
Our header got smaller,
it looks great even here
at this very narrow size.
Well, OK, next I think I'll
take care of this caption.
So just like with the
header, I need to figure
out where it starts looking bad.
It looks great out
here at two lines.
I'm still pretty
happy with it here.
And it seems to be right around
where it goes to four lines
where that bottom right corner
is intruding into my galaxy
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
where that bottom right corner
is intruding into my galaxy
and really kind of
ruining the mood.
OK, so where was that?
That seems to be between
700 and 750 pixels.
OK, so just like with my
header I'll use an @media rule,
this time with a
max-width of 750 pixels.
And what I'm doing here
is initially my caption is
absolutely positioned so
that it can be an overlay
on top of my image.
And its width is set at 50
percent so that it takes
up about half the size
of the image, like so.
So in my media query here,
I want to override both the
position and width properties
so that it will simply appear
below the image and take
up the full width of the column.
And that's it.
So we'll save and let me come
out a little bit and refresh.
And as you can see, just
like before nothing's changed
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And as you can see, just
like before nothing's changed
because I'm still wider than
that media queries test.
But as we get closer
to the bad part,
there it goes; it pops down.
It's quite legible below our
image and doesn't interfere
with it, no matter how narrow
our window screen gets.
OK, cool. Let's take
care of that sidebar.
That's I think the last bit
that looked pretty
bad at a narrow size.
So where does that
get unreadable?
In this case, I feel
like right around here is
where the block quote inside
my sidebar is getting to be,
you know, one or
two words per line.
It's really too narrow.
So let's make an adjustment
around 800, 850 pixels.
By now I think you
know the drill.
This adjustment is exactly
like the other ones.
We have an @media rule
for a width of 800 pixels.
Currently, this sidebar
is floated over,
so I'm disabling the float
just like with my caption.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
so I'm disabling the float
just like with my caption.
I'm resetting the width
so it will automatically be
the width of its container.
And I'm killing some of the
margins that we had there
so that the sidebar
will be offset
from the columns next to it.
So if we come back and
refresh, still there.
But as we get smaller, there
we go, the sidebar is popped in
and is now in line with
the rest of our document.
And even in the really,
really narrow screen size this
is starting to look pretty good.
OK, so let's talk a little
bit more about media queries.
As you saw, we use media queries
in CSS by using an @media rule,
which takes a media query to
test and then some CSS to apply
when that media query matches.
So here, I'm fixing our
caption like we saw earlier
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So here, I'm fixing our
caption like we saw earlier
by using a max-width
media query,
and then I'm overriding the
position and width properties.
This is in general how
you use an @media rule.
You have some rules somewhere
else in your style sheet
and then you say, OK, but
and sometimes I need
to override those.
In all three cases, we used
the max-width media query
because we were adjusting
for when things got narrower.
There are several other media
queries that you'll often want
to use when doing
responsive design.
There's a corresponding
min-width media query
where you can adjust things
as the site gets wider.
And also an exact-width
media query.
When you're adjusting your
site to be Retina-ready,
in addition to using
the features
that Casey showed you
earlier, you might need
to make some layout adjustments.
And you can test
for a Retina device
by using the device-pixel-ratio
media query, which,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
by using the device-pixel-ratio
media query, which,
just like width, takes
a min and max variance.
When adjusting your
layout with a media query,
there's a few things
you should keep in mind.
First off, the @media
rule is actually a very
blunt instrument.
What you're doing is making an
entire alternate style sheet
that applies in certain
circumstances.
You have to duplicate the
selectors you're using
in your default style sheet to
override particular properties.
And as your site
grows, this can lead
to a really large
maintenance burden.
You might double or triple
or quadruple the size
of your style sheet.
So instead, when possible, you
should try to use CSS features
that naturally adapt
your site without having
to duplicate all your work.
We saw two earlier: The column
width property allowed us
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We saw two earlier: The column
width property allowed us
to adjust the number of
columns magically basically
without resorting
to a media query.
And the image set
function allows us
to pick the right image for
our display without having
to use the device-pixel-ratio
property media query.
And secondly, when I was
adjusting our layout there,
I was doing it experimentally.
I loaded my site, fiddled
with my window width and found
where each part of
my layout went bad
and then made adjustments
for that width.
I didn't look up the dimensions
of a particular screen
on Wikipedia.
I let my content
actually tell me
where it needed to be adjusted.
This will make your
content more resilient
to an ever-increasing
range of scenarios
where it might be loaded.
OK, so we've made our
final layout adjustments
with some media queries.
There's just one
little bit I wanted
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
There's just one
little bit I wanted
to address before we
can call it a day.
And this is some of these
borders on our site.
So you can see up top there
we have this little byline
of "This is the Friday edition
of the Daily Space Digest,"
and we've got some
borders around it.
And they look great
on my laptop,
but they're a little
thick on my phone.
I made a 1 pixel
border and I wanted it
to be a 1 pixel border, but of
course, as you already know,
when I say 1 pixel in CSS,
I don't actually get
1 pixel on my display.
The CSS pixel is defined to be
a sort of abstract measurement
that roughly corresponds
to 1 physical pixel
on a pre-Retina display.
But now, with the Retina device,
a 1 CSS pixel actually
contains 4 device pixels.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
a 1 CSS pixel actually
contains 4 device pixels.
So what I want to do is sort
of reach into the CSS pixel
and make full use of each
of those device pixels.
I want to draw hairline borders.
OK, so right now I'm drawing
my border with 1 pixel in CSS.
And when that draws
on a standard display,
I get the thinnest line
I could possibly get.
And on a Retina display, I
get this line that's twice
as thick as I actually want.
So what I want to do is really
only use 1 row or column
of device pixels
to get this line.
So how do I do it?
Let's look at our CSS.
Here, I'm setting my
border with 1 pixel.
I'm not the only one who's
wanted hairline borders;
a lot of you have too.
And I've got to say, some of
the solutions people have come
up with are amazing
and horrifying.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
up with are amazing
and horrifying.
Here's my favorite.
This is pretty brilliant.
It uses an inline SVG
image and a data URL
as your background image.
Everyone got that?
It's really easy to
remember how to type this,
as I'm sure you can see.
All right.
Let's cut this out;
this is ridiculous.
And now, I'm really pleased to
say that in Yosemite and iOS 8,
WebKit has enabled a feature
that we call subpixel layout.
Now, mostly, this won't affect
what you're doing at all.
It's just a magical,
under-the-hood improvement
that just makes things
a little bit better.
But we can take advantage of
it to get the hairlines we want
without having to do
this sort of thing.
OK, how do we do it?
So here we have our 1 pixel
for our standard display.
And now, just like we saw
before with our media queries,
we're going to check
device-pixel-ratio to see,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
we're going to check
device-pixel-ratio to see,
are we on a Retina screen?
We are? Great.
And all we're doing is saying
we're on a Retina display,
great, just use a half a pixel.
Remember, the CSS pixel is 2
device pixels in each dimension,
so a half a pixel corresponds
to that beautiful,
thin device pixel.
And now I can actually read
this and remember what I meant
when I wrote it,
so that's exciting.
And here we are.
I've got my retina iPad.
And if we use the magic of
Keynote to zoom in on that,
you can see those lines are as
thin as they could possibly get.
>> Ooh, aah.
[ Laughter ]
Thanks Ted.
[ Applause ]
All right.
So our website now looks so much
better minus our sad engineering
design skills.
And it looks great
on every device,
and with very little markup.
Like how many lines
of code did we do?
>> I think we actually only
changed about 20 lines of code.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
>> That's pretty good, right?
Yes? Thank you.
[ Applause ]
All we had to do was make
our columns responsive.
We defined the width
of our column instead
of a column count.
We also designed our
layout so that it was
in font-relative units,
which means that if our
users change their font size,
we are going to have
fidelity to our layout.
Also, Ted showed you
how to use CSS Shapes
so that now we have the
text flowing beautifully
around the curvature of our
moon, and both our galaxy
and our moon image
are Retina-ready.
Then, we also covered
how to use media queries,
our blunt instrument for
making larger layout changes
when necessary.
And the icing on the cake are
those beautiful hairline borders
that really reach into
the retina screen.
>> So for more information,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
>> So for more information,
as always you can
contact Apple Evangelism.
And check out our documentation
in the Safari Developer Center
and participate in the
wonderful conversations
over at our Developer Forums.
It's Friday morning, so
our related session was
of course earlier this week.
And if you missed
it, definitely check
out the video; it's
really great.
And we've also talked
about several things
that have come up
in previous WWDCs.
In 2012, we introduced the
image-set function for CSS
in a great talk that goes
in extreme depth into how
to make a content Retina-ready.
It's really, really wonderful.
And then last year,
we introduced several new layout
features, which we didn't go
into here, like CSS
Regions, Flexbox,
and there's some really great
advanced layout you can do
in CSS that will make
your site really great.
And please do check that out.
I know some of you traveled
from quite far to be here.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I know some of you traveled
from quite far to be here.
I hope you have a
safe travel home.
>> Thanks, everyone.