14

I'd like to be able to set the margin-bottom of an element to its default value.

Consider the following example in which there are h1 elements which have their respective margin-bottom style properties set to 0:

h1 {
  border: 1px solid red;
  margin-bottom: 0;
}

p {
  margin: 0;
}
<h1>First Heading</h1>
<p>Paragraph</p>

<h1 id="normal-margin">Second Heading</h1>
<p>Paragraph</p>

How can I reset the margin-bottom value of #normal-margin to its initial, default value? Obviously using initial won't work, as the initial value of margin-bottom is 0.

I realise in this trivial example I can simply add :not(#normal-margin) to the style definition of h1 to fix the issue. I would however like a solution which would “undo” the margin and reset it to its initial value.

I’m thinking that I’m going to have to hard-code values into the CSS, which to me seems a bit cheap. Is that the only solution to this problem?

Jack Greenhill
  • 10,240
  • 12
  • 38
  • 70
  • 1
    Not sure you can and, in any case, this is likely to be different for each browser. - http://stackoverflow.com/questions/819161/what-is-the-default-padding-and-or-margin-for-a-p-element-reset-css – Paulie_D Sep 23 '15 at 10:30
  • @Paulie_D That's precisely why I asked this question in the first place, I'd like to maintain consistency between initial margin values in different browsers if at all possible. – Jack Greenhill Sep 23 '15 at 10:33
  • 2
    I'm not sure I get what you are asking then...are not using a CSS reset or Normalize? – Paulie_D Sep 23 '15 at 10:38
  • yes why not using Normalize and adding some classes where needed? You're just making your life more difficult in the long run styling html tags in your CSS (see OO CSS and methodologies like BEM to understand more about this) – Luca Sep 23 '15 at 10:41
  • I should have clarified – in my actual application of this problem, I have a style definition for some `h1` elements which, amongst other things, sets the `margin-bottom` of the respective element to 0. I’m looking for a way to undo that (i.e. set it to its initial value, as if I never set `margin-bottom` to 0). I'm also not using any CSS resets or the like, but I may consider it now. – Jack Greenhill Sep 23 '15 at 10:49

2 Answers2

12

I think the property you're looking for is unset.

unset resets the property to its inherited value if it inherits from its parent or to its initial value if not. Via - Mozilla Docs

jsFiddle: http://jsfiddle.net/AndrewL32/65sf2f66/58/

div {
  border: medium solid green;
  margin: 10px 0px;
}
h2 {
  margin-bottom:10px;
}

/* but make those in the sidebar use the value of the 'color' property (initial value) */
h2.specialHeader {
  margin-bottom: unset;
}
<div><h2>Normal Header</h2></div>
<div><h2 class="specialHeader">Special Header</h2></div>

Browser Support:

Chrome: > v.41

FireFox: > v.27

Edge: > v.13

Opera: > v.28

Safari: > v9.1

IE: Not Supported

See caniuse for all (un-)supported browsers

AndrewL64
  • 15,794
  • 8
  • 47
  • 79
  • I saw this on the Mozilla developer page and attempted to use it, but with no luck as I was using Safari. However it seems to be the only solution to achieve what I'm after right now (without using CSS resets and the like). – Jack Greenhill Sep 23 '15 at 10:50
  • Hmm, if you have one h2 tag with no rule and another with your special "unset class" these should look the same, right? .. wrong,or at least not in my test fiddle http://jsfiddle.net/65sf2f66/61/ – Asons Sep 23 '15 at 10:50
  • @AndrewLyndem I removed your css and still it does not work: http://jsfiddle.net/65sf2f66/62/ – Asons Sep 23 '15 at 11:02
  • If only IE was supported. – Paul Redmond Sep 23 '15 at 11:03
  • @LGSon Yes, I tried just now and noticed the same thing. The margin on the header without unset uses some user agent properties (webkit in chrome) so that is based on the browser. Unset removes even those browser default properties which is even better as it's purpose is to completely remove element's properties. – AndrewL64 Sep 23 '15 at 11:05
  • Wasn't it suppose to set it to the the value as when the element never were set in the first place?? – Asons Sep 23 '15 at 11:06
  • @LGSon https://developer.mozilla.org/en-US/docs/Web/CSS/unset ("or to its initial value if not.") – AndrewL64 Sep 23 '15 at 11:09
  • Since `margin-*` are not inherited, `unset` will behave exactly like `initial` which, as explained in the question, doesn't work. – Oriol Sep 24 '15 at 16:02
1

Currently it's not possible. In some future, use the revert keyword

As explained in 7.3. Explicit Defaulting, there are 4 diferent defaulting behaviors:

  • initial sets a property to its initial value.

    In the case of margin-*, that's 0.

  • inherit sets a property to the value of the parent element (or to the initial value for the root element).

  • unset behaves as inherit for inherited properties, and as initial otherwise.

    margin-* are not inherited, so it would produce 0.

  • The behavior of revert depends on the origin of the declaration

    • For user-agent origin, it behaves as unset
    • For user origin, it rolls back the cascade to the user-agent level, so that the specified value is calculated as if no author-level or user-level rules were specified for the property.
    • For author origin, it rolls back the cascade to the user level, so that the specified value is calculated as if no author-level rules were specified for the property.

So the behavior you want is revert's one, i.e.

  • The user-agent adds some margin to h1 elements
  • One of your (author) declarations removes that margin
  • revert rolls back that to the margin defined by the user-agent

Note revert is a recent addition to the CSS Cascading and Inheritance Level 4 spec, which is still only a draft. Therefore, browsers don't support it yet.

Oriol
  • 274,082
  • 63
  • 437
  • 513