Should I use 'border: none' or 'border: 0'?

Solution 1:

Both are valid. It's your choice.

I prefer border:0 because it's shorter; I find that easier to read. You may find none more legible. We live in a world of very capable CSS post-processors so I'd recommend you use whatever you prefer and then run it through a "compressor". There's no holy war worth fighting here but Webpack→LESS→PostCSS→PurgeCSS is a good 2020 stack.

That all said, if you're hand-writing all your production CSS, I maintain —despite the grumbling in the comments— it does not hurt to be bandwidth conscious. Using border:0 will save an infinitesimal amount of bandwidth on its own, but if you make every byte count, you will make your website faster.


The CSS2 specs are here. These are extended in CSS3 but not in any way relevant to this.

'border'
    Value:      [ <border-width> || <border-style> || <'border-top-color'> ] | inherit
    Initial:    see individual properties
    Applies to:     all elements
    Inherited:      no
    Percentages:    N/A
    Media:      visual
    Computed value:     see individual properties 

You can use any combination of width, style and colour.
Here, 0 sets the width, none the style. They have the same rendering result: nothing is shown.

Solution 2:

They are equivalent in effect, pointing to different shortcuts:

border: 0;
//short for..
border-width: 0;

And the other..

border: none;
//short for...
border-style: none;

Both work, just pick one and go with it :)

Solution 3:

(note: this answer has been updated on 2014-08-01 to make it more detailed, more accurate, and to add a live demo)

Expanding the shortand properties

According to W3C CSS2.1 specification (“Omitted values are set to their initial values”), the following properties are equivalent:

border: hidden;    border-style: hidden;
                   border-width: medium;
                   border-color: <the same as 'color' property>

border: none;      border-style: none;
                   border-width: medium;
                   border-color: <the same as 'color' property>

border: 0;         border-style: none;
                   border-width: 0;
                   border-color: <the same as 'color' property>

If these rules are the most specific ones applied to the borders of an element, then the borders won't be shown, either because of zero-width, or because of hidden/none style. So, at the first look, these three rules look equivalent. However, they behave in different ways when combined with other rules.

Borders in a table context in collapsing border model

When a table is rendered using border-collapse: collapse, then each rendered border is shared between multiple elements (inner borders are shared among as neighbor cells; outer borders are shared between cells and the table itself; but also rows, row groups, columns and column groups share borders). The specification defines some rules for border conflict resolution:

  1. Borders with the border-style of hidden take precedence over all other conflicting borders. […]

  2. Borders with a style of none have the lowest priority. […]

  3. If none of the styles are hidden and at least one of them is not none, then narrow borders are discarded in favor of wider ones. […]

  4. If border styles differ only in color, […]

So, in a table context, border: hidden (or border-style: hidden) will have the highest priority and will make the shared border hidden, no matter what.

On the other end of the priorities, border: none (or border-style: none) have the lowest priority, followed by the zero-width border (because it is the narrowest border). This means that a computed value of border-style: none and a computed value of border-width: 0 are essentially the same.

Cascading rules and inheritance

Since none and 0 affect different properties (border-style and border-width), they will behave differently when a more specific rule defines just the style or just the width. See Chris answer for an example.

Live demo!

Want to see all these cases in one single page? Open the live demo!

Solution 4:

As others have said both are valid and will do the trick. I'm not 100% convinced that they are identical though. If you have some style cascading going on then they could in theory produce different results since they are effectively overriding different values.

For example. If you set "border: none;" and then later on have two different styles that override the border width and style then one will do something and the other will not.

In the following example on both IE and firefox the first two test divs come out with no border. The second two however are different with the first div in the second block being plain and the second div in the second block having a medium width dashed border.

So though they are both valid you may need to keep an eye on your styles if they do much cascading and such like I think.

<html>
<head>
<style>
div {border: 1px solid black; margin: 1em;}
.zerotest div {border: 0;}
.nonetest div {border: none;}

div.setwidth {border-width: 3px;}
div.setstyle {border-style: dashed;}

</style>
</head>
<body>

<div class="zerotest">
<div class="setwidth">
"Border: 0" and "border-width: 3px"
</div>
<div class="setstyle">
"Border: 0" and "border-style: dashed"
</div>
</div>

<div class="nonetest">
<div class="setwidth">
"Border: none" and "border-width: 3px"
</div>
<div class="setstyle">
"Border: none" and "border-style: dashed"
</div>
</div>

</body>
</html>

Solution 5:

Using

border: none;

doesn't work in some versions of IE. IE9 is fine but in previous versions it displays the border even when the style is "none". I experienced this when using a print stylesheet where I didn't want borders on the input boxes.

border: 0;

seems to work fine in all browsers.