Cross Browser Gradients - Basic Linear Gradient

CSS linear gradients (that run along a line) are supported by the latest versions of all major browsers:
  • Firefox 3.6+
  • Webkit 2+  (Chrome, Safari, Konqueror)
  • IE 3+
  • Opera 10.5+ (not v10.10)
As expected, no two browsers use the same syntax, and the syntax is not intuitive. The primer below covers basic usage, perhaps a later post will extend this to more advanced examples.

I. Simple linear gradient:

.linearGradient{
background-image: url('gradient.png');
background-image: linear-gradient(left, red, blue);
background-image: -moz-linear-gradient(left, red, blue);
background-image: -webkit-gradient(linear, left center, right center, from(red), to(blue));
filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=1, StartColorStr='red', EndColorStr='blue');
-ms-filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=1, StartColorStr='red', EndColorStr='blue');
}
<div class="linearGradient" style="width:100px; height:100px;"></div>

Line by line, this covers browsers without CSS3 support, Opera / W3C, Firefox, Safari & Chrome, IE 6 & 7, and IE 8.
If JavaScript is disabled, IE will not show the gradient.
II. Understanding the variables:

The CSS defines three items for each gradient: Its style, its direction, and its colors.

Gradient style

Either 'linear' or 'radial'.  For FF/W3C this is part of the variable name (-moz-linear-gradient), for Webkit this is the first argument ( -webkit-gradient(linear,...)) and for IE this is skipped. IE does not need this argument as radial gradients are not supported.

Gradient Direction:

In IE the direction is either type 0 (vertical) or type 1 (horizontal).
The type is set as an attribute of the filter: ....GradientType=0.... (top->bottom).

