Safari's beautiful search tag is broken - let's fix that

posted: April 16th, 2007 · by: Sven

in: Css & Html, Programming · tagged as: , , , , , , ·  18 comments »

What?! Okay, you might well file this away as “Why in the world would I waste my time on this?” - “Ummmm, well … just because it’s cool, you know!” But watch carefully! As a matter of fact this is serious research and development stuff (of course) that deals with super-useful web technologies. :-)

Most probably everybody who’s high on Safari (you know, that “best browser in the world”) knows those beautiful search box HTML widgets that very much resemble Safari’s own search box in the address bar.

Everybody’s proprietary darling

Clearly I’m late to the party with this, but hey! :-)

So, first of all, for those of you who’ve been living under a rock, too, here’s what all this chattering is about:

In 2004 Apple added the search input type, a proprietary variant of the input tag to WebCore. Besides the new type there are additional attributes: incremental (features spotlight-like incremental searching), placeholder (is displayed as long as the widget is left alone), autosave and results (both used for a “recent searches” drop-down).

The syntax looks like this:

<input type="search" placeholder="Search" autosave="your.domain.name" results="5" />

And it will render like this (when unfocused/focused):

Safari's search tag tag looks like this

Now, what’s so cool about this? Aside from looking gorgeous, it adds value in terms of an enhanced user-experience. The usage patterns here are well known, e.g. from browser toolbar search boxes.

So why not just use it? The problem, of course, is that this HTML extension is proprietary. It won’t validate, but throw up to four ugly warnings:

Safari's search tag validation fails

Does this really need to be fixed?

When I redesigned my blog the other day and I included this search tag into the layout, almost immediately a friend of mine came up with a blunt “Hey dude, your markup doesn’t validate any more.” Oh, my gosh! :)

There are reasonable points about using non-standard-compliant, proprietary extensions. For example Random Genius phrased it like this:

<!--
  I know that using type="search" means that my page doesn't validate,
  but for safari users it offers such a nice search experience, and degrades
  nicely for other browsers, that there really is no reason why I shouldn't.
-->

… and even Zeldman seems to agree with Matt’s opinion that “there is nothing wrong with proprietary extensions from Apple, Microsoft, whoever as long as the standards are also supported”.

But on the other hand we don’t like breaking stuff superfluously either, do we? There’s something warm, fuzzy and satisfying about seeing this in Safari’s status bar:

Safari's status bar, no validation errors

… and to me that’s worth a little extra work. So let’s see what can be done with some simple, unobtrusive Javascript and CSS.

Check this out

We’re going to:

  • use a perfectly standard-conform default text input as a search field and give it a class named “search”
  • hook into the page load event, find the text input and
  • turn it into a Safari search input if Safari is looking at it
  • fake the look of the text field if another browser is looking at it

For the impatient - here’s a simple, working demo of this stuff (be sure to try it in Safari and e.g. Firefox):

Demo

Ok, let’s start with an input tag like this:

<input type="text" class="search" name="q" />

Next we need a way to hook into the page’s onload event. Assuming that we’ve already loaded Prototype.js we’ll use this library register the event handler:

Event.observe(window, 'load', beautify_search_inputs);

Once the page is loaded our beautify_search_inputs function will be called. This function iterates over all input tags in the document that have the class name search (mostly, there will be just one such tag). For each of these tags either the method make_search_input or fake_search_input will be called - depending on the browser type.


function beautify_search_inputs() {
  isSafari = (navigator.userAgent.indexOf("Safari") > 0)
  elements = document.getElementsByClassName('search', null, 'input')
  for (var i = 0; i < elements.length; i++) {
    if (isSafari) { 
      make_search_input(elements[i])
    } else { 
      fake_search_input(elements[i])
    }
  }
}   

That means, if we’re on Safari, the input tag will simply be turned into a type=”search” input tag:


function make_search_input(element) {
  element.type = 'search'
  element.setAttribute('placeholder', element.value);
  element.setAttribute('autosave', 'my.domain.name');
  element.setAttribute('results', '5');
}   

For every other browser we’ll at least try to partially fake Safari’s look:

To achieve this we’ll wrap it into a div, add two more div tags for the round endings (to allow a dynamic adjustment of the width) and hook up event handlers for the focus and blur events (to add that typical glowing blue focus):


function fake_search_input(element) {
  Event.observe(element, 'click', function() { 
    if (element.value == 'Search') element.value = '' })
  Event.observe(element, 'focus', function() { 
    element.parentNode.className = 'search-container search-active' })
  Event.observe(element, 'blur',  function() { 
    element.parentNode.className = 'search-container' })

  container = document.createElement('div')
  container.className = 'search-container'
  container.style.width = element.clientWidth + 'px'
  left = document.createElement('div')
  left.className = 'search-left'
  right = document.createElement('div')
  right.className = 'search-right'

  element.parentNode.insertBefore(container, element)
  element.parentNode.removeChild(element)
  container.appendChild(left)
  container.appendChild(right)
  container.appendChild(element)
}   

Of course these three additional div tags are a bit ugly. But I haven’t been able to come up with a more elegant way that also dynamically resizes the divs and works in several browsers.

There you have it.

  • Your page validates.
  • Safari users get the full proprietary Apple coolness.
  • All the other major browsers get a nice fake.
  • With Javascript turned of nothing happens at all and the widget “degrades” nicely to its pure input tag form.

How to install

You can find the source here:

http://svn.artweb-design.de/stuff/html/safari_search_tag/

After downloading you’ll probably want to integrate this stuff into existing CSS and Javascript files (if you’re not using an asset bundler, that is)

Pay attention to either put the image safari_search_tag.png in your /images folder or change the CSS rule in safari_search_tag.css accordingly.

Problems? Anything that can be done better?

Like I said this version relies on Prototype.js. So if you’re not using this library, you’ll probably need to use a different way to hook up the onload event handler.

Also, if you’re able to create the same visual effect in the same browsers with less additional tags, I’d highly appreciate learning about that.

I’ve checked this in no other browsers than Safari, IE 6.0, IE 7.0, Opera 9.0 and Firefox 2.0.

Feedback?

What do you think?

Leave a comment

