Google has a habit of heavily documenting their products and here I will share a method for customizing the JavaScript snippet that powers the Google Custom Search engine for your site.

Accessible Google Custom Search

Wed Mar 9, 2016

For all of Google's efforts to promote accessibility in web standards, it came as a bit of a surprise to learn that Google's Custom Search Engines are not entirely 508 compliant.

Fortunately, Google has a habit of heavily documenting their products and here I will share tips for customizing the Google Custom Search Engine on your site to comply with accessibility stardards.

The two major problems with GCSE is that the markup element tag: <gcse:search> fails validation, and images used in the rendered HTML (the magnifying glass and the Google Branding logo for users of the free tier) are missing "alt" attributes values, which means that visually impaired users using a screen reader will not be able to know that the search box is there!

HTML5 markup

We can rectify the first issue easily by implementing the Google Search Box and Search Results Container using HTML5 markup with a <div> tag, as referenced in the GCS documentation here:

https://developers.google.com/custom-search/docs/element#html5

The <div> tag can be used with the search engine type added as a class attribute, and any other supported attributes added as data-* attributes. Search engine types can be:

  • gcse:search
  • gcse:searchbox and gcse:searchresults (for two-column setup)
  • gcse:searchbox-only and gcse:searchresults-only (for two-[age setup)

For additional functionality, you can reference the list of supported attributes here:

https://developers.google.com/custom-search/docs/element#supported_attributes

For example, the following is valid HTML5 markup to add the searchbox to your page:

<div class="gcse-searchbox" data-resultsUrl="http://www.example.com" data-newWindow="true" data-queryParameterName="search">

Injecting Alt Attributes for Images

It's not so easy adding HTML attributes values to elements that don't exist until after the are generated by GCS's JavaScript. If we were writing this javascript functionality ourselves we could use a JS window.onload() or jQuery $(window).load(){} function to trigger our code after the whole page is finished loading. We could also trigger our repair code after a delay of a few seconds. But these solutions can be error prone and are not optimal to ensure consistent behavior.

A better option would be to use a callback function to trigger our repair commands after the GCSE JavaScript generates the searchbox markup and to have it integrated with our GCS code snippet. The good news is that GCS documentation does describe a way to implement a callback function where we can customize our output and modify the generated HTML.

In the GCS documentation we can learn how to pass tag parameters to the window.__gsce object and add our code to the snippet that we acquire from the Google Custom Search Dashboard. This is documented here:

https://developers.google.com/custom-search/docs/element#tagparams

This is an example of a google custom search code snippet from the Google Custom Search Dashboard:

Google Custom Search Dashboard Get Code Screen

<script>
  (function() {
    var cx = '000000000000000000000:xxxxxxxxxxx';
    var gcse = document.createElement('script');
    gcse.type = 'text/javascript';
    gcse.async = true;
    gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
        '//cse.google.com/cse.js?cx=' + cx;
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(gcse, s);
  })();
</script>

Here, we are concerned with the lines between the <script> </script> tags. Before the line beginning with "( function() {" we can define our callback function and attach it to the window.__gcse object.

We'll name our callback function "imgAltTagsFix" and use a few jQuery statements to find the image and input elements that use the magnifying glass and the branding logo and we'll use jQuery's attr() method to create new "alt" attributes for those elements and define their values:

var imgAltTagsFix = function() {
  $('img.gsc-branding-img').attr("alt", "Google Custom Search Branding");
  $('input.gsc-search-button').attr('alt', "Google Custom Search Button");
};

Next we name the window.__gcse object and assign our function as the value of the callback:

window.__gcse = {
  callback: imgAltTagsFix
};

So our complete code snippet now looks like:

<script>
  var imgAltTagsFix = function() {
    $('img.gsc-branding-img').attr("alt", "Google Custom Search Branding");
    $('input.gsc-search-button').attr('alt', "Google Custom Search Button");
  };
  window.__gcse = {
    callback: imgAltTagsFix
  };

  (function() {
    var cx = '000000000000000000000:xxxxxxxxxxx';
    var gcse = document.createElement('script');
    gcse.type = 'text/javascript';
    gcse.async = true;
    gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
        '//cse.google.com/cse.js?cx=' + cx;
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(gcse, s);
  })();
</script>

We can place this code into the Actions > meta data > additional code > before body close section of our site's templates and our published pages will now have our custom image alt attributes assigned to them.

Google Custom Search alt attribute code

Advanced Searchbox with a custom form element

For developers that want a more customized solution, it is possible to create a custom HTML form element to implement our Google Custom Search Engine. This would obviate the need to implement the above repairs to the code provided from the GCSE dashboard.

This is not really documented in Google's reference but an example of this would be:

<form action="//wwwnew.percussion.com/search-results.html" class="searchform" id="cse-search-box">
    <input name="cx" type="hidden" value="YOUR GCSE CX VALUE HERE">
    <input name="ie" type="hidden" value="UTF-8">
    <label for="q" style="display: none;">x</label>
    <input class="search-box" id="q" name="q" onfocus="document.getElementById('q').value=''" type="text" placeholder="Search...">
    <input type="submit" class="search-button" value=" ">
</form>

Note: If you are using the custom form element with the free GCSE account or did not turn off Google branding on the paid GCSE account, Google will still inject a branding image into your form element without an alt attribute. In this case you will still need to add custom JavaScript to add the attribute for 508 compliance. 

Piotr Butkiewicz
Piotr Butkiewicz
Web Consultant | Percussion Software

N/A