Skip to main content

Welcome to Geoff Hayward's Weblog

Commenting on Java, JavaFX, Java EE, Joomla, and IoT.

Do you need to know how to make CSS border gradients? This swift article will show you how to make a pseudo cross browser border gradient. CSS Border gradients are easy to make once you know how, and with the right tool. The border gradients in this article work across browsers without using images to fall back on.

Making the CSS Gradient

Let's start by making the CSS gradient. Surprisingly CSS gradients can be made to work across most of, if not all of, the browser you are normally developing for. The tricky part is each browser has its own implementation. However, there are great tools online to take the labour out of making gradients. So we will make life easier for ourselves and use one.

The CSS gradient tool I've found and like is the colorzilla gradient editor. The makers of the Colorzilla gradient editor tool provided a brilliant browser-based interface that comes with all the instructions you need for making the gradient.

Making the CSS Gradient a Border Gradient

In the solution below is the CSS gradient that was generated by the Colorzilla gradient editor tool. I've put the gradient CSS inside a class that is named 'border-gradient'.

Using this CSS we will make a border or at least a pseudo border (pseudo as in not real as opposed to a CSS pseudo-class). To do this just add padding and make sure the box doesn't collapse. You can stop the box from collapsing by using an in-line block or by floating the box with its overflow property set to hidden.

Then just put a box inside of the box and set the background to a solid colour. The box that is inside the box needs to be displayed as an in-line block. That is it - I said it was easy. Easy with thanks to the hard work that the online gradient editor tools of course, without them it would be tricky.

CSS Border Gradient Demo

See the border gradient example.

CSS Border Gradient Solution

.border-gradient{
	background: #58332b; /* Old browsers */
	/* IE9 SVG, needs conditional override of \'filter\' to \'none\' */
	background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzU4MzMyYiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNiZWYwZTQiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
	background: -moz-linear-gradient(top,  #58332b 0%, #bef0e4 100%); /* FF3.6+ */
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#58332b), color-stop(100%,#bef0e4)); /* Chrome,Safari4+ */
	background: -webkit-linear-gradient(top,  #58332b 0%,#bef0e4 100%); /* Chrome10+,Safari5.1+ */
	background: -o-linear-gradient(top,  #58332b 0%,#bef0e4 100%); /* Opera 11.10+ */
	background: -ms-linear-gradient(top,  #58332b 0%,#bef0e4 100%); /* IE10+ */
	background: linear-gradient(to bottom,  #58332b 0%,#bef0e4 100%); /* W3C */
	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#58332b\', endColorstr=\'#bef0e4\',GradientType=0 ); /* IE6-8 */
	padding: 3px;
	display: inline;
	float: left;
	overflow: hidden;
}
.border-gradient .border-gradient-content{
	background-color: #FFFFFF;
	display: inline-block;
}

Conclusion

This solution gives the effect of a gradient border. People who view it will perceive a gradient border. Importantly, this solution works across all browsers, I have tested it in IE 7 through to IE 10, Opera, Safari, Firefox, and Chrome.



Read

This article is written to impart a short cut in getting to the content of an XML document from within a JavaScript script quickly and consistently across browsers. You will see that by skipping the XML document's DOM all together time and bytes are saved.

There is also a second good to the solution that is conveyed in this article. To the best of my knowledge earlier than ie9 versions of Internet Explore do not treat RSS feeds as XML. This means in an Ajax's XMLHttpRequest object there is no responseXML document to work with and that can be a gotcha. Of course you may be able to change the header for RSS documents server side. However let's assume you cannot get access to do so as this article is about dealing with XML responses generally.

Getting the Text from XML the Normal Way

When the XMLHttpRequest object of an Ajax call returns with a responseXML you have a document. A handsome document full of information but, getting hold of the information is not so easy. There are traversals to make you dizzy, elements to store, and then there are cross browser issues for getting hold of the text nodes themselves.

An XML Traversal Example:

var items = responseXML.getElementsByTagName('item');
var title[3] = items[3].getElementsByTagName("title")[0];
var desc[3] = items[3].getElementsByTagName("description")[0];

And in reality there will be a for-each loop or for loop in there somewhere. There will be variables storing elements – allsorts going on. It may not be the hardest thing to do but the JavaScript file is growing byte by byte and the cross browser issues are afoot.

The XML Text Node Cross Browser Issue

Some browsers get hold of the text node like this:

.textContent
Others browsers get hold of the text node like this:

.text

This means making a function that will return the content whichever way the browser likes to work is a likely root. In other words, more bytes are added to the JavaScript file just to deal with cross browser differences. It is at this point you realise you are not working smart and are going down the wrong root. But, there is the better solution.

Getting the Text from XML the Smart Way

While the DOM is normally a good thing in this case it only serves to get in the way. Introduce regular expressions to the mix and add a little responseText and your smart cake is well on its way to tasty.

You may ask: What about the lack of single line mode in JavaScript's regular expression? And I would say good question. The answer is 'no problem' and it is all thanks to:

[\s\S]

This means from the group, denoted by the square brackets, of white space characters and not white space characters. That's right anything and including new line characters.

The example below uses regular expression to collect all the items from an RSS feed into an array. Then it takes the index for getting a random item. It then templates the item as appropriate and finally appends the templated item into the DOM of the main HTML page.

new Request({
    'url': '/testimonials.rss',
    onSuccess: function(responseText){
        //split items into an array 
        var items = responseText.match(/<item>[\s\S]*?<\/item>/g);
	
        // pick an item at random 
        var rand = Math.floor(Math.random()*items.length);

        // template the data 
        var html = '';
        html += /<div class="feed-description">(.*)<\/div>/.exec(items[rand])[1];
        html += '<p class="title">' + /<title>(.*)<\/title>/.exec(items[rand])[1] + '</p>';
        html += '</div>';

        //then wrap and append it to something 
        var testimonial = new Element('div', {
           'class': 'testimonial'
        }).set('html', html);
        $$('.testimonials')[0].grab(testimonial, 'bottom');
    }
}).send();

You can of course template all the items of the feed or nodes of your document the first few items or whatever you need. Using the same method you can get hold of any part of the item or whatever your XML document is. For example:

html += '<a href="' + /<link>(.*)<\/link>/.exec(items[rand])[1] + '">Read more</a>';

will add a link back to the article source as given in the RSS feed.

Conclusion

As XML is often the transport medium given in response to many Ajax requests, it is important to have a good cross browser solution that doesn't necessarily weight down the scripts size. This method is a way of dealing with what has been returned across all browsers without the need of extra functions that only serve to make your solution work a cross browsers. I am finding this approach works very well and it is worth sharing. What do you think about this approach?



Read

Mailing List


Responsive Media

With the ResponsiveMedia plugin for Joomla it is easy to add 3rd party content from YouTube, Vimeo, and Instagram right in to any Joomla! article.

ResponsiveMedia