Video for Everybody is very simply a chunk of HTML code that embeds a video into a website
using the HTML5 <video> element which offers native playback in Firefox
3.5, Safari 3 & 4, Google Chrome and an increasing number of other browsers:
This is native OGG video playback in Firefox 3.5 (you get H.264 playback in Safari). No
plugins to install. The video is played by the browser itself. It loads quickly and doesn?t threaten to crash your
browser.
In other browsers that do not support <video>, it falls
back to QuickTime.
(which allows playback on the iPhone)
If QuickTime is not installed, Adobe Flash is used:
You can host locally or embed any Flash file, such as a YouTube video.
Finally, if all else fails, the placeholder image is shown and the user can download the video using the links
provided.
This is all done without JavaScript and requires only two video encodes, one OGG file for Firefox
3.5, and one MP4 file for everything else (Flash / Safari / iPhone). Instructions
on how to convert your videos to these formats with the correct settings are provided
further down this article.
It?s compatible with HTML 4, HTML5 (valid markup), XHTML 1 and additionally
also works when served as application/xhtml+xml.
The market is made up of more OSes, browsers and processor architectures than
it was five years ago. More people (especially geeks) are browsing with AdBlock / NoScript
/ FlashBlock than ever before. We can no longer just assume people are going to have Flash
and are allowing you to use it.
The same rules apply to video. If my platform / device / browser of choice cannot see your video, or you do not
offer me the means to download the video to view offline, then I don?t see whatever it is you?ve got to show me.
I therefore want to help all web-developers get to grips with
<video>, to make it easy for them to show video content
without having to sacrifice legacy browsers, nor ask you to install anything just to do so.
Starting Off on the Wrong Foot:
I see a problem with how people are beginning to offer HTML5 video. Whilst it is fantastic that
DailyMotion and
YouTube are experimenting with HTML5 there are a
number of primary things content providers must satisfy for HTML5 video to adhere to the openness it is
purposed for.
Not treated like a special case
No special page you have to visit. No extra effort should be required on your part to get video your
browser already supports perfectly.
No browser sniffing
Implementations could turn up anywhere, in any form. OGG is open-source open-specification. Serving to only
mainstream browsers like Firefox 3.5 goes against the whole point of open-video removing the
requirement to be tied to one particular vendor.
Don?t require JavaScript
Developers generally don?t know how to include the video tag whilst falling back to alternatives. Trying
to detect browsers using JavaScript and writing the <video> element into the page is
just going about it the wrong way.
Video for Everybody specifically solves these problems.
It:
Allows content producers to provide HTML5 video as an equal citizen
The same code is used for browsers that support <video>, as well as
QuickTime and Flash. No special copy of your website has to be setup, no options
have to be ticked. Video for Everybody plays the right file for the right level of support the
user?s browser provides.
Degrades extremely gracefully, providing multiple levels of fallback
Using Flash only provides you support for platforms where Flash is installed. No
Flash: No Video. Video for Everybody will most of the time still
play the video even if Flash is not installed. Flash is not supported on the
iPhone, the ?1 platform for users accessing the ?Web on a mobile.
Is just plain copy & paste HTML
Of course, you can write a server side script to insert it over and over again according to however many
videos you have, but the HTML itself does not use JavaScript to insert the video
or detect browsers or even provide the fallbacks. You can enhance Video for Everybody with
JavaScript (it?s just the template to get you started), but the core selection of which
video format plays is completely down to the browser, no JavaScript involved.
The Code
There?s nothing particularly new about this, people have been doing object-fallback
for ages now, however this is an attempt at
including HTML5 video into the mix, as well as trying to degrade as gracefully as possible with many
levels and have very broad browser / device support (including the iPhone). See the
test page for a full list.
Here follows the full source code. It?s very large because it?s fully commented.
You can easily compact this down (one such example follows afterwards).
<!-- ?Video For Everybody? v0.3
=================================================================================================================== -->
<!-- first try HTML5 playback. if serving as XML, expand `controls` to `controls="controls"` and autoplay likewise -->
<video width="640" height="360" poster="__POSTER__.JPG" controls>
<source src="__VIDEO__.OGV" type="video/ogg" /><!-- Firefox 3.5 native OGG video -->
<source src="__VIDEO__.MP4" type="video/mp4" /><!-- Safari / iPhone video -->
<!-- IE only QuickTime embed: IE6 is ignored as it does not support `<object>` in `<object>` so we skip QuickTime
and go straight to Flash further down. the line break after the `classid` is required due to a bug in IE -->
<!--[if gt IE 6]>
<object width="640" height="375" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"><!
[endif]-->
<!-- non-IE QuickTime embed (hidden from IE): the self-closing comment tag allows non-IE browsers to
see the HTML whilst being compatible with serving as XML -->
<!--[if !IE]><!-->
<object width="640" height="375" type="video/quicktime" data="__VIDEO__.MP4">
<!--<![endif]-->
<param name="src" value="__VIDEO__.MP4" />
<param name="showlogo" value="false" />
<!-- fallback to Flash -->
<object width="640" height="380" type="application/x-shockwave-flash"
data="__FLASH__.SWF?image=__POSTER__.JPG&file=__VIDEO__.MP4">
<!-- Firefox uses the `data` attribute above, IE/Safari uses the param below -->
<param name="movie" value="__FLASH__.SWF?image=__POSTER__.JPG&file=__VIDEO__.MP4" />
<!-- fallback image. download links are below the video. warning: putting anything more than
the fallback image in the fallback may trigger an iPhone OS3.0+ bug -->
<img src="__POSTER__.JPG" width="640" height="360" alt="Title of video"
title="No video playback capabilities, please download the video below"
/>
</object><!--[if gt IE 6]><!-->
</object><!--<![endif]-->
</video>
<!-- you *must* offer a download link as they may be able to play the file locally -->
<p>Download Video: <a href="__VIDEO__.MP4">High Quality ?MP4?</a> | <a href="__VIDEO__.OGV">Low Quality ?OGG?</a></p>
(If you would like your video to automatically start playing, check out the sample code on the
Test Page.)
Here?s a compacted version as an example:
(Technically, only one line break is required, to deal with an IE bug, on line 4)
You need to do a number of things to use the code:
Ensure your server is using the correct mime-types. Firefox 3.5 will not play the OGG
video if the mime-type is wrong. Place these lines in your .htaccess file to send the
correct mime-types to browsers
AddType video/ogg .ogv
AddType video/mp4 .mp4
Replace __VIDEO__.MP4 with the path to your video encoded to MP4-H.264
Replace __VIDEO__.OGV with the path to your video encoded to OGG
Replace __POSTER__.JPG with the path to an image you want to act as a title
screen to the video, it will be shown before the video plays in Flash, and as a
representative image when the video is unable to play
Replace __FLASH__.SWF with the path to the Flash video player you
are using. I use JW
Player as it can play the same MP4 that is used for everything else, but this could be
any Flash resource including YouTube. Sample code for using YouTube can be seen on
the Video for Everybody YouTube Test
Page
It is absolutely essential that you provide download links outside of the video for two reasons:
You want people to view your video, right? So why would you wrap the video up in Flash, and then
don?t bother providing a means to download the video? There seems to be this phobia of allowing
people to actually view the video file you want to show them, like they?re going to immediately
pirate it on their street corner. Unless you?ve been living in a hole, it is impossible for you
to prevent people from downloading your video files, even if you lock them up in Flash and don?t
provide the key. There are hundreds of apps and websites to circumvent that. Give
people your video files?you want them to see the video anyway and you are
fooling yourself if you think that they shouldn?t be allowed to download the video.
There are some instances where people will simply not be able to view the video inside the
web-page. Providing users the means to download the video will ensure your message gets through.
This is the only way to support the Palm Pr?, for example.
Encoding the Videos
Video for Everybody uses an MP4 video file to play in Safari, in Flash and on
the iPhone. Therefore the MP4 file must conform to the requirements for these three platforms. Technically
Safari can play anything QuickTime can play. Flash can
play H.264 and the iPhone is a little more
restrictive in that it tops out at 640x480, does not support streaming, and does not support the Main H.264 profile.
See
Apple?s
own instructions for the specifics.
The OGG file is solely for Firefox 3.5 at the moment for Firefox 3.5 and
Chrome, but more browsers may use it in the future as OGG is an open standard and can be implemented by
any vendor if they choose so. It is not patent-encumbered and therefore a cheaper choice than MP4 which requires
licensing.
For best results, I recommend including the poster image as the first frame when you encode the video. In QuickTime
and HTML5 <video>, the first frame of the video is shown until the user clicks play, giving the
users an idea of the content beforehand. You can see I?ve done this with my video examples.
I am no expert in video encoding and explaining the entire process is beyond the scope of this article, however
this article explains the background technical
information and extensive instructions on how to encode compatible OGG files.
Drawbacks
Limited <video> Controls
You can roll your own
controls using any HTML and a
bit of JavaScript. HTML5
also has the benefit that it is far more efficient than Flash, HD video in
the browser is possible?without requiring a supercomputer.
A native video implementation improves as the browser improves. Upgrades are free. If a browser vendor adds
fullscreen playback to their <video> implementation, then you get it for free. Firefox 3.6
has built in fullscreen support, but until then there?s a
Firefox extension for it already.
It?s early days yet and if people don?t start using <video> then the improvements won?t
come as fast. Video for Everybody hopes to spur on the improvement of <video>
implementations.
Lastly, a current bug in
Firefox 3.5 means that when JavaScript is disabled (NoScript for example) the video
controls do not display. The developer of NoScript is aware of this issue and will try to come up with
a solution. For now, right-click on the video for the controls, or use autoplay on your videos, or rely on users
allowing your site in NoScript (the same as they have to do with Flash).
If It Doesn?t Work, It Doesn?t Work
As a raw bit of HTML, you have the issue that some browsers just don?t do things right no matter
what. I?ve worked around as many bugs as possible in the most common browsers, however there are some issues that
cannot be solved with HTML alone. For example, on Linux systems without Firefox 3.5,
Flash or MPEG-4 codecs, the browser may attempt to play the video using the M-Player plugin which will
display a blank, broken video interface (due to not having an MPEG4 decoder) instead of the fallback. Personally, I
suspect the adoption of Firefox 3.5 on Linux will be rapid, and many users will already
have installed either Flash or the extra codecs. Regardless, this is why it is important to
always provide download links below the video.
Without JavaScript Video for Everybody can?t deal with those kinds of situations. This
affects only a small number of users, however if you need to target these users you can always add
JavaScript to Video for Everybody to detect the problematic browser scenarios and make
adjustments accordingly. That?s perfectly fine to do as long the Video for Everybody
HTML is included in the source and JavaScript enhancements are done on page-load; that way
your JavaScript won?t prevent Video for Everybody working for the other 99% of
scenarios.
Frequently Asked Questions
Because new ideas are confusing.
Isn?t this 4× as much effort than just using Flash?
Video for Everybody doesn?t require 4 different video encodes! It uses only two,
which supports 4× as many platforms and browsers than Flash alone does as well as reaching almost
anybody who doesn?t have Flash installed or can?t install it (iPhone / Some 64-Bit operating
systems).
In fact, it ends up being more effort in the long-run using a Flash only method because when a device
like the iPhone comes along and it doesn?t have Flash and it becomes very popular, you now have to
re-encode FLV files and add browser detection and new code to deal with it. New hand-held devices that are coming
out generally don?t support Flash, or only support a tiny sub-set, however they are using ports of
Webkit and Gecko that may support HTML5 <video>, and as
the mobile smart-phone market increases, HTML5 video will keep up far quicker than Adobe and who they
choose to support.
The code is too large / ugly
In an ideal world, all the browser vendors would agree upon one standard and one way of doing things and update
their old browsers to match too. Then you could just use just <video src="my_video.ogg" /> and
it?d play in any browser.
That?s not the case though. Video for Everybody is a hack, a kludge, a workaround. It is to deal with
the fact we still have millstones like IE tied around our necks that just won?t get with
the times. Video for Everybody deals with all of these broken browsers so that you don?t have to.
I doubt you hand-type every object tag you use. You just copy and paste a template, or use a server-side function to
spit out the code each time. The size of the code is moot therefore and can be compacted to a decent size.
Going forward, in the future as HTML5 becomes standard and common, then the layers in Video for
Everybody can be dropped and we can all (hopefully) move to just the video element and be done. That won?t
happen unless we start making use of HTML5 now to help drive adoption. Maybe one day even Microsoft
will add <video> to IE and it should (unless they manage to do even that wrong)
?just work? with Video for Everybody, shedding the Flash layer and automatically
moving up to native video.
Are you saying that JavaScript is bad?
No. Video for Everybody is not aimed at bringing down JavaScript or demanding you go back
to the stone age. It is a base template that can easily be enhanced using JavaScript, but does not use
it itself to provide the fallback mechanisms.
Other HTML5 video embedding methods use JavaScript to detect the browser?s capabilities
and insert the appropriate <video> / Flash content, however this has the drawback
that JavaScript must be enabled or even supported?Most RSS readers do not execute
JavaScript as a security measure. With Video for Everybody, even in environments without
JavaScript the user will still either see the video or be able to download it. The more people who see
your video, the better for you.
Can I modify it?
Yes! However, just bear this in mind: Video for Everybody is designed to provide video for all browsers
within reason; there are a lot of hacks in the code to make the same HTML work across
many, many browsers, each tested with and without Flash
and QuickTime. That?s a big matrix of testing. If you modify Video for Everybody you
might?quite unknowingly?break support for some particular combinations. Please either do what testing you can,
or ask me to get involved in helping to test your modifications.
Why don?t you include Cortado, a Java applet that can play OGG video?
The user-experience is more important than the underlying technology. The problem with Java is the
user-experience compared to Flash and HTML5 video. The loading of a Java
applet causes a noticeable pause whilst the Java Runtime Environment loads. Even on my powerful Mac,
the page loading freezes and the hard disk thrashes for a few seconds, on low powered machines I?ve seen the
entire computer lock up for 10 seconds. On Windows you get a tray-icon appear an a bubble pop-up from said tray icon
distracting you. This is simply unacceptable for playing a video.
Amazon did an experiment whereby they added 100 milliseconds to the load time of their page. Sales dropped 1%
immediately. Google did a
similar test, adding just half a second to the load time. Traffic dropped 20% immediately.
By including Cortado in Video for Everybody I would be effectively putting some customers
off from visiting your website, even damaging people?s opinion of your site because it ?slows their computer
down?. Video is used to communicate a message and that needs to be done with the minimal amount of fuss and as
much speed as possible. Until Sun Oracle improve Java to the point where it is no longer a
visual nuisance and a speed-bump then I would consider it.
You are of course free to modify Video for Everybody to include Cortado! If it serves your
demographic or needs better, by all means do so.
Please Contribute
Video for Everybody is not a complete solution. It is the template for you to get started. Please help
test Video for Everybody on a wide range of browsers,
plugins and devices.
HTML5 video is here now, available on a very wide range of platforms and devices that stretch
well beyond what Flash can support. We need to start building the tools and the patterns to
support everybody seamlessly. Video for Everybody is my contribution to this larger movement across the
?Web as a helping hand to bridge the gap for developers so that they do not have to be in the position of choosing
one (Flash) or the other (<video>), but being able to choose both.
Please send anything Video for Everybody related to me at
kroccamen@gmail.com and consider subscribing to the
RSS for updates.
Related Projects
If you?ve modified Video for Everybody to do something else, or have created an HTML5
video related project, please let me know and if it upholds the same
principles as
VfE, I?ll list it here.
(I will not list projects that cannot play the video in an RSS reader. Using JavaScript to
insert <video> defeats the entire purpose.)
A WordPress plugin that provides you a simple interface for inserting video. It uses
Video for Everybody for the base template but steps up to a custom interface if
JavaScript is available. The plugin even does server-side encoding. The Flash
interface is designed to closely mimic the look of Firefox 3.5?s native
<video> controls to provide consistency, regardless of technology used. Absolutely
stunning work.
published on 2009-06-07 14:13:00 in the "code" category
Something I think might be useful to people. This code takes a directory listing and then sorts the contents listing
folders first (in alphabetical order), then the files are sorted by file type and then alphabetically for each file
type.
//directory to list, you choose; here we?ll just use the webroot$path = $_SERVER['DOCUMENT_ROOT'];//warning: `is_dir` will need you to change to the parent directory of what you are testing//see <uk3.php.net/manual/en/function.is-dir.php#70005> for detailschdir ($path);//get a directory listing$dir = array_diff (scandir ('.'),//folders / files to ignore array ('.', '..', '.DS_Store', 'Thumbs.db'));//sort folders first, then by type, then alphabeticallyusort ($dir, create_function ('$a,$b', ' return is_dir ($a) ? (is_dir ($b) ? strnatcasecmp ($a, $b) : -1) : (is_dir ($b) ? 1 : ( strcasecmp (pathinfo ($a, PATHINFO_EXTENSION), pathinfo ($b, PATHINFO_EXTENSION)) == 0 ? strnatcasecmp ($a, $b) : strcasecmp (pathinfo ($a, PATHINFO_EXTENSION), pathinfo ($b, PATHINFO_EXTENSION)) )) ;'));//echo to screenheader ('content-type: text/plain');print_r ($dir);
Here?s how this breaks down:
usort sorts an array using
another function given two items to compare. Return ?-1? if the first should go above the other, 1 if the second
should go above the other and 0 if they are equal.
We create a function with $a and $b parameters corresponding to the two items being
compared for sorting as it goes through the list.
return is_dir ($a)
If the first item is a directory then?
? (is_dir ($b) ? strnatcasecmp ($a, $b) : -1)
Check if the second item is a directory. If both items are directories then compare them by name.
strnatcasecmp will
return ?-1?, ?0? or ?1? accordingly.
: (is_dir ($b) ? 1 : (
Now if the first item is not a directory, check if the second item is. If the second item is a directory, it will go
above the first item?return ?1?.
Video for Everybody is very simply a chunk of HTML code that embeds a video into a website
using the HTML5 <video> element which offers native playback in Firefox
3.5 and Safari 3 & 4 and an increasing number of other browsers:
This is native OGG video playback in Firefox 3.5 (you get H.264 playback in Safari). No
plugins to install. The video is played by the browser itself. It loads quickly and doesn?t threaten to crash your
browser.
In other browsers that do not support <video>, it falls
back to QuickTime.
(which allows playback on the iPhone)
(Note that due to a bug in iPhone OS 3, the video will sometimes refuse to play, just refresh until it allows
playback. I hope this will be resolved in the near future.)
If QuickTime is not installed, Adobe Flash is used:
You can host locally or embed any Flash file, such as a YouTube video.
Finally, if all else fails, a warning is issued that provides links to download the video, and links to software
relevant to getting the video to play within the browser itself. Since this is just HTML, you can put
anything here you want.
This is all done without JavaScript and requires only two video encodes, one OGG file for Firefox
3.5, and one MP4 file for everything else (Flash / Safari / iPhone). Instructions on
how to convert your videos to these formats with the correct settings are provided further
down this article.
It?s compatible with HTML4, HTML5, XHTML1 and additionally also works when
served as application/xhtml+xml.
The market is made up of more OSes, browsers and processor architectures than
it was five years ago. More people (especially geeks) are browsing with AdBlock / NoScript
/ FlashBlock than ever before. We can no longer just assume people are going to have Flash
and are allowing you to use it.
The same rules apply to video. If my platform / device / browser of choice cannot see your video, or you do not offer
me the means to download the video to view offline, then I don?t see whatever it is you?ve got to show me.
I therefore want to help all web developers get to grips with
<video>, to make it easy for them to show video content
without having to sacrifice legacy browsers, nor ask you to install anything if at all possible?just as much as I
wouldn?t want you to ask me to install anything.
Starting Off on the Wrong Foot:
I see a problem with how people are beginning to offer HTML5 video. Whilst it is fantastic that
DailyMotion and
YouTube are experimenting with HTML5 there are a
number of primary things content providers must satisfy for HTML5 video to adhere to the openness it is
purposed for.
Not treated like a special case
No special page you have to visit. No extra effort should be required on your part to get video your browser
already supports perfectly.
No browser sniffing
Implementations could turn up anywhere, in any form. OGG is open-source open-specification. Serving to only
mainstream browsers like Firefox 3.5 goes against the whole point of open-video removing the
requirement to be tied to one particular vendor.
Don?t require JavaScript
Developers generally don?t know how to include the video tag whilst falling back to alternatives. Trying
to detect browsers using JavaScript and writing the <video> element into the page is just
going about it the wrong way.
Video for Everybody specifically solves these problems.
It:
Allows content producers to provide HTML5 video as an equal citizen
The same code is used for browsers that support <video>, as well as
QuickTime and Flash. No special copy of your website has to be setup, no options
have to be ticked. Video for Everybody plays the right file for the right level of support the
user?s browser provides.
Degrades extremely gracefully, providing multiple levels of fallback
Using Flash only provides you support for platforms where Flash is installed. No
Flash: No Video. Video for Everybody will most of the time still
play the video even if Flash is not installed. Flash is not supported on the
iPhone, the ?1 platform for users accessing the web on a mobile.
Is just plain copy & paste HTML
Of course, you can write a server side script to insert it over and over again according to however many
videos you have, but the HTML itself does not use JavaScript to insert the video
or detect browsers or even provide the fallbacks. You can enhance Video for Everybody with
JavaScript (it?s just the template to get you started), but the core selection of which video
format plays is completely down to the browser, no JavaScript involved.
How?
There?s nothing particularly new about this, people have been doing object-fallback
for ages now, however this is an attempt at
including HTML5 video into the mix, as well as trying to degrade as gracefully as possible with many
levels and have very broad browser / device support (including the iPhone). See the
test page for a full list.
The Code
Here follows the full source code. It?s very large because it?s fully commented.
You can easily compact this down (one such example follows afterwards).
<!-- ?Video for Everybody? v0.2 by Kroc Camen <camendesign.com> cc-by ======================================================================================================== --><!-- first try native HTML5 video playback --><video width="640" height="360" poster="__POSTER__.jpg" controls="controls"> <source src="__VIDEO__.ogv" type="video/ogg" /><!-- Firefox 3.5 native OGG video --> <source src="__VIDEO__.mp4" type="video/mp4" /><!-- Safari / iPhone video --><!-- IE only QuickTime embed. IE6 is ignored as it does not support <object> in <object> so we skip QuickTime and go straight to Flash further down. the line break after the classid is required due to a bug in IE --><!--[if gt IE 6]><object width="640" height="375" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"><![endif]--><!-- non-IE QuickTime embed (hidden from IE). the self-closing comment tag allows non-IE browsers to see the HTML whilst being compatible with serving as XML --><!--[if !IE]><!--> <object width="640" height="375" type="video/quicktime" data="__VIDEO__.mp4"><!--<![endif]--> <param name="src" value="__VIDEO__.mp4" /> <param name="autoplay" value="false" /> <param name="showlogo" value="false" /><!-- fallback to Flash --> <object width="640" height="380" type="application/x-shockwave-flash" data="__FLASH__.swf?image=__POSTER__.jpg&file=__VIDEO__.mp4"> <param name="movie" value="__FLASH__.swf?image=__POSTER__.jpg&file=__VIDEO__.mp4" /><!-- fallback message --> <img src="__POSTER__.jpg" width="640" height="360" /><!-- you *must* offer a download link as they may be able to play the file locally --> <p> <strong>No video playback capabilities detected.</strong> Why not try to download the file instead?<br /> <a href="__VIDEO__.mp4">MPEG4 / H.264 ?.mp4? (Windows / Mac)</a> | <a href="__VIDEO__.ogv">Ogg Theora & Vorbis ?.ogv? (Linux)</a> </p><p> To play the video here in the webpage, please do one of the following: </p><ul> <li>Upgrade to <a href="http://getfirefox.com">Firefox v3.5</a>, or <a href="http://apple.com/safari">Safari v4</a></li> <li>Install <a href="http://get.adobe.com/flashplayer/">Adobe Flash Player</a></li> <li>Install <a href="http://apple.com/quicktime/download/">Apple QuickTime</a></li> </ul> </object><!--[if gt IE 6]><!--> </object><!--<![endif]--></video>
(If you would like your video to automatically start playing, check out the sample code on the
Test Page.)
Here?s a compacted version as an example.
Technically, only one line break is required (to deal with an IE bug), on line 4.
You need to do a number of things to use the code:
Ensure your server is using the correct mime-types. Firefox 3.5 will not play the OGG
video if the mime-type is wrong. Place these lines in your .htaccess file to send the
correct mime-types to browsers
AddType video/ogg .ogvAddType video/mp4 .mp4
Replace __VIDEO__.mp4 with the path to your video encoded to MP4-H.264
Replace __VIDEO__.ogv with the path to your video encoded to OGG
Replace __POSTER__.jpg with the path to an image you want to act as a title
screen to the video, it will be shown before the video plays in Flash, and as a
representative image when the video is unable to play
Replace __FLASH__.swf with the path to the Flash video player you
are using. I use JW
Player as it can play the same MP4 that is used for everything else, but this could be
any Flash resource including YouTube. Sample code for using YouTube can be seen on the
Video for Everybody YouTube Test
Page
Encoding the Videos
Video for Everybody uses an MP4 video file to play in Safari, in Flash and on
the iPhone. Therefore the MP4 file must conform to the requirements for these three platforms. Technically
Safari can play anything QuickTime can play. Flash can
play H.264 and the iPhone is a little more
restrictive in that it tops out at 640x480, does not support streaming, and does not support the Main H.264 profile.
See
Apple?s
own instructions for the specifics.
The OGG file is solely for Firefox 3.5 at the moment for Firefox 3.5 and
Chrome 3.0, but more browsers may use it in the future as OGG is an open standard and can be implemented
by any vendor if they choose so. It is not patent-encumbered and therefore a cheaper choice than MP4 which requires
licensing.
Note: This section has been removed. I never meant to provide comprehensive or accurate instructions as they
could never fit into this article but the landscape is changing rapidly and I have no skill with video encoding and
cannot maintain my instructions. I would be willing to link to other guides on the web, please
contact me.
For best results, I recommend including the poster image as the first frame when you encode the video. In QuickTime
and HTML5 <video>, the first frame of the video is shown until the user clicks play, giving the
users an idea of the content beforehand. You can see I?ve done this with my video examples.
Drawbacks
Limited <video> Controls
With Flash you get the benefits of full-screen and extra video controls. There?s no fullscreen
playback support in any HTML5 <video> implementation yet (but there is
this), and the controls are generally
very basic. You can roll
your own controls using any HTML and a
bit of JavaScript.
So no, this is not any better than Flash. Yet. But really, the idea is to live with the drawbacks to
wait for the benefits in the future that go
waybeyond what
Flash can do.
HTML5 also has the benefit that it is far more efficient than Flash,
HD video in the browser is possible?without requiring a supercomputer.
A native video implementation improves as the browser improves. Upgrades are free. If a browser vendor adds
fullscreen playback to their <video> implementation, then you get it for free. There?s a
Firefox extension for it already.
It?s early days yet and if people don?t start using <video> then the improvements won?t come
as fast. Video for Everybody hopes to spur on the improvement of <video>
implementations.
Lastly, a current bug in
Firefox 3.5 means that when JavaScript is disabled (NoScript for example) the video
controls do not display. The developer of NoScript is aware of this issue and will try to come up with a
solution. For now, use autoplay on your videos, or rely on users allowing your site in NoScript (the
same as they have to do with Flash).
If It Doesn?t Work, It Doesn?t Work
As a raw bit of HTML, you have the issue that some browsers just don?t do things right no matter what.
I?ve worked around as many bugs as possible in the most common browsers, however there are some issues that cannot
be solved with HTML alone. For example, on Linux systems without Firefox 3.5,
Flash or MPEG-4 codecs, the browser may attempt to play the video using the m-player plugin which will
display a blank, broken video interface (due to not having an MPEG-4 decoder) instead of the fallback text.
Personally, I suspect the adoption of Firefox 3.5 on Linux will be rapid, and many users
will already have installed either Flash or the extra codecs.
Without JavaScript Video for Everybody can?t deal with those kinds of situations though.
This affects only a small number of users, however if you need to target these users you can always add
JavaScript to Video for Everybody to detect the problematic browser scenarios and make
adjustments accordingly. That?s perfectly fine to do as long the Video for Everybody HTML
is included in the source and JavaScript enhancements are done on page-load; that way your
JavaScript won?t prevent Video for Everybody working for the other 99% of scenarios.
Frequently Asked Questions
Because new ideas are confusing.
Isn?t this 4× as much effort than just using Flash?
Video for Everybody doesn?t require 4 different video encodes! It uses only two,
which supports 4× as many platforms and browsers than Flash alone does as well as reaching almost
anybody who doesn?t have Flash installed or can?t install it (iPhone / Some 64-Bit operating systems).
In fact, it ends up being more effort in the long-run using a Flash only method because when a device
like the iPhone comes along and it doesn?t have Flash and it becomes very popular, you now have to
re-encode FLV files and add browser detection and new code to deal with it. New hand-held devices that are coming out
generally don?t support Flash, or only support a tiny sub-set, however they are using ports of
Webkit and Gecko that may support HTML5 <video>, and as the
mobile smart-phone market increases, HTML5 video will keep up far quicker than Adobe and who they choose
to support.
The code is too large / ugly
In an ideal world, all the browser vendors would agree upon one standard and one way of doing things and update their
old browsers to match too. Then you could just use just <video src="my_video.ogg" /> and it?d
play in any browser.
That?s not the case though. Video for Everybody is a hack, a kludge, a workaround. It is to deal with
the fact we still have millstones like IE tied around our necks that just won?t get with
the times. Video for Everybody deals with all of these broken browsers so that you don?t have to.
I doubt you hand-type every object tag you use. You just copy and paste a template, or use a server-side function to
spit out the code each time. The size of the code is moot therefore and can be compacted to a decent size.
Going forward, in the future as HTML5 becomes standard and common, then the layers in Video for
Everybody can be dropped and we can all (hopefully) move to just the video element and be done. That won?t
happen unless we start making use of HTML5 now to help drive adoption. Maybe one day even Microsoft will
add <video> to IE and it should (unless they manage to do even that wrong) ?just
work? with Video for Everybody, shedding the Flash layer and automatically moving up to
native video.
Are you saying that JavaScript is bad?
No. Video for Everybody is not aimed at bringing down JavaScript or demanding you go back
to the stone age. It is a base template that can easily be enhanced using JavaScript, but does not use
it itself to provide the fallback mechanisms.
Other HTML5 video embedding methods use JavaScript to detect the browser?s capabilities
and insert the appropriate <video> / Flash content, however this has the drawback
that JavaScript must be enabled or even supported?Most RSS readers do not execute
JavaScript as a security measure. With Video for Everybody, even in environments without
JavaScript the user will still either see the video or be able to download it. The more people who see
your video, the better for you.
Can I modify it?
Yes! However, just bear this in mind: Video for Everybody is designed to provide video for all browsers
within reason; there are a lot of hacks in the code to make the same HTML work across
many, many browsers, each tested with and without Flash
and QuickTime. That?s a big matrix of testing. If you modify Video for Everybody you
might?quite unknowingly?break support for some particular combinations. Please either do what testing you can, or
ask me to get involved in helping to test your modifications.
Why don?t you include Cortado, a Java applet that can play OGG video?
The user-experience is more important than the underlying technology. The problem with Java is the
user-experience compared to Flash and HTML5 video. The loading of a Java
applet causes a noticeable pause whilst the Java Runtime Environment loads. Even on my powerful Mac, the
page loading freezes and the hard disk thrashes for a few seconds, on low powered machines I?ve seen the entire
computer lock up for 10 seconds. On Windows you get a tray-icon appear an a bubble pop-up from said tray icon
distracting you. This is simply unacceptable for playing a video.
Amazon did an experiment whereby they added 100 milliseconds to the load time of their page. Sales dropped 1%
immediately. Google did a
similar test, adding just half a second to the load time. Traffic dropped 20% immediately.
By including Cortado in Video for Everybody I would be effectively putting some customers
off from visiting your website, even damaging people?s opinion of your site because it ?slows their computer
down?. Video is used to communicate a message and that needs to be done with the minimal amount of fuss and as much
speed as possible. Until Sun Oracle improve Java to the point where it is no longer a visual
nuisance and a speed-bump then I would consider it.
You are of course free to modify Video for Everybody to include Cortado! If it serves your
demographic or needs better, by all means do so.
Please Contribute
Video for Everybody is not a complete solution. It is the template for you to get started. Please help
test Video for Everybody on a wide range of browsers,
plugins and devices.
HTML5 video is here now, available on a very wide range of platforms and devices that stretch
well beyond what Flash can support. We need to start building the tools and the patterns to
support everybody seamlessly. Video for Everybody is my contribution to this larger movement across the
web as a helping hand to bridge the gap for developers so that they do not have to be in the position of choosing one
(Flash) or the other (<video>), but being able to choose both.
Please send anything Video for Everybody related to me at
kroccamen@gmail.com or my
Twitter and consider subscribing to the RSS for updates.
Related Projects
If you?ve modified Video for Everybody to do something else, or have created an HTML5
video related project, please let me know and if it upholds the same
principles as
VfE, I?ll list it here.
A WordPress plugin that provides you a simple interface for inserting video. It uses
Video for Everybody for the base template but steps up to a custom interface if
JavaScript is available. The plugin even does server-side encoding. The Flash
interface is designed to closely mimic the look of Firefox 3.5?s native
<video> controls to provide consistency, regardless of technology used. Absolutely
stunning work.
Sightings
Using Video For Everybody on your site? Please drop me an
e-mail and let me know!
published on 2009-04-20 07:02:00 in the "code" category
That?s a single abbr element (on mouseover).
No spans, divs or superfluous elements. No classes. No Javascript. Just CSS.
Unfortunately the cost of this simplicity is that it only works in Firefox 3.1+, Safari 3,
4 / Chrome 1, 2. If you have any of these, then try it out on
this article, which has a number of abbreviations.
I suspect that I am opening a can-of-worms with this one, as the abuse of the abbreviation
element is already bad enough. This will only encourage people to do worse. However, it is an effect that I?ve
long wanted to do, and has only recently become possible for my target-market with the beta builds of
Firefox 3.15
The crux of this is the ability to absolutely position CSS-generated content
(i.e. :before & :after). This has been supported in
Safari for some time. The bug for Firefox was filed in 2004 (That?s
Firefox 0.8). That annoys me beyond description that something that?s part of the CSS2
spec could be left that long, and only now?in 2009?can I actually do the effect (in my favourite browser) I?ve
been wanting to do all this time.
In essence it?s very simple. Just use :before to write the abbreviation?s title before the
abbreviation and position / style accordingly. I?ve tried on and off over the last few years to do this in
Firefox, but it?s simply not possible without absolute positioning. I came up with some clever hacks,
but they all fell down in one major way: they were simply not absolutely positioned, so therefore would not hang over
any bounding box (for long titles at the page edge).
A second problem is being able to target Firefox 3.5 and not Firefox 3, but also include
Safari. Firefox 3 does not include support for the
?nth-child?
CSS selector, whereas Firefox 3.5 (and Safari) does. This works out handily,
as browser support for this selector also matches browser support for absolute positioning of generated content!
Therefore the following selector matches abbreviations with titles, in Firefox 3.5 and
Safari. For Firefox 3, no match would be made, and therefore the browser would fall back to
the default dotted-underline.
abbr:nth-child(n)[title]:hover { ...
There is however, one problem with this: Opera. It freaks out for some reason and offsets the
absolutely-positioned description by the page scroll, as well as other quirks. Opera also doesn?t
support border-radius, giving a rather blunt look. I need to somehow exclude Opera
entirely, but I don?t know of any CSS selector or hack that can do that. I?ve found ones to exclude
Safari specifically, or Opera and Safari, but nothing that can exclude all
versions of Opera.
On to the code!
/* the abbreviation itself */abbr:nth-child(n)[title]:hover {/* the abbr element is relative, so that we can absolutely position the `:before` description */ position: relative;/* the negative margin removes the effect of the padding and border so that the floaty does not nudge the surrounding content around */ padding: 1px 5px; margin: -2px -6px;/* use the line-height of the paragraph the abbr is in, instead of the abbr itself. this keeps the description central when different line-heights are used in p / code / h1 &c. */ color: #235; line-height: inherit;/* why have borders for something that appears to have none? 1. you may wish to customise, and 2. without the border, the shadow appears detached from the edge! */ border: 1px solid #93a3b9 !important;/* gecko supports % for border curves, allowing us to have a perfectly round caps regardless of size */ -moz-border-radius: 0 50% 50% 0; -moz-box-shadow: -1px 2px 1px rgba(0,0,0,.5); /* webkit does not support % for radius, for small fonts the curves disappear. 8px curves will support a minimum 11px font-size. a solution to this is to set line-height to 1.5em (instead of inherit) above, and then use 0.75em instead of 8px below. this will work if you have a strict line-height of 1.5em already through your document */ -webkit-border-top-right-radius: 8px; -webkit-border-bottom-right-radius: 8px; -webkit-box-shadow: -1px 2px 1px rgba(0,0,0,.5); background-color: #93a3b9;}/* the abbreviation description */abbr:nth-child(n)[title]:hover::before {/* write out the abbreviation description */ content: attr(title);/* the controversial bit */ position: absolute; display: block;/* top has to be nudged up because this is *inside* the abbr whose 1px border is offsetting it. `right: 100%` positions the description hanging out to the left regardless of description width */ height: 100%; top: -1px; right: 100%; padding: 0 5px 0 7px;/* because of `right` above, the width is technically 0px, therefore `nowrap` is required! */ color: #456; white-space: nowrap; text-indent: 0; border: 1px solid #c3d3e7; -moz-border-radius: 50% 0 0 50%; -webkit-border-top-left-radius: 8px; -webkit-border-bottom-left-radius: 8px; -webkit-box-shadow: -1px 2px 1px rgba(0,0,0,.5); -moz-box-shadow: -1px 2px 1px rgba(0,0,0,.5); background-color: #c3d3e7;}
I strongly suggest that before putting this code to use, you read up on the proper way
to use the abbreviation element. In short, abbreviations are not for defining terms, but rather expanding on how a
piece of text should be read according to the author?s original intentions.
This code is licenced under a Creative Commons Attribution 3.0 licence; please share and remix this, just include
?Kroc Camen? and/or ?camendesign.com? in your CSS comments, thanks.
I don?t do enough CSS articles on this website, so time to break down one of my pet prides: my little
CSS-styled dates.
Markup
The backbone of any good CSS is good markup. The dates on this website are hyperlinks to the permalink
page for each article. rel="bookmark" is an
HTML convention to
denote a permalink, this avoids having to use a class instead.
Inside the hyperlink is just the date with some additional inline markup,
abbreviations for the month and year, and sub around the time to try to
reflect the visual nature of the time, whereby it?s displayed underneath, and is hidden (lesser importance) until
moused-over.
This is a surprisingly little amount of HTML for those visuals, eh? I?ve seen sites that would use
five or six DIVs to achieve the same effect. This is where the power of CSS comes in, to let us wrangle
the most out of this small bit of markup.
CSS
Day
We start by defining the outline shape of the permalink.
The attribute selector ?[rel~=bookmark]? selects all hyperlinks that contain bookmark in
their ?rel? attribute. ?~=? is used instead of just = as it allows for
rel attributes that contain more than one word separated by spaces. E.g.
?rel="bookmark alternate"?. Whilst highly unlikely, I?m just covering all bases.
The hyperlink is converted to block layout. ?position: relative;? is applied so that the year can be
absolutely positioned inside the date into the top-right corner, as in the markup the year appears last.
?margin-bottom: 18px;? adds room below the date as space for the time to appear on mouse over.
The hyperlink itself forms the day of the date ?10th? and the month ?abbr-1?, and year
?abbr-2? are repositioned to the top. Therefore we set the font and background according to the day. The
background-image is moved down so that it sits one pixel away from the red bar, leaving a white line, improving the
overall look and feel.
The ordinal suffix ?th? is not centred along with the number, but instead sits aside it. This is done
by making it?s position absolute so that it gets lifted off of the text and no-longer affects the width of the text
being centred.
/* lift the suffix, so that the number is fully centered */a[rel~=bookmark] sup { position: absolute; padding-top: 4px; font-size: 10px; line-height: 10px; letter-spacing: normal;}
Subtle, but so effective!
Month
The month and year, both being abbreviations share some styles in common. We set the font style and return the
letter-spacing to normal (as it was set to 2 in the hyperlink for the day number).
The month, already in the top-left corner of the date is stretched across the top, and uses a negative margin on the
top and left edges so that it?s red border covers over the grey border of the hyperlink base.
The ?:first-child? selector is used to choose the first
abbr element (containing the month), without affecting the other
abbr element (the year).
Year
The year is absolutely positioned and moved to the top-right corner. Because we used
?position: relative;? on the hyperlink, ?top: 0;? moves the year to the top of the
hyperlink, not the top of the page!
A border is given so that the background-image gradient is covered on the left and right pixels giving a minute
bevelled look to the top part of the date.
Time
The sub element containing the time is hidden by default and not revealed until mouse-over
The time is given a top border that will act as a divider between the day and time when the hyperlink is expanded by
showing the time.
Mouse-Over
On mouse over, two things are done. As a permalink, the date should have some kind of hover-state. You could change
colours, background-images, anything. In my instance I decided to place a focus rectangle around it.
The focus rectangle is used by the OS to show focus on an element, typically a text box. Take this image of Google
for example. On the Mac a blue outline is used, this varies from OS to OS, and browser to
browser.
In both Safari (and Chrome) and Firefox you can set this focus ring using the
OS/browser-selected colour.
(Another selector for :focus is included to also allow for keyboard navigation)
-webkit-focus-ring-color caters to Webkit, and on the following line
-moz-mac-focusring handles Firefox. The outline also has to be curved (with
-moz-outline-radius), but this is unfortunately not supported in Safari yet.
Despite being primarily for the Mac, this CSS works on other
OSes, having different results. On Windows, the outline is shown
white, on Linux it?s shown black, and on Google?s Chrome browser it?s even orange!
The second thing to do on mouse-over, of course, is to show the time by unhiding the sub element.
a[rel~=bookmark]:hover sub, a[rel~=bookmark]:focus sub { display: block;}
Compatibility
Works in Firefox 2 & 3 and above, Safari 4
(Win/Mac), Chrome 2.0
Works in IE8!
A bug in Webkit for Safari 3 (and Chrome 1.0) means that the ordinal
is misplaced.
I?m not sure what causes this, I can?t work out how to fix it either. Suggestions please!
Due to lack of border-radius in non- Gecko-based (such as Firefox) or
Webkit-based (such as Safari) browsers, the rounded corners do not display on
Opera, for example
This code is licenced under a Creative Commons Attribution 3.0 licence; please share and remix this, just include
?Kroc Camen? and/or ?camendesign.com? in your CSS comments, thanks.
Please find attached a zip file containing the full code, better formatted, and the background-images used.
This presents a lot of valuable information in a very simple way, and therefore as a good idea, it should be
stolen borrowed.
Here are, in my opinion, a number of key optimisation tips for your website:
Move scripts to the bottom of the body
When the page loading hits a script tag?everything stops. Scripts have the right of way. A script
can?t change the DOM until the HTML has loaded, so more important
things like stylesheets are held up loading a script file that?s no actual use until the
HTML has finished loading! Get your HTML structure and CSS
to the user as quick as you can. The browser will be able to render the page much quicker
and then scripts can be loaded, rather than leaving a blank page for the user stare at
whilst they wait for scripts to download.
Moving the script tags to just before the
</body> tag alone will make your website
noticeably snappier! However, doing this brings added responsibility. Because the page will render
before scripts have initialised, particularly quick clickers will be able to interact with your
site before your Javascript is ready! This brings us on to the next tip:
Ensure the site still works with Javascript disabled
I cannot stress this enough, and how much it makes a positive difference?even when Javascript is
enabled! Firstly, more and more people are now browsing with Javascript switched off by default
thanks to the security benefits and flexibility provided by
NoScript. It
increases browsing speed, frees up bandwidth, increases privacy by blocking all sorts of third
party scripts, and helps mitigate XSS attacks.
Just as your HTML and CSS should be separate, so should your Javascript.
If you
code
your site to work without AJAX first, all your server-side events are done, you
can just veneer the site with event-bound Javascript to replace REST events with
AJAX ones based on the URLs already in the HTML. Google
doesn?t run Javascript, so it still needs to get around!
Having the site work without Javascript increases user trust, increases the platforms you support
without any extra work, increases SEO,
reduces maintenance and best of all, allows people to click through your site at super speed when
they know where they want to go.
Provide proper fallbacks for Flash content
Assuming everybody has Flash doesn?t cut the mustard any more, there are more
diverse platforms in use?that don?t support Flash?than there were years ago;
iPhone for one. People are blocking Flash with AdBlock,
NoScript and FlashBlock.
If people can?t see your content then you lose out. There are almost always better ways of
presenting content to users without using Flash, and if you have to use Flash then
don?t provide a lame cop-out excuse like ?Install Flash? as the only fallback message.
Describe what the actual content is, why you can?t view it and provide it in an alternative
format (such as an image).
This especially applies to videos. I don?t have Flash installed, telling me to
install Flash is just annoying, when there?s plenty of other ways you can give me
the content. How about falling back to a QuickTime embed? Why don?t you provide a
download link for the video file in the fallback text, huh? Even better than that, modern browsers
support HTML5 <video> that requires no plugin at all?use that instead!
If you are embedding video you should be using Video for
Everybody? a comprehensive solution that uses native HTML5 <video> in
browsers that support it, then falls back to Flash for other browsers, then
QuickTime if Flash is not installed
(e.g. iPhone) and if all else fails shows a fallback message
allowing people to download the video.
There is no reason anybody should be staring at a broken plugin icon.
Clean up the head
You can really fill the head element with junk if you want to.
/favicon.ico is assumed by default, putting this in the head
is just extraneous bytes. If you need to store your favicon somewhere else (why?
No why? No really, why?) then just mod_rewrite it to
/favicon.ico to avoid 404s and wasted
HTTP-requests from browsers / aggregators assuming the default
Don?t use keywords / description:
All SEO is bunk. Paying for SEO
?specialists? to wave their magic wand over your site is no more material
than a pair of emperor?s clothes. If you have clean, tidy, semantic markup,
have avoided text in images and have a sensible and clear system of navigation
that doesn?t depend on Javascript, then Google will have no problem
understanding your site.
To that end, I have found that filling the head full of keywords is a waste of
time. Camen Design appears on Google without
any
issue. Seriously, drop the voodoo and witch doctors, it?s not the ?90s
anymore
To give a feel of snappiness, you want to get the structure rendered as soon as possible, ideally
before any images have even loaded. It?s critical therefore to get the stylesheet to the user as
soon as possible. Any HTTP-requests before the CSS sheet are wasting
valuable time!
Therefore, don?t place any <link> or script elements
above the stylesheet in the HTML head. If you really want to save a few milliseconds
more for dial-up users, put the stylesheet above the <title>!
Give all <img> elements height and width attributes
One thing that really annoys me is when you view a site with a lot of images and as
you?re reading, the page is jumping all over the place as the images load. If you define the
correct height and width attributes on image tags, then the page will render faster (less reflows)
as well as allowing your users to get on with reading without disturbance whilst the images load.
If your HTML is outputted by a CMS and
the height and width attributes are not added, then either modify the code to look up the image
size
(getimagesize
in PHP), or hound the developers until they do.
Reduce HTTP-requests
Bandwidth is not the problem when it comes to speed, even on dial-up. The browser can only do a
limited number of simultaneous HTTP requests (usually 2). That is the bottleneck that
you are fighting against.
By whittling the number of HTTP-requests down to an absolute minimum, you will make the time
between one page and the next almost instantaneous.
Think of it this way: in a worst case scenario, a single HTTP-request could take up to
a second alone if the server is under heavy load or if the bandwidth is already saturated.
Combine print stylesheet with main stylesheet:
Even if a stylesheet in the head uses media="print" the browser will
still download it regardless. When printing or in print-preview, nothing new can
be downloaded, it has to already be in cache. Therefore having a print link in
the HTML head is wasting an HTTP-request!
If you include the CSS print declarations in an @media
block in the main stylesheet then the same amount of data is being downloaded,
but the number of HTTP-requests is reduced, allowing the browser to be busy
downloading something else. If your CSS sheet is gzipped then the
size of the combined stylesheet will be less than two separate sheets
Combine Javascript files
Again, being brutal with HTTP-requests, merge
JS files into one when publishing.
I once wrote a
build-system
that ?compiled? a web-app by searching through Javascript files and finding
instances of a function called
$import
(which just loaded in the named Javascript file), and
replaced
the function call with the contents of that file.
Use the
YUI
Compressor to compress the combined file by removing extraneous
whitespace and comments &c.
To give you an idea of the savings that?s possible, I managed to compress 319
KB of Javascript in 15 files, into 141
KB in just 2 (library / app).
I used this same method to replace @import statements in
CSS sheets with the imported sheet to combine multiple sheets into one.
If you?re writing swathes of code that have to be spread across many files,
it?s well worth investing time in scripting a decent build system to
?compile? the site before uploading to a live environment
Provide background colours to imitate background images
An effect that adds to the perception of speed is to use the CSS to closely represent the page?s
design without images. If you view the page without images, is the page layout still communicated
via the same colours?
For everything with a background image, set a matching background-colour to act as a
?placeholder? for the image, and where possible, design your HTML structure, such
that background colours can be used to represent the layout of the site when images are not present.
On Camen Design, background images are used for gradients and an approximate background colour is
provided. CSS borders do the rest. On
Tripology, without images, everything just turns
a light shade of blue, and no structure is communicated.
Simply put?the website should look almost as good without images, as it should with them.
GZip what you can
Save bandwidth for both you and the user by compressing text-based content such as
HTML, CSS and Javascript files.
On this website, the publishing script saves each web
page as a zip-compressed file, (using PHP?s
gzencode
function) with a ?.xhtml? extension. The CSS file is compressed similarly into a
?.csz? file, and the RSS files as ?.rsz?. Apache?s mod_rewrite is then
used to serve the correct content-encoding header to the
browser.
Here?s an example of some ?.htaccess? commands that could be used:
If you don?t want to have to compress your files every time you publish, you can get the server
to compress files during output. Bear in mind though that this will increase CPU usage
on the server and might not be ideal under heavy traffic; it?s always better to pre-compress your
files.
All imaging software?and especially Adobe Photoshop?output inefficient JPEG and PNG
files that waste sometimes even hundreds of kilobytes in needless information. There are a number
of tools out there that can losslessly reduce the file size. I?ve seen as much
as 1 MB or more saved from a gallery of thumbnails.
Yahoo have put together a website that combines these tools into one at
smush.it. If however you want to do things locally for
scripting purposes, the individual programs they?re using can be found on the bottom of their
FAQ page. I use a simple
Dashboard widget called PNGPong.
Write / output cleanly indented HTML
The HTML on this site, in fact, every site I?ve written?CMS or
not?has had clean HTML, nicely indented and human-readable. Whilst not necessary for
all kinds of site, this particular site is very much designed to encourage reading of the source.
There are other benefits though of outputting clean HTML. It greatly helps with
debugging HTML / CSS issues, but really the benefits are not the result,
it?s the fact that it takes a keen eye, patience and a lot of love to get a big, heavy 10?000+
line CMS to output perfect HTML and that careful consideration whilst
achieving that will ensure that you?ve gone over your codebase with a fine-toothed comb and
probably end up fixing and improving tons more than just HTML.
Clean HTML makes for a clean codebase too.
Drop Internet Explorer 6 support
A number of websites, including Apple?s Mobile Me have
already taken the lead in dropping support for Internet Explorer 6. The trend is
unavoidable.
Think of it this way:?given that there are more people using Firefox 3 (which passes
Acid 2 and supports <canvas>) than IE6, the only users of IE6 who
can?t upgrade to a newer version or a better browser entirely are Win9× users and frozen
corporate desktops. Anybody at home using IE6 is doing so out of a lack of knowledge
that they should install updates, or simply use a better browser.
You are working your arse off, wasting large amounts of time banging your head against
IE6 bugs, for a group of people who only need to be shown how to install a better
browser. It?s like spending tons of money and effort in healthcare dealing with the effects of a
disease, when all the time you have the cure in your hand and just need to give it to the people,
or tell them where to get it.
The lack of + and
> selectors mean that IE6 won?t go
near an element without a class or ID in sight. This is insane to be writing code this
way. This website has no IDs, no classes and no DIVs to show that crazy tag-soup is
not necessary.
You will be able to produce far greater things if you throw away the millstone around your neck
that is IE6 and start learning everything that?s been possible for the last
five years.
Do not block browsers from the content, citing ?compatibility?
This is going to be quite controversial coming from me when I?ve just said to you above to drop
IE6 support and even my own site does not display correctly with Internet
Explorer, but don?t bring up a splash screen that outright blocks
Internet Explorer (any version), or any browser for that matter from
accessing the content of your site?no matter how
pretty said
screen looks.
If you don?t like IE6, don?t waste your time writing messages (or drawing
pictures) for it (you haven?t got Stockholm syndrome have you?). Would you outright block
Lynx users, or Dillo users or any user of an alternative browser that
isn?t ?compatible? with your site? Why attack only IE6 when the list of browsers
that will be compatible with your site is smaller than the list that are not?
The fact your site looks wrong is besides the point, somebody?s life could depend on being able
to access the content on your site when all they?ve got is IE6 because of whatever
reason. I?ve had to access stuff on my site using IE when on other people?s
computers or at a public library. You yourself should know that all that matters is the raw text in
those kinds of desperate situations, not how it looks.
Completely blocking any browser?IE6 included?goes against the very nature of
HTML and CSS, formats that are designed to be universally accessible and
still be readable with even the littlest of support.
If you are really concerned about how your website looks on an eight year old browser (would you
honestly still use and support Netscape 6?), then place a message at the top of the
page telling the user to upgrade their browser, but don?t hide the content, the text still
matters to the user.
If the layout and content is totally broken by IE6?s partial CSS
support, then consider using
?Universal
Internet Explorer CSS?, a stylesheet that provides a back to basics
design for IE6 that can communicate the text clearly and forego your complex layout completely,
allowing you to focus support on better browsers.
Any suggestions or comments, send them my way; hit the name link below.
ReMarkable is my own
Markdown-like syntax, used to
write and publish the content on this site.
It is a plain-text method of writing articles that is then converted into HTML.
To skip the talk and see it in use, you can add ?.rem? to the end of any article on this site to see the original
ReMarkable source for the article. For example:
?/code/remarkable.rem?.
Version History
v0.3.2?17th June ?09
Default ?base_path? changed to ?.?
Fixed segfault with PHP, memory overflow in the regex for PRE blocks
Corrected warnings when PHP ?error_reporting? switched on
Unicode multiplication symbol ?×? for ?4×4?, ?Increased 3×!? or ?6ft × 10ft?
New line-break convention supported: ?space-underscore? at the end of a line,
e.g. ?The quick brown fox _?
?`...`? now allows double-backtick inside and ? ```` ?
gives ?<samp>``</samp>?
?`...`? is now <samp>, and ?``...``? for
<code>
v0.3.1?20th April ?09
Superscript was failing on ?10^th? as the unicode quotes confusing the
regex
I have a lot of HTML. In writing and tweaking the content on this site, I found I was getting bogged
down in a lot of HTML tags for relatively minor things, such as links,
abbreviations and citations.
Though I love writing in HTML, I wanted to reduce this complexity and focus more on the content than the
markup.
The first place I turned to was
Markdown, probably the most
widely known plain-text formatter. John Gruber wrote Markdown for his site,
daringfireball.net and to suit his way of writing articles.
There were a number of shortcomings with Markdown when placed against my site:
No support for abbreviations, citations and definition lists
Perl. No hope I?d ever be able to customise it
Working around these concerns of mine could have been possible by using another Markdown clone that
would be easier for me to customise. A project called
PHPMarkdown implements a
Markdown parser in PHP, it also adds to the syntax, providing additions like abbreviations
and definition lists.
There?s one big problem with PHPMarkdown though. Its size. My site?s php is
almost 600 lines long. PHPMarkdown is almost 3?000 lines long. To include PHPMarkdown in my site would
be like strapping an elephant to a flea and asking it to jump a canyon.
Really then, what I knew I had to do was to write my own Markdown clone, in my own particular demeanour.
I could cherry-pick the best syntax I wanted, but ultimately make it as artful as Camen Design is itself.
Features
At a glance, compared to Markdown, ReMarkable has:
?. More Inline Syntax:
ReMarkable adds syntax for {abbr|abbreviations}, ((small text)),
~citations~, [insertions], ---deletions--- and
«inline quotations».
?. Definition Lists:
The PHPMarkdown
syntax doesn?t allow for optional descriptions, where as the HTML spec, and
ReMarkable does.
:: Definition Term Description?:: Definition Term 2:: Definition Term 3 Description?
You can see this structure put to good use in this article.
?. IDs in Headings:
An idea taken from PHPMarkdown, for the benefit of writing a table of contents, or others linking to
specific parts of an article, headings can have an HTML ID like so:
Using my PHP port of David Gouch?s
toTitleCase, headings are
automatically correctly Title Cased by ReMarkable
?. Automatic Table of Contents
Using the special marker &__TOC__; ReMarkable will generate a table of contents for
each heading after the marker that has an ID.
?. Automatic Marking-Up of Links:
Links with absolute URLs are automatically marked up with rel="external".
Hyperlinks directly to a file have the type="mime/type" attribute added automatically for the most
common file types. ReMarkable has an easy to modify internal list of these types automatically recognised.
The benefit of this is that a) you should be doing this anyway, and b) you can use CSS mime-type icons
like this.
?. Intelligent List Paragraphing:
ReMarkable intelligently adds <p> tags to
<li> items.
A normal list:
If any list item contains more than one paragraph, or any other block such as another list or blockquote, paragraphs
are automatically added.
? Item 1? Lorem ipsum dolor sit amet, consectetur adipisicing elit. sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.? Item 3
Produces:
<ul> <li>Item 1</li> <li> <p> Lorem ipsum dolor sit amet, consectetur adipisicing elit. </p><p> sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </p> </li></ul>
But, if you put blank lines between the list items:
Lastly, if a list item contains no space between the opening text, and a list within the list item,
ReMarkable does not add the first paragraph. Why? For a table of contents list:
1. Features 1.1. More Inline Syntax: 1.2. Definition Lists: ?
Notice Features is not wrapped in a paragrah.
ReMarkable does all of these conversion cases using only one regex replace.
?. Human Readable Output:
In order for ReMarkable to be acceptable, it had to replace my hand-written HTML.
ReMarkable outputs clean and organised HTML and does perfect word wrapping so that when you
view-source you don?t have to scroll sideways.
ReMarkable can also indent the whole output to your liking, so you can fit it into your blog template.
<pre> blocks are intelligently unindented so that your code samples don?t break trying to fit
ReMarkable output into your site design.
Remarkable Code
Whilst not on exact feature parity with PHPMarkdown, ReMarkable achieves its design with
very compact code.
PHPMarkdown is spread across 120 functions composing two classes.
ReMarkable is nearly 400 lines long in just one function.
Lists, definition lists and blockquotes are recursively converted (including all the conversion cases mentioned
above) in two lines of code. Needless to say, the regex kills a kitten each time you run ReMarkable.
ReMarkable?s code has been a real labour of love. I have
tried to make sure it is well commented, but the tricks being used to reduce the amount of looping, and to achieve
all that it does within one function can be difficult to understand. A future
UndertheHood article will do a more detailed breakdown of the
PHP used.
What?s Next?
The goal with ReMarkable was to be able to publish my entire site?s contents. That has been achieved.
Now ReMarkable is in your hands. I?m sure you?ll find a million bugs I never noticed. I don?t
write articles the same way you do. Send bugs and suggestions to
kroccamen@gmail.com.
What?s Planned
There are a number of shortcomings of ReMarkable that I?m aware of and will be tackling at various
stages of the future (as Camen Design?s needs demand, really).
Any suggestions for features, is always welcome.
Priorities
That said however, ReMarkable was not designed to ever be all things to all people. In accepting
suggestions and fixes into my version of the code, these are ReMarkable?s priorities:
HTML5, UTF-8. No classes
If you need every HTML tag to have a class or ID you need to learn
how to write better code.
ReMarkable doesn?t output any HTML5 specific tags, so it?s safe to use in
HTML4
Sloppy writing is not a fringe case
ReMarkable will never allow escaping of characters. That?s a cop out to avoid
properly designing the syntax.
Any weird text you?re writing that?s firing off ReMarkable syntax is more than
likely a computer term or technical quote and should be wrapped in `code` spans.
For example: I copied the ~luser folder to ~root would be recognised as a
citation between the two tildes. Regardless of any literal readability, these folder names
(including the tilde) are not part of the English language. Use
I copied the `~luser` folder to `~root` instead.
If the bug can be solved by following the syntax documentation correctly, or by changing two or
three letters in your source, then it?s not a bug.
Code is Art
If I can?t maintain elegance and beauty in the code then it can?t be worth it.
published on 2008-12-16 10:17:00 in the "code" category
?. the Need for CSS-Hacks
In a world of imperfect browsers, the CSS-hack can be both a beautiful thing, and also an ugly thing too.
It is unavoidable that at some point some feature or design you wish to implement hits a limitation or parsing /
rendering bug of one (or more) browsers you are supporting.
If this has never happened to you; well done?you?re an IE only web-developer who?s never stepped
outside of Microsoft software, nor table-based design. You?re probably confused by the term CSS.
If, however, you do not own that privileged position of ignorance, everybody comes across the need to target a
particular bit of CSS to a particular browser.
?. the Question of Maintenance
There are manyarguments about if CSS-hacks
should be totally avoided, embraced, or properly managed somehow.
Firstly, to think they can be avoided is naïve. I have a website that only supports Acid2 compliant browsers, uses
CSS3 liberally, and doesn?t support IE one iota?and still I have CSS-hacks
to deal with browser idiosyncrasies.
The next two lines of argument are either a) just embed hacks in your normal document?it?s less maintenance to
only edit one document and b) keep hacks to a separate file where they can be managed individually, ideally using
conditional comments to target IE specifically or Javascript to correct behaviour.
Embedding CSS-hacks in stylesheets increases maintenance by making them an integral part of testing in
all browsers. CSS designed to correct one browser may have undesired effects on another browser. Or a
hack that has been used before, may no longer work on a newer version of a browser, but now you have to scramble to
somehow support both browsers.
A hack is anything that has the potential to fail disastrously
each time something changes expectedly.
Having to make corrections to your whole stylesheet to please one browser, is unnecessary maintenance. Having all
your failure points in one document is not less maintenance. I have not very fond memories of having to rewrite large
portions of a stylesheet because of being unable to please one browser without effecting
sic others.
The answer therefore is to tie CSS-hacks?or at least alternative CSS?directly to the
browser it fixes, so that it does not becoming a ticking time bomb for other browsers and future versions.
In the case of IE, conditional comments give very precise targeting
capabilities. Conditional comments are an excellent solution for applying alternative CSS, rather than
relying on CSS-hacks preying on broken parsing. However, there are a couple of let-downs:
IE Only
Conditional Comments rest inside the HTML
Having to maintain HTML because of a browser, is like suddenly waking up one day to discover that the
letter Z has been officially depreciated by the European Union and now you have to update all your documents to conform.
Your HTML, like diamonds, should be forever.
Lastly, using a Javascript fix is only increasing the length of thread you have to follow when something breaks. If
suddenly you find that a CSS property you apply does not have the expected behaviour in IE,
but gives different results with the Javascript fix on, and then off: you now have a maintenance nightmare that
involves back-tracking through ?x?-tons of Javascript, that likely, you didn?t write yourself.
What if a new version of a browser comes out and your Javascript fix doesn?t work with that browser, but also, the
site design won?t render correctly without it? Now you?re forced to either remove the Javascript and do the
CSS again, properly, from scratch; or update the Javascript with all the work that entails.
A solution is needed that:
Works for all browsers and does not rely on browser-specific capabilities to implement
Negates the need for CSS-hacks, and instead encourages alternative CSS
Targets browsers/versions specifically or according to a range
Does not fail when a new browser or version arrives on the scene
?. the Answer Is Still Targeting
We all know that user-agent targeting is bad. It defeats the purpose of having standards to work across all browsers.
However, thus far, we have, by proxy, ascertained that there are two types of CSS:
CSS that works in all browsers
CSS that does not work in all browsers
The maintenance problems so far outlined are because there is no clean separation of these two?except for
IE conditional comments, with the acknowledgement that they are an incomplete solution.
We have also ascertained that browser-specific CSS is eventually required given imperfect browsers. You
can either choose to compromise on your design to avoid this, or compromise on the browser and keep the design.
Either way, the end-user should never be compromised on.
It?s important to state that writing standards-compliant, proper CSS is always desired. Legacy
browsers are exactly that: legacy. Therefore a solution to dividing the two types of CSS must primarily
acknowledge that proper CSS comes first and does not require any maintenance going forward. The current
solutions mentioned earlier do not give weight to the better CSS over the bad CSS.
Basically, with a perfect solution, a perfect browser would never parse any hack or CSS intended for
only one browser?it would be ignorant of legacy browsers.
The important thing with User-Agent targeting is the ability to also not target user-agents. Some believe
user-agent targeting to be a form of quicksand that has you chasing after every browser ever made.
A browser that applies the standards, and requires no browser-specific CSS to render the
design, does not need to be targeted. No solution is actually needed.
My proposal is therefore a solution only for legacy browsers. If a browser does not need browser-specific
CSS to get it to render a design right, then it requires zero maintenance on part of this solution.
There is no interference by the solution to browsers that do not need it.
The Solution
Apache?s mod_rewrite module allows us to take a file requested by the browser, and
provide a different file instead, based on some matching or non-matching criteria.
What if we had a ?fixes.css? file that was different for each browser that needs to be targeted, but
void by default so that any browser that doesn?t need fixes, doesn?t get any?
We start with two stylesheets declared in the HTML head element:
You write your main stylesheet using absolutely no CSS-hacks or browser-specific
workarounds. Write for the future. As more and more browsers come on board with Acid 2 / 3,
CSS3 compatibility &c. they should automatically fall into working
with your site?zero maintenance needed.
Remember, this mod_rewrite solution is only to bring non-complaint browsers into spec.
Ideally, for example, you?d write your stylesheet to meet Acid 2 capabilities and when IE8 is released
the site just works, and the IE7 workarounds stay with IE7.
The actual ?fixes.css? file itself is, therefore, completely blank.
In your ?.htaccess? file use the following two lines to target a browser and rewrite the ?fixes.css? file to
a browser-specific version: (IE7 in this example)
(Assuming you?ve already got ?RewriteEngine on? in your ?.htaccess? file and
?RewriteBase?
if needed.)
This selects a user-agent containing MSIE 7. as long as it?s not followed by Opera at some point (to
ignore Opera spoofing as IE). The ?fixes.css? file is then rewritten to a ?fixes.ie7.css? file
where you may store the IE7 specific fixes you need to apply.
Now users of IE7 will receive a different ?fixes.css? than users of any other browser.
It?s a bit like having a user style on your own website. You
can apply a CSS ?patch? to the site for specific browsers, keeping your main stylesheet legacy free
and future-facing.
Potential Uses
Use @font-face to render titles using embedded fonts, but fall back to images on
unsupported browsers
Use box-shadow and text-shadow effects in the main stylesheet, but fall
back to transparent PNGs or generated content to replicate the effect in older browsers
Provide a ?lo-fi? design for legacy browsers (try viewing
this site in a good
browser, and then in IE6)
In short, old browsers shouldn?t prevent you from using the latest and greatest that up-to-date browsers offer.
It?s up to you to keep legacy where it belongs.
Addressing Concerns
?Aha!?, I hear you say. ?But surely this creates more maintenance, now we have many
CSS files!?
With this solution, when you make a browser-specific correction, you only need to test in that browser itself. Less
maintenance. Without this solution, a browser-specific fix also gets parsed by all browsers, and you need to test
them as well. More maintenance.
?But now you have to maintain the ?.htaccess? file!?
As browsers get more capable, the less browser-specific CSS you will need to target, if at all. An old
browser doesn?t stop being an old browser. As long as you?re not changing the HTML, this solution
can safely bit-rot without ever being looked at.
This solution also allows you to react smoothly and quickly to an unexpected regression between versions of browsers.
Imagine you try out a beta browser like Opera 10 or
Firefox 3.1 and you suddenly find
your design breaks with it. You can?without touching a line of your existing main stylesheet?add two lines to the
?.htaccess? file to detect the new browser, and then develop, on a new sheet, the necessary fixes without
compromising any of the existing CSS. You can then choose to leave that as is, or then once working roll
it back into the main sheet. This is significantly less panic-prone than having to apply fixes for an unreleased
browser to a live, perfectly working stylesheet.
Imagine you want to stop supporting a legacy browser. With this method, you remove the two lines in the
?.htaccess? file, delete the specific ?fixes.css? file and that?s it?browser unsupported. Without this
solution, you would have to manually unpick the CSS-hacks from your main stylesheet and slowly rub-out
any influence that browser had on the design of the CSS. Sometimes the only way to truly remove a
browser?s influence from a large bit of CSS is to simply rewrite it (due to all the extra capabilities
opened up with newer versions that you should now be making use of).
?What about people/browsers spoofing user-agents??
Not a problem. Seriously. Writing the right regex to spot lame attempts at spoofing is not difficult. Many browsers
add like Gecko / khtml despite this being patently false. It?s becoming more common even to add
Firefox into Gecko browsers given Firefox?s weight in the market. It?s sad, really, that some have given
in to this pathetic behaviour.
If you?re literally browsing with a completely false user-agent by default, you are a) 0.01% of the
population and b) have a personality disorder, or something. Spoofing has it?s uses, but it?s legacy as well and
should be sent the way of the dodo (if browser vendors stop with this ridiculous behaviour of saying they?re
engines they are nothing like).
I hate wasting HTTP-Requests. If you want a fast site, it?s not bandwidth or file size that matters;
no, it?s the number of HTTP-Requests. Each one could have potential delays up to 1?2 seconds in
worse cases.
So there?s a severe flaw with this solution, the browser has to fetch two CSS files, even if the
browser doesn?t need any fixes. This is a tax on good behaviour!
There is a workaround for this that presents only one stylesheet to compliant browsers, but two stylesheets to those
browsers that need fixes.
And then, in the ?.htaccess? file, redirect ?main.css? to the fix sheets, for those legacy browsers:
RewriteCond %{HTTP_USER_AGENT}MSIEs7.(?!.*Opera)RewriteRule ^(.*)main.css$/$1fixes.ie7.css [L]# ...# after legacy fixes, redirect ?main.css? to the actual main sheet ?_main.css?RewriteRule ^(.*)(?<!_)main.css$/$1_main.css [L]
And at the top of each fixes sheet, just simply import the main stylesheet.
(The main sheet uses a dummy name to prevent the @import from getting stuck in an infinite loop.)
@import "_main.css";/* browser specific fixes here... */
This way, a browser that needs correction gets the fixes sheet first (with the main stylesheet imported at the top)
and a browser that doesn?t need any fixes just gets the main sheet alone.
Example Reference
For those with worn C and V keys, here?s some additional rewrite conditions to select particular browsers (Add the
RewriteRule according to your chosen method). If you?ve any suggestions for good examples, do
send them my way
If you want some sample user-agent strings to work out the right regex needed for a particular browser,
here?s a good list.
Internet Explorer (Any Version):
RewriteCond %{HTTP_USER_AGENT}MSIEsd.(?!.*Opera)
Change d to any number to select a particular version
Do not ever try detect Firefox using ?Firefox?. Remember that Gecko,
the rendering engine that powers Firefox is used in many other browsers too that would have equal
capabilities, such as Camino. Many browsers now
spoof as Firefox too, so always detect using the Gecko date of the browser in the user-agent.
published on 2008-11-13 19:35:00 in the "code" category
I received this email:
Hi Kroc,
I stumbled on your website today and was quite impressed with quite a few different things about it (the
design, the tone of your writing, &c.).
The one thing in particular, and something I wanted to question you on, was your reference to
HTML5. Something I know nothing about. In the post I came across you talked about a guy named
Sam Ruby and how he referred to it as minimalist code. Anyway that?s beside the point. I?m really
interested in using no IDs and/or classes, but know nothing about HTML5.
So here?s my question, ? do you recommend any other resources or tutorials for someone like
me? I rely very heavily on classes and my stuff is sloppy for the most part. I?d love to convert my site
but have no idea where to start.
Any advice or words of wisdom would be greatly appreciated. Thanks in advance.
You only require one thing, and then to do three things in order to succeed in your goals here.
Firstly, you need to get some willpower. You already seem to have that, as you?ve taken interest to email me to ask
about where to start. Without the want to write better code, no learning in the world can help!
It should be noted that absolutely nothing I?m doing is undocumented; in that fact none of the code on my website
is even special?all it is, is the representation of my personal drive for quality, as I measure it.
I don?t think willpower is going to be a problem for you if you already twig that HTML5 and cleaner
code is the direction you might want to go. Some people don?t ever progress beyond writing
IE-only junk, and that?s not down to skill level, it?s a willpower
problem.
Secondly, you need to do three things:
revise,
revise,
revise.
I proof-read and break my code over and over again, to chip away what niggles me here and there. Getting rid of
classes is a one-by-one process, because each class has a use that may be totally unrelated to the other classes in
the document. Each class is it?s own problem, some big, some small?some requiring a complete rewrite even.
I?m quite happy to break my entire codebase for a week?rewriting and reorganising everything?just to get one
tiny annoyance out of sight and out of mind.
If you proof read your codebase you?ll spot various things that could be better, all of varying difficulty levels,
some maybe without a clear solution. Start by picking something that annoys you, that you know could be done better,
and fix it? even if it?s just tidying up a comment so that it looks nicer. Polish your code.
That is how I work. I scan through my code and look at it objectively. I think about where I can make it cleaner,
tidier, less complicated, better documented, easier for others to understand; anything that catches my eye.
I pick something that I personally feel motivated toward (I have no boss on my personal site, so I only have to fix
what I care about; and in that, the quality, through passion, is maintained) and I set about fixing it. Sometimes
that?s a big problem?like what I?m working on right now: a Markdown clone, so as to reduce the
amount of HTML I?m writing for minor things like abbreviations, links and citations
ReMarkable?or sometimes it?s a small thing like shaving
a few lines off here and there. I do whatever my heart feels capable of doing that day. I try never strain myself by
doing work I?m not interested in?that?s for secular work.
Once I?ve made my fix, I go through the whole process again. Often whilst I?m implementing one fix it unearths
other annoyances that I want to solve and I?ll either get distracted and go off and fix those, or wait until I?ve
finished the thing I started on and be well set with another task to do afterwards?with a much stronger
understanding of the problem to drive me forward with the design issues.
O, the design issues.
I am a slave to my code sometimes. I will not accept a sloppy solution. I pace around a lot. I wrestle with the
architectural design of the code in my mind for days. I spend 100 hours writing 29
lines of code. Because to me, good code is not about how l33t your programming knowledge is, good code is about
how much you rethink what you?re trying to do. What cohesive statement are you trying to make with your code?
Sometimes your code is not just about trying to solve a problem,
it?s trying to solve a problem using your personality.
But getting back to HTML5?
Before you learn HTML5, first learn HTML4. I know that sounds stupid, you may very well
think you already know HTML4. In learning HTML5, I first referred to
this list. Apart from the depreciated ones, do
you know how to use all of them? I found that there were a number of HTML4 tags that I rarely used, that
could easily replace sloppy <div>s and classes.
I see this often, and it really annoys me.
<div id="header"> <h1>Title</h1></div>
Elements that are not <div>s can be styled just the same as a <div>.
A <h1> is not somehow magically unable to have borders or backgrounds or margins or padding or
anything a <div> can.
People seem to get this mindset that only <div>s can be used as boxes.
Here?s a list of elements you can use instead of <div>s.
P, BLOCKQUOTE (with P inside),
H1/H2/H3?, ADDRESS,
DL/DT/DD, UL/OL/LI, HR
(Note: You can?t put a block level element in another. i.e. you can?t have a
H1 inside a P or vice-versa)
All of these can be styled with any effect?meaning that you can get rid of a <div> and/or
class, by just referring to the element directly, or by it?s parent.
And for that matter, why would you have a class for a menu item, when the menu is perfectly identifiable? Even in
this bad example, you could still get rid of the menuitem class, and just refer to them with
#menu div {...}.
An <ol> makes a perfect menu. It is after all, an Ordered List. Get to know what each of the
element names means, how you would think of that in a standard word processor document, and then how that can be
applied to your site, imagining your site as a word processor document without any CSS. Your menu would
be a table of contents of sorts, and therefore would obviously be an Ordered List.
He wanted the headings on the left blue, and the headings on the right, green. Which is fair enough.
However, could you not just select the column, and do away with the need for the classes?
/* as a rough example */#leftcol h2 {color: blue;}#rightcol h2 {color: green;}
Knowing, and using more elements, instead of resorting to <div>s all the time, allows you to use
CSS to select those elements more widely as well as specifically. Here, both of these are
<h2>s. Now if they were <div>s, we would have to use classes, because there
would likely be yet more <div>s in the columns and you couldn?t say #leftcol div
without turning many things blue or green instead of just what you wanted.
Getting rid of <span>s with classes requires knowing the meaning of the many inline elements.
Google them.
ABBR, ACRONYM, BIG, CITE,
CODE, DEL, DFN, EM, INS, KBD,
Q, SAMP, SMALL, STRONG, SUB, SUP,
VAR
Think of these elements outside of the browser, on a printed piece of paper. You can then bombard them with
CSS to make them look like anything?even if they don?t look anything like what they?re supposed
represent?but their use will be semantically sound, having the right meaning in your website.
If you know the selectors and the the tags well enough, then you only need a class (or ID) when you
cannot differentiate two elements from each other with the browser you are supporting. Since I?m using
CSS3 and not supporting IE at all, I don?t need
any classes because I?ve made the right choice of tags, and can differentiate all of them with the right
CSS selectors.
If you want clean code using few, if any, classes then right away ditch IE6. Stop supporting it, tell
people to upgrade. Without + and
> selectors, IE6 is too frightened to go anywhere that
isn?t within sight of a class or ID.
IE7 does support +
and >, and whilst it lacks in many other areas, it has the
necessary basics to write good HTML/CSS.
Check what your targeted browsers support.
Once you have made a decent HTML4 site, then you will look at the HTML5 specification, and
it will make sense?you will know what to do with it.
Here are some links to refer to in your adventures:
I?ve ported this to PHP and put it to use on this site. My version is based on David Gouch?s
Javascript port, unlike the WordPress
port which is, frankly, crap.
People are working on getting Perl support for Google App Engine, led by Brad Fitzpatrick (of Livejournal, memcached, etc. fame) at Google.
They've created a new module, Sys::Protect, to simulate the restricted Perl interpreter that would have to exist for Google App Engine. There's some discussion of why they didn't use Safe, but it sounds like it's based only on rumors of Safe problems, not anything concrete.
Safe is built on Opcode, and Sys::Protect appears to work the same way Safe + Opcode do, by blocking certain Perl opcodes. All the problems I've heard of and personally experienced with Safe were because it was working just fine -- but being terribly annoying because many common Perl modules do things a typical Safe compartment disallows. That's because most Perl module writers don't use Safe and thus never encounter such problems. It seems likely that Sys::Protect and a hardened Perl Google App Engine environment will have the same problem and will have to modify many common modules if they're to be used.
Moving on, posters are talking about having support for Moose, Catalyst, CGI::Application, POE, Template::Toolkit, HTML::Template ... well, a lot. I guess that makes sense but it will be a lot of work and complicates the picture compared to the simple Python and custom Django-only initial unveiling of Google App Engine.
If you're interested in Perl support for Google App Engine, log into your Google account, visit the "issue" page, and click on the star by the title to vote in favor of Perl support.
After reading a ridiculous post on "surviving the digg effect on a shared host," (and then laughing ridiculously at it), I decided to write a real tutorial on real-live ways not only to survive the digg effect, but also a simple but powerful way to improve your site's performance. Read more within.
Some time ago, I wrote an application for my company. Like most weblets I've written, this used PHP and either MySQL or MSSQL for the backend. This particular application logged all phone calls. As part of the record, it would record the caller's account number, which is a 5 or 6 digit integer.
So, I got a phone call from the director of our customer contact department this week. He was concerned about the reports. He made a decision last week that when a call came in that was a lead - in other words, a non-customer, that his people would fill the phone number from the caller ID into the account number field. But when he ran his export reports, he found that hisn techs had entered this phone number for ALL of the calls: 429-496-7295. That's weird, he said. So he called me and asked why that was. I checked all the calls and most were from one woman, so my first instinct was "Check if her browser has autocomplete turned on". But he swore that he tried it too and gotten the same result.
I checked the database and sure enough, it was right there: 429-496-7295, in all of the fields. So I went back to the code. In short, I took the input from the form, and declared it like this:
$accountnum = (int) $_POST['accountnum'];
Pretty straightforward: explicitly declare the type. So, I started my debugging by attempting to manually enter the data into the database. Sure enough: the account key field showed this: 4294967295.
So, I went back to the PHP and started by dumping out the raw SQL query:
INSERT INTO calls ('','x','x','x','4294967295','x','x');
What? So the database automatically converts it to this weird phone number and PHP does too? Suddenly it occured to me. One of the benefits of 64-bit computing is the ability to address more memory. There are limits to what can be done in 32-bit computing, and one is that integers have a limit! In this case, a database field called "integer" is limited to numbers between -2,147,483,648 and +2,147,483,647. It just so happens that the number is the same length as a US phone number - 10 digits. Changing the db field to "BIGINT" allowed me to manually run the SQL query and it worked. But the app still didn't.
PHP's int() and (int) $var syntaxes both conform to the integer limit. So I devised a work around:
$ac = $_POST['accountnum'];
if(!is_numeric($ac) { $ac = (int) $ac; }
It's not gorgeous, but it will more than suffice for an internal app. We web programmers don't usually have to deal with big integers, so it's totally possible that web developers would never have had occasion to handle a situation like this. Here's looking forward to native 64-bit for our next server, though.
This is going to be a very nerdy post, because I'm going to get into some actual PHP code. I've been thinking a lot about efficient threading. The implementation of threading on OSNews is very complex, because it involves lots of math in order to properly construct and align tables. Furthermore, because we don't use CSS for positioning, it's accomplished via 'align' commands and TWO templates, which is really clumsy, because between flat mode, admin mode, collapsed threading mode, and expanded threaded mode, we have several templates, and since they are all independent, they tend to unintentionally vary, so you might see different things in replies and threads. My goal in writing a threaded display for firsttube.com was to avoid all of the pitfalls in that implementation and come up with something clean. Read on for the gory details.
I am going to start a new practice here. Every now and again I'm going to post some PHP code with some explanation. Today, I'm going to write about what I've been calling "pretty URLs" and how to create and manage them in PHP.
PHP includes a variable in the superglobal scope $_SERVER called "PATH_INFO." PATH_INFO includes information entered after the name of the requested script.
Let's use firsttube.com as an example. The URL of a story is constructed as such: