Any time you use a shorthand property in CSS, you set all the values for all the properties it deals with. It’s not a bug, it’s just how CSS works. I’ve seen it confuse people plenty of times. Let’s shine a light on the issue to hopefully make it more understood.
Here’s an example:
.module {
background-repeat: no-repeat;
background: url(lion.jpg);
/* Oops! This will repeat. */
}
The shorthand CSS background property overrides all the sup properties. The default value for background-repeat is repeat, so by not declaring it in the shorthand, it gets set to that default value.
It works that way for every single one of the background sub properties:
.module {
/* This will get set to `repeat` */
background-repeat: no-repeat;
/* This will get set to `0 0` */
background-position: top right;
/* This will get set to `auto auto` */
background-size: 100px;
/* This will get set to `scroll` */
background-attachment: fixed;
/* This will get set to `border-box` */
background-origin: content-box;
/* This will get set to `border-box` */
background-clip: padding-box;
/* This will get set to `transparent` */
background-color: red;
/* This will get overridden */
background-image: url(cool.png);
/* OVERRIDE */
background: url(lion.jpg);
}
This is the case with box model (and related) stuff, like:
.module {
margin-right: 20px;
margin: 10px;
/* margin-right will be 10px now */
padding-top: 30px;
padding: 10px;
/* padding-top will be 10px now */
border-left: 1px;
border: 0;
/* border-left will be removed */
}
Fonts is another situation where you can accidentally reset yourself:
p {
/* Will get reset to what is set in shorthand (required) */
font-family: Sans-Serif;
/* Will get reset to what is set in shorthand (required) */
font-size: 24px;
/* Will get reset to `normal` */
line-height: 2;
/* Will get reset to `normal` */
font-style: italic;
/* will get reset to `normal` */
font-weight: bold;
/* will get reset to `normal` */
font-variant: small-caps;
/* OVERRIDE */
font: 16px Serif;
}
Note that the shorthand requires at least the font-family and font-size to work.
Lists are yet another:
ul {
/* Will get reset to what is set in shorthand */
list-style-type: square;
/* Will get reset to `outside` */
list-style-position: inside;
/* Will get reset to `none` */
list-style-image: url(cooldot.png);
/* OVERRIDE */
list-style: disc;
}
The flex property as part of flexbox layout is also shorthand:
.flex > span {
/* Will be reset to `auto` (or `main-size` if supported) */
flex-basis: 150px;
/* Will be reset to `1` */
flex-grow: 0;
/* Will be reset to `1` */
flex-shrink: 0;
/* OVERRIDE */
flex: auto;
}
This is an unusual one though, as rather than the shorthand resetting things you might not want reset, it resets them in ways you probably do want reset and might not even know it. Fantasai:
We (the Flexbox spec editors) strongly recommend not using the longhands of ‘flex’ unless you really, really want to cascade in flex settings from some other style rule, so I’d suggest somehow discouraging the use of ‘flex-grow/shrink/basis’ here (or, preferably, leaving it out/in an advanced section). The shorthand resets things in appropriate ways, and will therefore result in fewer cascading errors. Please use the shorthand!
Here’s a Pen with some of this stuff in real code.
I think you should mention in this case, that there is also a “inherit” property, so that you can write e.g.
And it will rewrite only URL and position, but keep the color and repeat
Wellllll.
inherit
has special meaning. It will still override other properties set within the same selector. For instance:What background-color will the div have? Blue, not red.
I always tell my clients and interns to place “reset” before anything. Then add your styles after. ;)
I tell them the bottom line: Anything in the next line of css is the latest “override” like your examples above. :)
Also if working with IE7 writing shorthand margins won’t reset, both margins are added together.
E.g.
A serious question,is IE7 something to think about at all in 2015?
Not for everyone, it all depends on the website. That’s what analytics is for. I still get a lot unfortunately.
No offense but I recommended clients not to use IE7 since their security system is out of date… whereas XP is no longer supported. Just sayin’.
This is exactly why I try to discourage people from using shorthand properties unless you’re intentionally setting all the properties in the shorthand (and in some cases, there are more things implied than you normally worry about). The discipline of always setting every property in the shorthand (using
inherit
if you wish) also avoids surprising behaviour when the default is not quite what you expect.I think you don’t really save that much space by using shorthand since compression will smear a lot of the extra size out.
Its also about documentation. Using
background-color
, even if you know that no other background properties are set, makes it clear what you intend to do.Yup! This is something I used to run into too. I tend to use the shorthand for the “base styles” of an element, and the more specific attributes for overriding styles or modifier classes. Usually works pretty well for me
Just noticed the note from the Flexbox spec editors. Yup, that’s almost exactly how I usually handle all shorthands. I like to use ’em unless it’s specifically overwriting something else.
@David: I think you are mistaken (not that its that important these days :)) but IE7 has no problem with resetting horizontal margins and does not add them together (unless there’s a special case that I don’t know about).
There is a bug in ie6/7 with margin:auto where the default vertical margins of an elements (such as a p element) are not reset to zero.
There is also the famous double margin bug on floats in ie6 (cured with display:inline) but not evident in IE7.
I was kinda hoping to see
cool.png
andlion.png
. They sound like rad images.ho. lee. crap.
the amount of screwing around this explains…
love CSS. hate CSS. love CSS. hate CSS
Wow, so glad you mentioned this! I had no idea! I bet this is the root of many of my problems. I love this site!
I’m a bit of a shorthand addict but lately been trying to keep shorthand away from my code mostly for some of the reasons above. Nice little post, well worth a read for any newbie (and a few vets) as a little eye opener.
It’s only a mistake if you place the short hand property after the other longhand properties:
Totally agree, Without putting any thoughts to resets, I had always had shorthand properties come before long-hand
The issue is almost never that you are putting shorthand and specific properties in different selectors and they are applied in ways you don’t expect.
It would be an interesting (if difficult) exercise to troll websites and see how often things like selector stuffing (
html body div > .allredborders
) and!important
are used to overcome unexpected shortcut behaviour.My nitpicky two cents:
The box model stuff is different from the other ones. While the other ones reset the missing values to their initial (or default) state, the border, margin, and padding properties don’t do that. They simply inherit assumed values from the existing one(s). So I wouldn’t really classify those as the same thing, because in that case it’s always intentional to reset the missing values.
Also, font shorthand is really the only one that trips people up because typographic properties get passed down into child elements. So, for example, if you set a font-size on the “body” element, then set font shorthand on paragraphs, you suddenly see the font size disappear, because you expect it to be passed down. That’s why I think font shorthand should only be used on the html element or the body.
With something like list shorthand (or many of the others you mentioned), you don’t expect their values to be passed down like typographic ones are (and they aren’t) so the resetting of values is rarely, if ever, a problem in those cases.
Oops… One correction: I said “set font-size” on the body, but that won’t apply because font-size is required in font shorthand. Any of the others (like font-variant) would illustrate my point more accurately.
A slightly different perspective from a specific scenario: I work on a large site (~400mil users) and we are hyper-focused on performance and page-weight. The site has lots of background colors, and we declare the property with “background” instead of “background-color” since it is 6 characters shorter. We have very few background images, so we don’t have to worry about accidental resets, and can just get more specific if necessary.
The best practice i use(and i am totally cool with) is to use shorthand then over ride it with longhand (:D)
this whay i am sure i won’t accidentally reset my prev codes
Thanks for the blogs! It is easy to forget sometimes the first C of CSS, “Cascading” and also the invisible third S of CSS “Specificity”.
Keep up the good work!
In this exemple
border-radius
is not resetborder-radius
is not in the border shorthand syntax. That is why it is not get reseted.@Homan
The
border-image
properties also aren’t part of theborder
shorthand, but they still get reset.In fact, the specs specifically recommend using the border shorthand in order to clear any other border-related properties:
So why is
border-radius
not included? Maybe because, despite it’s name, it doesn’t only affect the border, but also the padding region and any backgrounds. Or maybe there was no logical argument either way, that’s just the way it happened. Either way, it’s an extra complication worth remembering.Google Chrome helped me understand about css resets with the “Developer Tools” as you can see here