One of the first things a software engineer learns is “don’t reinvent the wheel”. If something is already made, use that instead of writing your own. “Stand on the shoulders of giants, they know what they’re doing better than you”. Writing your own tools and libraries, even when one already exists, is labelled “NIH syndrome” and is considered quite bad.
If you’ve used definition lists (<dl>
) you’re aware of the problem. By default, <dt>
s and <dd>
s have display:block
. In order to turn them into what we want in most cases (each pair of term and definition on one line) we usually employ a number of different techniques:
- Using a different
<dl>
for each pair: Style dictating markup, which is bad - Floats: Not flexible
display: run-in;
on the<dt>
: Browser support is bad (No Firefox support)- Adding a
<br>
after each<dd>
and setting both term and definition asdisplay:inline
: Invalid markup. Need I say more?
If only adding <br>
s was valid… Or, even better, what if we could insert <br>
s from CSS? Actually, we can!
My first article in ALA was published today, read it here:
Every time you call a proprietary feature “CSS3”, a kitten dies
Some comments about it on twitter:
Vendor prefixes, the CSS WG and me
The CSS Working Group is recently discussing the very serious problem that vendor prefixes have become. We have reached a point where browsers are seriously considering to implement -webkit- prefixes, just because authors won’t bother using anything else. This is just sad. 🙁 Daniel Glazman, Christian Heilmann and others wrote about it, making very good points and hoping that authors will wake up and start behaving. If you haven’t already, visit those links and read what they are saying. I’m not very optimistic about it, but I’ll do whatever I can to support their efforts.
And that brings us to the other thing that made me sad these days. 2 days ago, the CSS WG published its Minutes (sorta like a meeting) and I was surprised to hear that I’ve been mentioned. My surprise quickly turned into this painful feeling in your stomach when you’re being unfairly accused:
tantek: Opposite is happening right now. Web standards activists are teaching people to use -webkit- tantek: People like Lea Verou. tantek: Their demos are filled with -webkit-. You will see presentations from all the web standards advocates advocating people to use -webkit- prefixes.
Try to picture being blamed of the very thing you hate, and you might understand how that felt. I’ve always been an advocate of inclusive CSS coding that doesn’t shut down other browsers. It’s good for future-proofing, it’s good for competition and it’s the right thing to do. Heck, I even made a popular script to help people adding all prefixes! I’m even one of the few people in the industry who has never expressed a definite browser preference. I love and hate every browser equally, as I can see assets and defects in all of them (ok, except Safari. Safari must die :P).
When Tantek realized he had falsely accused me of this, he corrected himself in the #css IRC room on w3.org:
[17:27] <tantek> (ASIDE: regarding using -webkit- prefix, clarification re: Lea Verou - she's advocated using *both* vendor prefixed properties (multiple vendors) and the unprefixed version after them. See her talk http://www.slideshare.net/LeaVerou/css3-a-practical-introduction-ft2010-talk from Front-Trends 2010 for example. An actual example of -webkit- *only* prefix examples (thus implied advocacy) is Google's http://slides.html5rocks.com/ , e.g. [17:27] <tantek> http://slides.html5rocks.com/#css-columns has three -webkit- property declarations starting with -webkit-column-count )
That’s nice of him, and it does help. At least I had a link to give to people who kept asking me on twitter if I was really the prefix monster he made me out to be. 😛 The problem is that not many read the IRC logs, but many more read the www-style archives. Especially since, with all this buzz, many people were directed into reading this discussion by the above articles. I don’t know how many people will be misled by Tantek’s uninformed comment without reading his correction, but I know for sure that the number is non-zero. And the worst of all is that many of them are people in the CSSWG or in the W3C in general, people who I have great respect and admiration for. And quite frankly, that sucks.
I don’t think Tantek had bad intentions. I’ve met him multiple times and I know he’s a nice guy. Maybe he was being lazy by making comments he didn’t check, but that’s about it. It could happen to many people. My main frustration is that it feels there is nothing I can do about it, besides answering people when they take the time to talk to me about it. I can do nothing with the ones that won’t, and that’s the majority. At least, if a forum was used over a mailing list, this could’ve been edited or something.
Moving an element along a circle
It all started a few months ago, when Chris Coyier casually asked me how would I move an element along a circle, without of course rotating the element itself. If I recall correctly, his solution was to use multiple keyframes, for various points on a circle’s circumference, approximating it. I couldn’t think of anything better at the time, but the question was stuck in the back of my head.
A while ago, I posted about how to use steps()
as an easing function to create a typing animation that degrades gracefully.
Today I decided to simplify it a bit and make it more flexible, at the cost of browser support. The new version fully works in Firefox 1+ and IE10, since Opera and WebKit don’t support the ch unit and even though IE9 supports it, it doesn’t support CSS animations.
This project started as an attempt to improve dabblet and to generate data for the book chapter I’m writing for Smashing Book #3. I wanted to create a very simple/basic testsuite for CSS3 stuff so that you could hover on a e.g. CSS3 property and you got a nice browser support popup. While I didn’t achieve that (turns out BrowserScope doesn’t do that kind of thing), I still think it’s interesting as a spin-off project, especially since the results will probably surprise you.
How it works
css3test (very superficially) tests pretty much everything in the specs mentioned on the sidebar (not just the popular widely implemented stuff). You can click on every feature to expand it and see the exact the testcases run and whether they passed. It only checks what syntax the browser recognizes, which doesn’t necessarily mean it will work correctly when used. WebKit is especially notorious for cheating in tests like this, recognizing stuff it doesn’t understand, like the values “round” and “space” for background-repeat, but the cheating isn’t big enough to seriously compromise the test.
Whether a feature is supported with a prefix or not doesn’t matter for the result. If it’s supported without a prefix, it will test that one. If it’s supported only with a prefix, it will test the prefixed one. For properties especially, if an unprefixed one is supported, it will be used in all the tests.
Only stuff that’s in a W3C specification is tested. So, please don’t ask or send pull requests for proprietary things like -webkit-gradient() or -webkit-background-clip: text; or -webkit-box-reflect and so on.
Every feature contributes the same to the end score, as well as to the score of the individual spec, regardless of the number of tests it has.
Crazy shit
Chrome may display slightly different scores (1% difference) across pageloads. It seems that for some reason, it fails the tests for border-image completely on some pageloads, which doesn’t make any sense. Whoever wants to investigate, I’d be grateful.
Edit: Fixed (someone found and submitted an even crazier workaround.).
Browserscope
This is the first project of mine in which I’ve used browserscope. This means that your results will be sent over to its servers and aggreggated. When I have enough data, I’m gonna built a nice table for everyone to see 🙂 In the meantime, check the results page.
It doesn’t work on my browser, U SUCK!
The test won’t work on dinosaur browsers like IE8, but who cares measuring their CSS3 support anyway? “For a laugh” isn’t a good enough answer to warrant the time needed.
If you find a bug, please remember you didn’t pay a dime for this before nagging. Politely report it on Github, or even better, fix it and send a pull request.
Why did you build it?
To motivate browsers to support the less hyped stuff, because I’m tired of seeing the same things being evangelized over and over. There’s much more to CSS3.
Current results
At the time of this writing, these are the results for the major modern browsers:
- Chrome Canary, WebKit nightlies, Firefox Nightly: 64%
- Chrome, IE10PP4: 63%
- Firefox 10: 61%
- Safari 5.1, iOS5 Safari: 60%
- Opera 11.60: 56%
- Firefox 9: 58%
- Firefox 6-8: 57%
- Firefox 5, Opera 11.1 – 11.5: 55%
- Safari 5.0: 54%
- Firefox 4: 49%
- Safari 4: 47%
- Opera 10: 45%
- Firefox 3.6: 44%
- IE9: 39%
Enjoy! css3test.com Fork css3test on Github Browserscope results
Why tabs are clearly superior
If you follow me on twitter or have heard one of my talks you’ll probably know I despise spaces for indentation with a passion. However, I’ve never gone into the details of my opinion on stage, and twitter isn’t really the right medium for advocacy. I always wanted to write a blog post about my take on this old debate, so here it is.
Tabs take up less space
Yes, this might be an insignificant difference after gzipping and a nonexistent one after minification. But it means you need these processes to keep your code size reasonable. You depend on them, for no reason. Comments for example are useful, and it’s worth having them even if you knew you couldn’t minify or gzip your code. Tabs could do the same thing as spaces, so you’re just bloating your code for no reason.
Tabs can be personalized
The width of a tab character can be adjusted per editor. This is not a disadvantage of tabs as commonly evangelized, but a major advantage. People can view your code in the way they feel comfortable with, not in the way *you* prefer. Tabs decouple the code’s presentation from its logic, just like CSS decouples presentation from HTML. They give more power to the reader rather than letting the author control everything. Basically, using spaces is like saying “I don’t give a rat’s ass about how you feel more comfortable reading code. I will force you to use my preferences because it’s my code”.
Tabs are better for collaboration
Personalization is incredibly valuable when a team is collaborating, as different coders can have different opinions. Some coders prefer their indents to be 2 spaces wide, some coders prefer them to be 4 spaces wide. Rather than manually or automatically converting the code post-pull, and then back pre-commit, it would be adjusted automatically, depending on the editor’s tab-width setting, so every coder could start editing right away, with their favorite type of indent.
You don’t depend on certain tools
When using spaces, you depend on your editor to hide the fact that an indent is actually N characters instead of one. You depend on your editor to insert N spaces every time you press the Tab key and to delete N characters every time you press backspace or delete near an indent. When you have to use something that’s not your editor (for example when writing a snippet of code on a webapp that embeds something like codemirror) you will have to face the ugliness of your decision. Especially with codemirror, everyone else will have to face the ugliness of spaces too, as it converts tabs to spaces 🙁
Tabs are easy to select
Assume for some reason you want to select all indents and double them or convert them to spaces. This is very easy with tabs, because that’s their sole meaning. Tabs were invented for this sort of thing. Spaces on the other hand, have many meanings, so you can’t just find & replace space characters. And how do we usually call the practice of using things for a different purpose than they were made for? Yup, that’s right, using spaces for indentation is a hack.
Code indented with tabs is easier to copy & paste
As pointed out by Norbert Süle in the comments, when you copy and paste code that’s indented with spaces, you have to manually adjust the indentation afterwards, unless the other person also happens to prefer the same width indents as you. With tabs, there is no such issue, as it’s always tabs so it will fit in with your (tabbed) code seamlessly. The world would be a better place if everyone used tabs.
But what about the web? Tabs are super wide there!
This used to be a big problem, and even the enlightened coders that prefer tabs usually convert them to spaces before posting code online. However, CSS3 solves this problem, with the tab-size property. It’s supported by Opera, Firefox and very soon by WebKit too. It also degrades gracefully: The code is less pretty, but still perfectly readable.
Are spaces always evil?
Spaces are the best choice for aligning, rather than indenting. For example, in the following code snippet:
var x = 10, y = 0;
you need 4 spaces to make the variables line up. If you used tabs, they would only line up when the tab width is 4 and the formatting would look messed up in every other case. However, if this code snippet was also indented, the indents could (and should) still be tabs.
Another example is aligning CSS3 properties with different vendor prefixes. The indent should be done with tabs, but the aligning with spaces, like so:
div {
-webkit-transition: 1s;
-moz-transition: 1s;
-ms-transition: 1s;
-o-transition: 1s;
transition: 1s;
}
It’s just a pointless detail, are you seriously that obsessed?
Um, ok I am exaggerating a bit when I say how spaces suck. I do think they suck, although I admit the world has much bigger problems than coders who use spaces for indentation.
For example, coders that don’t name their variables properly. Or the ones that prefer Emacs over Vim 😉
Further reading
- Indentation With Spaces Considered Harmful
- Tabs vs spaces for code indentation
- Why I love having tabs in source code
- Tabs vs spaces
- Relevant: Elastic tabstops
Update: More reasons from commenters
- Tabs reduce typing effort (Yes, editors will insert groups of spaces automatically when you press tab, but cursor movement and deletions must be done one at a time).
- Tabs make typing consistent – inserting/deleting/moving past an indent is always a single keypress. With spaces, one keypress creates an indent, but then you need to press delete an *indeterminate number of times* to remove the indent. That means I have to watch what I’m doing and press delete until my cursor lines up with the previous line, or (3) occurs.
- Tabs are indivisible. With spaces it is easy to end up on a non-tab column, and then you have either messy code or waste time tidying up the indentation. Tabs eliminate this problem by “snapping” code to the correct indentation column automatically.
My new year’s resolution
Warning: Personal post ahead. If you’re here to read some code trickery, move along and wait for the next post, kthxbai
Blogs are excellent places for new year’s resolutions. Posts stay there for years, to remind you what you’ve been thinking long ago. A list on a piece of paper or a file in your computer will be forgotten and lost, but a resolution on your blog will come back to haunt you. Sometimes you want that extra push. I’m not too fond of new year’s resolutions and this may as well be my first, but this year there are certain goals I want to achieve, unlike previous years were things were more fluid.
So, in 2012 I want to…
- Land my dreamjob in a US company/organization I respect
- Get the hell out of Greece and move to the Bay Area
- Strive to improve my english even more, until I sound and write like a native speaker
- Find a publisher I respect that’s willing to print in full color and write my first book.
- Stop getting into stupid fights on twitter. They are destructive to both my well-being and my creativity.
- Get my degree in Computer Science. This has been my longest side project, 4 years and counting.
What we still can’t do client-side
With the rise of all these APIs and the browser race to implement them, you’d think that currently we can do pretty much everything in JavaScript and even if we currently can’t due to browser support issues, we will once the specs are implemented. Unfortunately, that’s not true. There are still things we can’t do, and there’s no specification to address them at the time of this writing and no way to do them with the APIs we already have (or if there is a way, it’s unreasonably complicated).
We can’t do templating across pages
Before rushing to tell me “no, we can”, keep reading. I mean have different files and re-use them accross different pages. For example, a header and a footer. If our project is entirely client-side, we have to repeat them manually on every page. Of course, we can always use (i)frames, but that solution is worse than the problem it solves. There should be a simple way to inject HTML from another file, like server-side includes, but client-side. without using JavaScript at all, this is a task that belongs to HTML (with JS we can always use XHR to do it but…). The browser would then be able to cache these static parts, with significant speed improvements on subsequent page loads.
Update: The Web Components family of specs sort of helps with this, but still requires a lot of DIY and Mozilla is against HTML imports and will not implement them, which is one main component of this.
We can’t do localization
At least not in a sane, standard way. Client-side localization is a big PITA. There should be an API for this. That would have the added advantage that browsers could pick it up and offer a UI for it. I can’t count the number of times I’ve thought a website didn’t have an English version just because their UI was so bad I couldn’t find the switcher. Google Chrome often detects a website language and offers to translate it, if such an API existed we could offer properly translated versions of the website in a manner detectable by the browser.
Update: We have the ECMAScript Globalization API, although it looks far from ideal at the moment.
We can’t do screen capture
And not just of the screen, but we can’t even capture an element on the page and draw it on a canvas unless we use huge libraries that basically try to emulate a browser or SVG foreignObject which has its own share of issues. We should have a Screen Capture API, or at the very least, a way to draw DOM nodes on canvas. Yes, there are privacy concerns that need to be taken care of, but this is so tremendously useful that it’s worth the time needed to go intro researching those.
We can’t get POST parameters and HTTP headers
There’s absolutely NO way to get the POST parameters or the HTTP response headers that the current page was sent with. You can get the GET parameters through the location object, but no way to get POST parameters. This makes it very hard to make client-side applications that accept input from 3rd party websites when that input is too long to be on the URL (as is the case of dabblet for example).
We can’t make peer to peer connections
There is absolutely no way to connect to another client running our web app (to play a game for example), without an intermediate server.
Update: There’s RTCPeerConnection in WebRTC, though the API is pretty horrible.
_________
Anything else we still can’t do and we still don’t have an API to do so in the future? Say it in the comments!
Or, if I’m mistaken about one of the above and there is actually an active spec to address it, please point me to it!
Why would you want to do these things client-side?!
Everything that helps take load away from the server is good. The client is always one machine, everything on the server may end up running thousands of times per second if the web app succeeds, making the app slow and/or costly to run. I strongly believe in lean servers. Servers should only do things that architecturally need a server (e.g. centralized data storage), everything else is the client’s job. Almost everything that we use native apps for, should (and eventually will) be doable by JavaScript.