18 Comments

  1. Caius Durling said May 27th, 2007 at 09:20 PM  

    Hehe, I love my block comment about type=search. I since fixed it (for php sites) by checking it in PHP & serving the correct one. Might try it with js at some point though.

  2. Sven said August 26th, 2007 at 01:19 AM  

    Hey Caius!

    Hehe, thanks for the inspiring article :)

    Yes, serving separate versions of a page for different user-agents is an option, of course. The drawback is that it breaks REST and is not easily cacheable though. I’d therefor prefer a solution that serves the same version to all clients. But … as always … mileages vary.

  3. Greg said February 27th, 2008 at 09:00 PM  

    Hi, i tried you example and it is the best!!! But…I have a problem…I already use the mootools library to perform other effects on my site… including prototype.js in the html document i get a conflict with my library.

    How can i set up the onload event handler with mootools? probably addEvent??? do i have to replace it with Event.observe ???

    Thanks a lot! (forgive my english if any mistake…i speak italian :P )

  4. Sven said March 3rd, 2008 at 08:13 PM  

    Hey Greg,

    sorry, I haven’t done anything with mootools, yet. So maybe you’re better off asking on some mootools related mailinglist or something?

  5. Gordon Frobenius said July 23rd, 2008 at 04:21 PM  

    Very cool. I’m trying to place this in the header of my site. It causes a page break because of the div. I added a display: inline; to the search-container in the css file, this fixes the page break but throws off the ends of the search box slightly. Do you know of a fix for this? Thanks.

  6. Rachel Scaperotta said July 29th, 2008 at 07:10 AM  

    stop being such a fag gordon. that would be a start….

  7. Matt Levy said February 12th, 2009 at 01:30 PM  

    Thanks for your excellent article. I have written a jquery plugin for this if anyone is interested?

    http://www.levsys.co.uk/products/jquery-safari-search-1.0/

  8. Adam said February 22nd, 2009 at 11:36 PM  

    This is fantastic, nice work!

    I’ve added one small thing to makesearchinput:

    element.setAttribute(‘value’, ”);

    This way there’s no text in the search field when the user clicks on it (and the clear button isn’t visible when the page loads).

  9. jack said January 23rd, 2011 at 11:38 AM  

    thanks for that headsup. That’s a useful tip! I’ve never ran into that, but for sure that’s something quite some people will need a solution for. cheap vps

  10. QQQ said February 7th, 2011 at 06:32 PM  

    Finally we kissed and the passion scale went sky high and I knew I was onto a good thing - sex was a certainty free porn videos. She never hesitated when I began to fondle her breasts and she willingly exposed them for me mobile porn. They were firm and I suspected a breast enhancement but said nothing - they still felt good and I was enjoying them and gradually working my way further south free porn tube. She was a step ahead of me and before I could completely undress her she moved on me atk hairy and I was suddenly having my pants pulled down and I was enjoying one of he best cock sucking hairy pussy experiences I had ever had. ABB728019394

  11. Neon2 said February 24th, 2011 at 07:05 AM  

    Will you alpha action adviser and verify Safari doesn’t accept 64 bit next to it! pass4sure 70-271 You can acquaintance me off account actuality to added troubleshoot the issue. pass4sure 70-291 Thanks for this column and for the work-around. pass4sure 70-442 I wouldn’t wish to use Safari after DeliciousSafari! pass4sure 70-454 Thanks for your work!

  12. Go ped said February 24th, 2011 at 01:46 PM  

    This way there’s no text in the search field when the user clicks on it (and the clear button isn’t visible when the page loads).Go Ped

  13. Jessica said March 13th, 2011 at 10:50 AM  

    Thanks for the little fix! It helps a lot and now I can go on with my life without worrying too much for this.

    Source: Porn Call

  14. chat said March 31st, 2011 at 07:30 PM  

    Here is the fixed tag -

    The following cleaned up the issue:

    Dependencies.loadoncepaths -= Dependencies.loadoncepaths.select{|path| \ path =~ %r(^#{File.dirname(FILE)}) }

  15. side sleeper pillow said April 22nd, 2011 at 07:00 AM  

    Nicely written article, Knowledgeable and informative post. I’m really glad I came my way along your site. Keep posting, I really like the whole topic. Thanks for sharing.

  16. Okey oyunu said May 12th, 2011 at 04:04 PM  

    Thanks for this article. Tüm dünya artik okey oyunu oynuyor. Yillardir bir çok oyun programi olmasina ragmen, içlerinden en güzeli olarak nitelendirebilecegimiz tek bir site göze çarpmaktadir. Diger tüm okey oyunu programlarinin aksine ücretsiz olmasi ve 3 boyutlu olarak hizmet vermesi mükemmel bir gelismedir. Sizlerde www.okey-oyunu.com adresinden bu essiz okey oyununu indirebilirsiniz. Kullanimi çok basit ve Türkçe dil seçenegi ile kolaylikla oyuna baslayabilirsiniz. Ister kendi ülkenizden, isterseniz dünyanin tüm farkli bölgelerinden dilediginiz oyun odalarini seçerek, oyuna hemen baslayabilirsiniz. Okey oyunu oynamak için artik arkadas bile aramaniza gerek kalmadan, bilgisayarinizdan 100 binlerce üye ile online olarak okey oyununu oynamanin zevkine varabilirsiniz.

  17. porno said May 22nd, 2011 at 01:29 PM  

    I do agree with all of the ideas you have presented in your post. They’re really convincing and will definitely work. Still, the posts are too short for newbies. Could you please extend them a bit from next time? Thanks for the post.

  18. porno said May 22nd, 2011 at 02:00 PM  

    good comment. thanks you friends.

    I’ve surfed the net more than three hours today, however, I haven’t found such useful information. Thanks a lot, it is really useful to me

Sorry, comments are closed for this article.

artweb design
Sven Fuchs
Grünberger Str. 65
10245 Berlin, Germany


http://www.artweb-design.de

Fon +49 (30) 47 98 69 96
Fax +49 (30) 47 98 69 97