In Webkit, the direction is specified as the 2rd & 3rd argument: 
  • A start and end point must be specified, each consisting of a pair of space-separated values.
    • -webkit-gradient(linear, left center, right center, ... 
  • These values can be in pixels, percentages, or the keywords top, bottom, left and right (origin is the top left corner).
    • -webkit-gradient(linear, left center, right center, ... 
      -webkit-gradient(linear, 0px 50%, 100% 50%...  
3C / FF / Opera add the following to the Webkit implementation:
  • End position is not required (it can be specified using 'stops').
    • linear-gradient(left, ...
      instead of -webkit-gradient(linear, left center, right center)
  • The second [space separated] value is not required, defaults to 'center'.
    • linear-gradient(left, ...  
      instead of -webkit-gradient(linear, left center, ...
  • Gradient can be described as an angle (in degrees)
    • linear-gradient(45deg,...
  • Keyword 'center' will have gradient begin in center of element:
    • linear gradient(center,...
Gradient Colors

IE accepts 'start' and 'end' colors in keyword or hexidecimel (rgb/argb - see later) form:
Red can be written as:
  • red
  • #FF0000
  • #FFFF0000 
The colors are attributes of the filter:
..Microsoft.Gradient(StartColorStr='red', EndColorStr='blue'...
According to the docs, the final 'Str' in the attribute name is only required when a hex argb value is passed.  In practice, testing shows that this is the format that should be used always.
Webkit and FF both accept a 'from' and 'to' color as the last two arguments of the style.
Input of these colors are no different than all other colors used by the browser.
For example, red can be written as:
  • red
  • rgb(255,0,0)
  • rgba(255,0,0,1)
  • FF: hsl(0,100,100) / Webkit: hsl(0,100%,50%)
  • #F00
  • #FF0000
Webkit requires the start color to be passed as an argument to 'from'.
  • Webkit: -webkit-gradient(linear, left center, right center, from(red), to(blue));
  • FF:  -moz-linear-gradient(left, red, blue);
As you can see, the FF / W3C implementation is shorter, simpler and more powerful.  Lets hope Webkit comes on board soon.
(I normally use Firefox, but am writing this using Chrome.  It's appalling, though better than IE.)
III. Gradient from opaque to transparent:

All browsers support a opaque to transparent gradient, through an "alpha channel" - a way to represent the transparency of any color. 

In FF/Webkit, the alpha channel is a number between 0 and 1, and is after the other colors as rgba or hsla.
Three ways to signify transparency:
  • rgba(0, 0, 0, 0)
  • hsla(0, 0, 0, 0)
  • transparent
In IE the alpha channel is listed first, and ranges from #00 to #FF.
#00000000 - transparent
The following is the same gradient as above, but from transparent to blue.
.linearGradient{
background-image: url('gradient.png');
background-image: linear-gradient(left, rgb(0,0,0,0), blue);
background-image: -moz-linear-gradient(left, hsl(0,0,0,0), blue);
background-image: -webkit-gradient(linear, left center, right center, from(transparent), to(blue));
filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=1, StartColorStr='#00000000', EndColorStr='blue');
-ms-filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=1, StartColorStr='#00000000', EndColorStr='blue');
}

 

Loading mentions Retweet

Comments [2]

MooTools Forge Issues

We at Siteroller are in love with Mootools. 
We have been using it since version 1.0, and think, frankly, that the whole thing should be integrated into ECMAscript v2.

About half a year ago they created a public repository wherein anyone can create an upload their own Mootools classes.
A few years late, but better late than never.
If just it work.

It doesn't work.  Getting our MooRTE class in was hours of labor, and updating it has proven impossible.
Since there was a serious bug in our initial commit, this is a major issue.
From our complaint in January:

The forge update button is still not working.
The MooRTE plugin now has nearly 150 downloads.
And every one of them is broken.

Shortly after committing we found a major issue - not sure how it passed through testing - and went to correct it.

Now, nearly a month later, with dozens of attempts to update it ignored, I still have the same buggy commit up there.

Unsurprisingly, this has been a negative experience with our users - I don't know how many we still have.

A bug report was filed on the github branch, the IRC channel was haunted, to no avail.

Please; The forge is supposed to help the community, I beseech, beg, implore, and request if anyone who can look into this issue can please, please look into it.

Sincerely, a poor, desperate, Mootools developer.

The Mootools user group has several threads on this issue, and the uservoice page boasts several high ranking suggestions for this to be fixed.

Mootools has what it takes to dominate their field.  If they would but realize that the community is important.
I understand that Mootools is volunteer work - it includes some of my own commits.
And I understand that the Forge is being handled by just one developer. 
But it is the job of the Mootools team to see that such issues are out of they way if they wish to be taken seriously.

In the Forge plugin page it says:

Never should a plugin rely on a 3rd party link to explain its behavior or functionality. 
We need this to ensure that if a website is removed or becomes inaccessible, people can still enjoy your plugins' functionality.

For now, I strongly recommend that anyone who submits a plugin to add contact links in their README.md, and that you keep as little as possible on the Forge. 
[You] need this to ensure that if ..or [when the Forge] ..becomes inaccessible, people can still enjoy your plugin's functionality.

Loading mentions Retweet

Comments [0]

Quick Tip: Converting To & From A Hexidecimal

CSS accepts Red/Green/Blue color values written in either of two ways:
  1. An array (each value can be 0 - 255)
    background: rgb(255,255,255);
  2. A hexidecimal (each digit can be 0 - F)
    background: #FFFFFF;
The hex method uses base 16 to codify all values up to 255 in just two digits.
The letters A - F represent the numbers 10 - 15 respectively.
  • F1 = (16 * 16) + (1 * 16) = 272
  • 09 = (00 * 16) + (9 * 16) = 9

---

For the color picker, we needed an easy way to convert between the two notational values. 
Fortunately, Javascript has built in methods just for this, toString & parseInt.
(Both of which accept a number representing the base or radix that we are computing by.)

Converting to Hex:

var white = 255;
white = white.toString(16);
// white == 'ff'

Great! ...as long as the input value is above 16.  Otherwise, the returned value will be only one digit and will likely confuse the browser.
Since Javascript lacks an internal padding function, we will have to wing it:

var black = 0;
black = black.toString(16);
if (black.length < 2) black = '0' + black;
//black == '00'

There are better all purpose pad functions, but this is good for our needs.
BTW, all browsers can accept a 3 digit hex value, but when only one of the three colors is one digit that won't work.

Done.

Converting from Hex:

var white = FF;
white = parseInt(white, 16);
// white == '255'

Simple, no?!
One last thing - if you use Mootools, this is already built into functions called rgbToHex() and hexToRgb(), which is even simpler!
 var arr = '#FF0000'.hexToRgb();
// arr == [255,0,0]
Loading mentions Retweet

Comments [1]

Collapsed Margins and Free Margins

Two of the less well known attributes of margins that happen often enough.
Unfortunately, the oft-quoted  Sitepoint article on this subject makes quite a garble out of it.


1. Collapsed Margins.

According to the w3c, margins of different elements may overlap. 
Two <p>'s, each with a margin above and below of ten pixels, would only have ten pixels total between them.
While there are technically two separate 10px margins, they both occupy the same space.

In the example below, the (blue) margins are the same above, below, and between the elements.

<p>Hello</p>
<p>World</p>

Hello

World

To the best of my knowledge, there are no exceptions to this rule, and it works consistently cross browser.
While I would not have opted for this, it is logical, consistent, and well documented.

2. Free Margins

The margins of an inner element are not contained by an outer one.
Inner margins will just break right through and keep other elements away from the parent, while the parent wraps tightly around the child.

Imagine a <p> with a margin of 10px that is inside a <div>. 
The <div> will wrap the <p> tightly on top and bottom, but the <p>'s margin will keep any other element from coming close.

In the example, The div has NO margins of its own. The (blue) margin of the <p> is seen outside the <div>. The solid lines represent the borders of the div and the p (which are in the same place vertically).
<div>
    <p>Hello world</p>
</div>

Hello world


Exceptions to this rule abound.  For starters, this only applies to the vertical margins, and not the horizontal ones.
Furthermore, any one of the following CSS rules in the parent will prevent this behavior, even where these rules are the default.
  • overflow: [auto, scroll, hidden, inherit (non-IE)] ;
  • border: [solid];
  • padding: [1px];
  • position:absolute;
  • display:inline-block;
  • float: [left,right];
  • zoom:1 - In IE, anything that sets haslayout to true.
  • If the parent is the <body> element.
   
There is absolutely no logic for this behavior, though it is all there in the spec.
The abundance of exceptions make it difficult to get this right, and none of these exceptions actually have any reason for changing the behavior as it does.

I'd bet money that this was a bug in one of the earlier browsers and was included in the spec for the sake of backwards compatibility.
For consistency, I am entirely against it and recommend using whatever is convenient to have the margin bound in place.

However, it does happen, and it is more or less consistent cross browser (with the exception of the haslayout and inherit bits). Plan accordingly.


3. Putting the two together:

When the parent and the child each have a margin, the inner margin breaks free - right into the space of the outer margin..
Obviously, when two adjacent elements and their children all have margins, there will be quite some overlap.

Ah, don't we love CSS?!

Loading mentions Retweet

Comments [0]

The wireless HD format wars

Wireless High Definition.

For years, consumers have been waiting to hook up their 72" HDTVs wirelessly and enjoy the goodness of a clutter free home.

Despite promises that this would soon be standard and inexpensive (up to $100 for the feature), it's been a tough trip. Until recently it wasn't available at all in North America, and now it is mostly found using stand alone devices such as GefenTV's streaming devices.

But despite the size of those devices, the actual chip that does the streaming could fit in an iPod nano, and is generally made by one of three semiconductor makers.


Format wars both help and hurt - competition is good, but it causes delays and obsolete products even faster than Apple does.

In this case, SiBeam created a standard called WirelessHD In January 2008.

It runs in the the 60GHZ spectrum, which is available, though can interfere with other devices.
Sony, Samsung, LG, Toshiba, Panasonic, and Intel all came on board for the formalization of this standard.

A few months later, Atheros announced their own standard and alliance called WiGig (Wireless Gigabit Alliance).
Partners include Samsung, LG, Nokia and Intel.

Just after that, Amimon weighed in with their own standard - WHDI (Wireless Home Digital Interface), running in the 5GHZ spectrum.
Promoters include Sony, Samsung, LG, Toshiba, Motorola, Sharp and Hitachi.

Notice that the top supporters for each are the the same.
(Ever wondered how they got to be major corporations? Hedge your bets, kiddo.)

Meanwhile who needs any video standard?!  A generic format can carry video just fine - WirelessUSB and WiFi (802.11n) each have more than enough bandwidth to hold their own.  Microchip maker Cavium has been pushing their own NetHD chip, designed to optimize video for travel along these other standards.

Amimon's response is that by designing around wireless you can organise your packets in a way that prevents loss.
And while they may be right, brittleness can be seen in the lack of support for wireless 3D - none of the vendors are clear about exactly what support they will offer, and when.

So who's winning?

The WiGig group has been pretty silent.

SiBeam has been in the news quite a bit, and they did pick a better name for their technology (let that not be underestimated), but I haven't seen much by way of product around.

Amimon's technology seems to have a bit of the edge.

  • LG displayed an entire WHDI HDTV product line (26 devices!) at CES a few weeks ago.
  • Sharp has a bunch of TVs lined up for production.
  • Philips, Sony, Gefen, and others have been pushing their devices for quite a while. 
  • And a search around the net shows dozens of other places where they are innovating.

On the other hand:
An article on Engadget a few weeks ago claimed that Gefen TV would be switching to WirelessHD from WHDI.  Switching standards would break backwards compatibility, so we'll see how that develops.
UPDATE: They offer two products - one using WirelessHD with a range of 30 feet, and one using WHDI with a range of 100 feet.

Taiwan based Zinwell (or here or here?) has been doing well lately with their WHDI based devices, but news out of tradingmarkets is that they'll be switching to Cavium's NetHD any day now.

So, it's still too early to say anyone's really winning.

But the sooner these become reality, the better!

Loading mentions Retweet

Comments [0]

Tools Of The Trade: Payment Processors

Obviously, collecting money is an important eventual goal for most startups. ;)

There is a whole range of services out there, in several categories:

Third Party Collections (copy a few lines onto your site and forget about it):

Processing (There are waaay too many to list.  My top 3, but see this thread):
Recurring Billing:
Phone Charge (customer gives mobile number, charge is included in their next phone bill):
For gamers:
Accept Credit Cards via iPhone (Android apps in dev for both):
Other:
  • Account Debiting (Much cheaper than taking a credit card, but requires customers to give their bank details): Noca
  • Virtual money: Revolution Money Exchange
  • Health Niche [though it could be used more broadly]: ClaimsXchange
  • Group money management and billing: WePay
  • CMS/API: Shopify
  • Trust based purchase (user commits to pay - mostly for games or virtual goods): Kwedit
  • I have left out micropayments, as they deserve their own post.
Loading mentions Retweet

Comments [0]

Quick Tip: Check if array is empty

I. Check if array exists, even if empty:

var arr = [];   //true 
var arr = null; //false 
  • JavaScript
    if (arr)...
  • PHP
    if (isset($arr
    ))...

II. Check that array has at least one value. Falsey values count as not empty.

var arr = ['']; //true 
var arr = [];   //false
  • JavaScript
    if (arr .length)...
    There is no need for:  if(arr.length == 0)..
  • PHP:
    if ($arr
     )...
    The following will work, but is unecessary:
    • if (count($arr))...
    • if (!empty($arr))...

III. Check that array has at least one 'true' value.
var arr = [5];               //true
var arr = [0,null,false,'']; //false
  • JavaScript
    function mt(ar){
       for (var i = 0, l = ar.length; i < l; i++)
          if (ar[i]) return true;
          return false;
    }
    if (mt(arr))...
  • PHP:
    if (array_filter($arr)) ...
    Alternatively:  if (implode(arr)) ...

 

IV. Check that array has at least one 'true' value, being fancy.

Alternative syntaxes for Javascript, and handling for special truey rules (eg. when you wish to count a 0 as 'true'):
var arr = [0];             //true
var arr = [null,false,'']; //false
  • JavaScript
    This syntax is shorter and more flexible than above - but -
    Will incorrectly count strings '0' and 'false' as falsey:
    • Assuming 0 to be falsey
      if (arr.join('`').replace(/`(false|0)*/g,''))...
    • Assuming 0 to be truey
      if (arr.join('`').replace(/`(false)*/g,''))...
    • Assuming a space to be falsey
      if (arr.join('`').replace(/`(false|0|\s)*/g,''))...
     
    Or, simpler, if you can accept both 0 and false as truey  
    • if (arr.join('')) ... 
      Will act the same as if (arr.join('').length) ...
  • PHP:
    Count a 0 as true:
    if (strlen(implode(arr)) ) ...
Loading mentions Retweet

Comments [0]

Quick Tip: Safe extract()

PHP's extract function will turn any associative array into a bunch of variables.

If you call a page with the following URL:
http://example.url/index.php?var1=apples&var2=pears

And extract() the GET variable you will achieve:
$var1 = 'apples';
$var2 = 'pears';

The code is much shorter and more readable when not peppered with $_GET[]'s.
Great, huh?

Actually, its a headache, both from a security standpoint (anyone can pass any variable they want into your code. What will $admin=true do to you?) and from a maintenance angle (what string would like clobbered today?).

Fortunately there are some great workarounds that allow you to only extract those variables you want extracted.

  1. The Loop:
    $extract = array('var1','var2','var3');

    foreach($extract as $v) $$v = $_REQUEST[$v];
  2. Intersecting arrays:
    $extract = array('var1', 'var2', 'var3');
    extract(array_intersect_key($_REQUEST, array_flip($extract)));
  3. Lists (don't scale well):
    list($var1, $var2, $var3) =
    array($_REQUEST['var1'],$_REQUEST['var2'],$_REQUEST['var3']);
  4. Extract with flags:
    $var1 = $var2 = $var3 = '';
    extract($_REQUEST, EXTR_IF_EXISTS);
Some notes about the flags that are available for extract():
  • Using EXTR_IF_EXISTS tells PHP to only overwrite those variables that already exist.
    If you extract your REQUEST in the first line of the document, that is fine.  Once you have start declaring other variables this won't work.
  • An alternative is EXTR_SKIP, which tells PHP to ignore any variables that already exist - only to declare new variables. Only fine if your sensitive variables all exist, and the ones you need extracted do not namsakes.  Inadvisable at best.
  • The extract function returns the number of variables extracted, so you can check that number and abort if not as expected, but the security benefits are negligible.
    if(4 != extract($_REQUEST, EXTR_IF_EXISTS))die('wrong number of variables');
Loading mentions Retweet

Comments [0]

Tools Of The Trade: Browsers

Though not a service, I've received a few emails asking me to outline the choice of browsers. Since nothing affects your online experience as does the browser you use, here goes.

The well known browsers in order of preference:

  1. Firefox
     - the best all round package.
    Fast, secure, feature-complete, popular.
    Has a bazilion plug-ins, so you can customize it to to the pixel.
    Displays pages correctly.
  2. Google Chrome & Apple Safari - Good, not great
    Both are part of the Webkit project, and are very similar.
    They are known as "Tricycles with Jet Engines" as they are very fast but not very mature browsers.
    Displays pages correctly.
  3. Opera 10.10 (beta version 10.5) - Acceptable
    Not very fast, not customizable. Very pretty and comes with a nice feature set. Like it or leave it.
    Displays pages somewhat correctly - not perfectly.
  4. Internet Explorer
     - Terrible!
    Very slow, not customizable, Heavy and Insecure [in secure mode, not very useful].
    Displays pages the way it wants to - but never quite the way the designer intended.
Internet Explorer has been in the news quite a bit the past few days.
A security vulnerability that affects all versions of this browser was a prime cause of the $600 million a year pullout of Google from China, and reason for the French and German Governments to recommend that all users move off of IE, at least for the time being.

As of this writing, a fix has been proposed, but for most users it just joins the many many other exploits exploits that this browser exposes the user to.

But while security is important, and speed is nice, they are not the reason to leave IE.  The real reason is its pathetic display engine - the lack of support for standards ranging from canvas to curved corners means that you are not getting the experience you should be. 
And while many sites have workarounds ('fake' curved corners) these workarounds are slower and less powerful - and more and more developers are just not bothering.  They figure the site looks good enough, and works good enough, that they just let it through. IE users don't even know what they are missing.

Opera has also been in the news lately.  Their latest browser - an unstable beta called version 10.5, is the fastest browser by all counts, and has some serious display improvements.

Here's a chart from Betanews with their comparisons - everything's relative, but these look about right.


For those that need a super responsive browser for one or two sites [such as games], but don't plan on using it for regular browsing, consider using Opera 10.5 or Google Chrome.  Otherwise, please, please, move to Firefox for general browsing.
Loading mentions Retweet

Comments [0]

Tools Of The Trade: URL Shorteners

Short URLs are a great thing.  They let you fit a 50 character string into a tweet, let you restructure your links in a useful way, and let you track exactly how visitors are coming to your site.
They are help spammers spread their garbage without any accountability or foreshadowing.

Because of this, the number of URL shortening services has been throttled lately, but the options abound:


URL Shortening Services of note:

  1. Bit.ly & J.mp
    Currently king of the heap, Easy to use system with analytics, custom URLs and more.
    The two URLs are run by the the same company, bit.ly/abcd is the same as j.mp/abcd
  2. TinyURL
    The former champ that basically created the industry is still going strong.
  3. Tr.im
  4. Snurl
Personal URLs (Scripts to let you run your own service):
  1. Free PHP URL shortener script that kicks ass
  2. MLURL
  3. PHPShortener
    (I am a fan of Guille's, as you can see in the credits for MooRTE)
URL Expanding Services:
  1. LongURL
  2. Where's it go?
Watch:
  1. Goo.gl:  Currently available only for users of the Google toolbar
  2. Facebook.me: Currently only available within Facebook or Facebook connect
  3. Bit.ly Pro: (WIll allow you to setup URLs to your own 'trusted' domain)
Reading Material (Interesting related articles - not technical):
  1. Trickeries - why duplicate an existing service?
  2. plasmasturm.org - how it should've been done
Loading mentions Retweet

Comments [0]

About