Which of the two methods conforms to W3C standards? Do they both behave as expected across browsers?
border: none;
border: 0;
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.
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 :)
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>
(note: this answer has been updated on 2014-08-01 to make it more detailed, more accurate, and to add a live demo)
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.
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:
Borders with the
border-style
ofhidden
take precedence over all other conflicting borders. […]Borders with a style of
none
have the lowest priority. […]If none of the styles are
hidden
and at least one of them is notnone
, then narrow borders are discarded in favor of wider ones. […]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.
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.
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;
.
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.
Well, to precisely see the difference between border: 0
and border: none
we can make some experiments.
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;
var container = document.querySelector('#container');
var btnSetZero = document.querySelector('#setZero');
var btnSetNone = document.querySelector('#setNone');
var btnSetTransparent = document.querySelector('#setTransparent');
var btnReset = document.querySelector('#reset');
btnSetZero.addEventListener('click', () => {
container.className = "border-zero";
});
btnSetNone.addEventListener('click', () => {
container.className = "border-none";
});
btnSetTransparent.addEventListener('click', () => {
container.className = "border-transparent";
});
btnReset.addEventListener('click', () => {
container.className = "";
});
div div {
border: 2px solid red;
margin: 2px;
font-family: monospace;
white-space: nowrap;
width: 250px;
}
div.border-zero div {
border: 0;
}
div.border-none div {
border: none;
}
div.border-transparent div {
border: transparent;
}
<div id="container">
<div style="border-style: solid!important; border-color: red!important;">
border-style: solid!important;<br>
border-color: red!important;
</div>
<div style="border-width: 2px!important; border-color: red!important;">
border-width: 2px!important;<br>
border-color: red!important;
</div>
<div style="border-width: 2px!important; border-style: solid!important;">
border-width: 2px!important;<br>
border-style: solid!important;
</div>
</div>
<button id="setZero">border: 0;</button>
<button id="setNone">border: none;</button>
<button id="setTransparent">border: transparent;</button>
<button id="reset">reset</button>
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
;
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.
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