[css] Should I use 'border: none' or 'border: 0'?

Which of the two methods conforms to W3C standards? Do they both behave as expected across browsers?

border: none;
border: 0;

This question is related to css border

The answer is


Easiest Way to remove border with css

border: 0;

(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!


You may simply use both as per the specification kindly provided by Oli.

I always use border:0 none;.

Though there is no harm in specifying them seperately and some browsers will parse the CSS faster if you do use the legacy CSS1 property calls.

Though border:0; will normally default the border style to none, I have however noticed some browsers enforcing their default border style which can strangely overwrite border:0;.


This is the result in Firefox 78.0.2 (64-Bit):

img {
    border: none;
        border-top-color: currentcolor;
        border-top-style: none;
        border-top-width: medium;
        border-right-color: currentcolor;
        border-right-style: none;
        border-right-width: medium;
        border-bottom-color: currentcolor;
        border-bottom-style: none;
        border-bottom-width: medium;
        border-left-color: currentcolor;
        border-left-style: none;
        border-left-width: medium;
}

img {
    border: 0;
        border-top-color: currentcolor;
        border-top-style: none;
        border-top-width: 0px;
        border-right-color: currentcolor;
        border-right-style: none;
        border-right-width: 0px;
        border-bottom-color: currentcolor;
        border-bottom-style: none;
        border-bottom-width: 0px;
        border-left-color: currentcolor;
        border-left-style: none;
        border-left-width: 0px;
        border-image-outset: 0;
        border-image-repeat: stretch;
        border-image-slice: 100%;
        border-image-source: none;
        border-image-width: 1;
}

Date: 20200720


While results will most likely be the same (no border), the 0 and none are technically addressing different things.

0 addresses border width and none addresses border style. Obviously a border of 0 width is nonexistent so will therefore have no style.

However, if later on in your stylesheet you intend to override this, you would naturally specifically address one or the other. If I now wanted a 3px border, that would be directly overriding border: 0 in regards to width. If I now wanted a dotted border, that would be directly overriding border: none in regards to styling.


In my point,

border:none is working but not valid w3c standard

so better we can use border:0;


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>

I use:

border: 0;

From 8.5.4 in CSS 2.1:

'border'

Value: [ <border-width> || <border-style> || <'border-top-color'> ] | inherit

So either of your methods look fine.


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.


Well, to precisely see the difference between border: 0 and border: none we can make some experiments.

Experiment:

Lets create three divs, first one whose border can only be disabled by setting its width to zero, second one that can only be disabled by setting its style to none, and a third with a border that can only be "disabled" by setting its color to transparent. Then lets try the effect of:

  • border: 0;
  • border: none;
  • border: transparent

    border-style: solid!important; border-color: red!important; border-width: 2px!important; border-color: red!important; border-width: 2px!important; border-style: solid!important;

_x000D_
_x000D_
var container = document.querySelector('#container');_x000D_
var btnSetZero = document.querySelector('#setZero');_x000D_
var btnSetNone = document.querySelector('#setNone');_x000D_
var btnSetTransparent = document.querySelector('#setTransparent');_x000D_
var btnReset = document.querySelector('#reset');_x000D_
btnSetZero.addEventListener('click', () => {_x000D_
 container.className = "border-zero";_x000D_
});_x000D_
_x000D_
btnSetNone.addEventListener('click', () => {_x000D_
 container.className = "border-none";_x000D_
});_x000D_
_x000D_
btnSetTransparent.addEventListener('click', () => {_x000D_
 container.className = "border-transparent";_x000D_
});_x000D_
_x000D_
btnReset.addEventListener('click', () => {_x000D_
 container.className = "";_x000D_
});
_x000D_
div div {_x000D_
  border: 2px solid red;_x000D_
  margin: 2px;_x000D_
  font-family: monospace;_x000D_
  white-space: nowrap;_x000D_
  width: 250px;_x000D_
}_x000D_
_x000D_
div.border-zero div {_x000D_
  border: 0;_x000D_
}_x000D_
div.border-none div {_x000D_
  border: none;_x000D_
}_x000D_
div.border-transparent div {_x000D_
  border: transparent;_x000D_
}
_x000D_
<div id="container">_x000D_
  <div style="border-style: solid!important; border-color: red!important;">_x000D_
    border-style: solid!important;<br>_x000D_
    border-color: red!important;_x000D_
  </div>_x000D_
  <div style="border-width: 2px!important; border-color: red!important;">_x000D_
    border-width: 2px!important;<br>_x000D_
    border-color: red!important;_x000D_
  </div>_x000D_
  <div style="border-width: 2px!important; border-style: solid!important;">_x000D_
    border-width: 2px!important;<br>_x000D_
    border-style: solid!important;_x000D_
  </div>_x000D_
</div>_x000D_
_x000D_
<button id="setZero">border: 0;</button>_x000D_
<button id="setNone">border: none;</button>_x000D_
<button id="setTransparent">border: transparent;</button>_x000D_
<button id="reset">reset</button>
_x000D_
_x000D_
_x000D_

My results were the same in both firefox and chrome:

border: 0; Seems to set border-width to 0 and border-style to none, but not change border-color;

border: none; Seems to only change border-style (to none);

border: transparent; Seems to change border-color to transparent and border-style to none;


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 :)