2015/07/30

A Tweet is not enough

This Monday I did read a new blog post in Surfin' Safari about a new feature that Apple is introducing to make it easy to use the current system font on web pages. For whatever reason I was a little fed up with so many vendor CSS prefixes so I sent a tweet about it, but obviously it's hard to express things correctly on a tweet specially as I'm not an English native speaker and I'm not able to abbreviate things like all of you do because I'm afraid that then it will be even harder to understand what I say.

So after fighting only a little to avoid the characters limit I sent:
The mess caused by vendor prefixes on the wild is not enough, so we have new -apple webkit.org/blog/3709/using-the-system-font-in-web-content/ @jonathandavis
I'm not gonna copy each following message and reply as you can try to read it there, but I would like to point out some parts, a better explanation and say thanks to everyone that contributed as I think that it has helped to talk about the problem caused by the current usage of vendor prefixes.

I'm nobody, I don't work on a big company, I haven't written any book, it takes me too long to write things because I have to try to find the correct words so excuse me if this post has mistakes or it's unreadable, I've tried my best.

What did caused me to send that tweet?
It's known since quite some time that the current usage of vendor prefixes is causing harm in the interoperability between web browsers. Quite a few years ago we had the first browser wars between IE and Netscape where each one tried to defeat the other introducing new features as fast as possible and we all know that IE6 was the winner, so we had so many websites that took advantage of those proprietary features and the "Best viewed with IE" or "You must use IE to view this site" messages that most of us hated with passion.

It took many years to fight and reverse that situation, engineers had to work too many hours finding out the way that things worked and reverse-engineering the specifications. We also keep the perpetual "Mozilla" and "like Gecko" in the User-Agent, but currently this is absolutely getting out of hand.

So going again to a browser monoculture is something that I don't want and anything that points in that direction makes me cringe.

Currently other browsers are trying hard to avoid those same mistakes, experimental features are available only in "Nightly", "beta", toggling a setting in about:flags, using a command line parameter, whatever, ... but the common goal of that approach is to not expose experimental features for broad usage to the public web but the people that want can try it out, give feedback and find out if it solves the problems as expected.

But Apple is not planning to do that, they pointed out that this isn't aimed only at betas (although a day later he replied that it's only in beta at the moment, obvious as there's no final release ATM).

And one part that I found really offensive was this tweet about my comment that Apple doesn't remove the prefixed version of anything that they introduce:
And we will always support them (unlike some vendors that remove things at will). So what is the issue?
with other comments that I found ... we'll I think that it's better to not say what I'm thinking:
You can’t just break sites or apps. Apple doesn’t roll like that. A number of properties changed from prefixed to unprefixed too.
 It is what any company should say that cares about developer and user experience. An API is a contract and guarantee.
Just load the Release notes of any Mac OSX version and search for Deprecated Frameworks and Removed Frameorks.

So it's clear that Apple is able to deprecate and remove APIs even if they were the greatest new innovation at the time, but the obvious difference is that they have full control of the OS (if you don't like what we do, here's the door out), but on the Web they are playing the Embrace, Extend, ... game.

Going back again to the starting point:

Why are vendor-prefixes bad?
I'm not the one stating that, please read carefully this great post by Karl Dubost, take a look at what Mozilla and Microsoft has been forced to do just to have a chance of people using their browsers, and then tell me if this message from @ryosukeniwa is right or wrong:
I don't think proprietary CSS features aren't that bad since they fallback nicely. DOM and JS API are different, ..
But as I said, I'm nobody, please read what Daniel Glazman has to say about the matter. I'm really honored thinking that all of these great people have spent some time reading about my humble tweet, but then I have found out the real reason why I despite vendor prefixes: The CSS working group asked all of us to stand against them for the Open Web and it seems that the message got deep into my head.

That's enough for this post, I have many other things to say because there were lots of tweets and I don't want to mix the things here.



2015/07/19

Creating a responsive Div with proportional dimensions

When you create a responsive layout, you might need sometimes to embed an element (classic example: a YouTube iframe) in a way that it scales down for smaller screens, keeping the aspect ratio.

The way to do that is to wrap that element in a parent div, and control the dimensions of that Div:
<div class="responsive-wrapper"> 
  <iframe></iframe> 
</div>
In the CSS you can then use something like this:
.responsive-wrapper {
    width:100%;
    padding-bottom:37.5%;
    position:relative;
}

.responsive-wrapper iframe {
    position:absolute;
    left:0;
    top:0;
    width:100%;
    height:100%;
}
The trick is that the .responsive-wrapper is a 0 height div, and it has only a padding-bottom defined as a percentage so that means that its total height is really based on the width of its parent.

http://jsfiddle.net/fsmnwefn/

Ok, we all have seen that trick, but: what happens when want to limit the width of the embedded element?
If your page has enough width and the embedded element takes 100% width it might look too big, so you might want to limit its width to 800px for example.

Well, the solution is not really complex after thinking a little: just wrap everything in another div with max-width, that way the total width that .responsive-wrapper will be always limited to our maximum and the height (given by padding-bottom) won't grow as we resize the page.

http://jsfiddle.net/fsmnwefn/2/

Anyway, defining the padding as a percentage ( = desiredHeight * 100 /desiredWidth) doesn't look nice to me, I wanted to be able to use only defined widths and heights.

What I want is the intrinsic behavior that img has, so that we can define width and height as well as max-width, max-height.

There's a solution for this using vw units, that way the element will keep the aspect ratio, but it's gonna be messy again to keep a maximum width that works correctly in mobile: if you work only with the .responsive-wrapper and try to set max-width:800px you can add now max-height:300px for example, but if you have set width:100vw then the element will create an horizontal scroll as soon as you keep some margin on its sides.

So you still need to keep that extra wrapper div.

But there's another interesting solution, why don't we use an image to give us that ratio automatically? This idea is explained on StackOverflow by Elliot Richerson 

It's good to have different options and I find this one interesting, you just need to add an image with the aspect ratio that you want as the first element of .responsive-wrapper and with width:100%, height:auto and then you can apply the max-width/height to .responsive-wrapper itself.

Obviously this still forces us to add an extra element and now you have an extra http request to download that image, that you have to recreate for every aspect-ratio that you need.

And then I thought: Would it be possible to create such image on the fly?
At the moment I'm working with javascript (not only static html), so my crazy mind starts to think: I can use a data-url, and even I can try to find out what's the basic structure of a .gif and create a fake one with the dimensions that I want, then base64 encode it and use it as the src of the image.

Wait a minute man! that's too much work, we're in 2015, you can just create a canvas, set it to the desired size and get its content as data-url without the need to find out how to create a .gif or .png

But, but...
Yes, I can use a canvas instead!

so the new trick is to use a <canvas height="300" width="800"> and then in the CSS
.responsive-wrapper {
    width:100%;
    max-width:800px;
    position:relative;
}

.responsive-wrapper iframe {
    position:absolute;
    left:0;
    top:0;
    width:100%;
    height:100%;
}

.responsive-wrapper canvas{
    width:100%;
    height:auto;
} 
The nice part of this solution is that you can use whatever units you want, and the aspect ratio is defined in the HTML, so you can use this class with different elements and even add other media queries for whatever other effect you might need.

http://jsfiddle.net/fsmnwefn/3/