Leaving Certain Values Unchanged When Using CSS Shorthand Properties

Leaving certain values unchanged when using CSS shorthand properties

This isn't currently possible, unfortunately. You'll have to stick with assigning margin-top and margin-bottom respectively.

A shorthand property always changes the values of all its component (longhand) properties. Namely, any values omitted in a shorthand property will default to initial for their respective properties, unless resolved by cascading or by some other rules depending on the shorthand property. For example, the following results in auto margins on all sides except the bottom due to the margin-bottom longhand that appears after the shorthand:

#header {
/*
* Note: this is short for margin: auto auto auto auto;
* none of the longhands are set to initial! Different shorthands
* have different rules, but a shorthand always changes the values
* of all its longhands.
*/
margin: auto;
margin-bottom: 1em;
}

If there were separate shorthands for horizontal margins and vertical margins, you would be able to do this without having to worry about keeping specific longhand values, but no such shorthands exist at the moment.

As I mentioned in my comment, margin: 1em inherit is invalid as the CSS-wide keywords inherit (along with initial and others introduced in later standards) may only appear by themselves in property declarations, and this includes shorthand declarations. Even if margin: 1em inherit did work, the element would inherit horizontal margins from its parent element, and not from its own cascade (since that's not what inheritance means). It is not possible to retrieve a cascaded or specified value for a property on a given element, and being able to do this would almost certainly be error-prone due to the fact that the bottommost declaration from the most specific selector that contains the resolved value could be anywhere.

Don't understand the statement individual inherited values are not possible with any shorthand property

As the note says, the following is invalid, even though intuitively it looks like it should set two of the corner radii to 0 and two of them to inherit:

border-radius:0 0 inherit inherit

This is because different shorthands have different grammars making it impossible for multiple inherit values to be mixed with other values. You wouldn't be able to determine which of the component properties should inherit, and you wouldn't be able to determine how to parse the remaining values that aren't inherit.

For example, while the above declaration looks easy enough, consider a background declaration:

background: inherit inherit #fff

There are two inherit keywords here, but the background shorthand contains a multitude of component properties with a complex grammar. It's impossible to determine which two of the longhands other than background-color should inherit. You have to tell the browser. Which means writing longhand declarations.

So, inherit is defined as a CSS-wide keyword that may only appear by itself in any property declaration, including shorthands. This eliminates any possible ambiguity regardless of whether the property is a longhand property accepting a single value, a longhand property accepting multiple values (such as border-top-left-radius or background-size), or a shorthand property.

See also: Leaving certain values unchanged when using CSS shorthand properties

Set margin-left and margin-right and keep vertical margin

No, there is no way to keep the vertical margins when using the short-hand property. That is because:

  • In CSS, when two or more selectors are applicable for an element, the values that are provided in the latest selector (or more specific selector) wins for common properties. Here, margin is given both in .inner, the other class selector and so the one within .inner will get overwritten.
  • inherit (along with a length value) doesn't seem to be valid for the shorthand margin property whereas it is valid for the longhand margin-* properties and when inherit alone is specified in the shorthand. Moreover, margin: 10px is set in the .inner selector which is actually the same element (and not the parent), so inherit won't work.
  • auto is a valid value for margin but it does not keep the margin specified in a previous selector. It tells the UA to calculate and assign a suitable value. For your case, it may set the margin-top and margin-bottom to 10px but it may not also (depending on other factors).
  • When any length value (pixel or percentage) is given for the margin property, the UA decides on how to interpret the given value based on the no. of values provided. If one value is provided, that gets set to all sides, 2 values means first is vertical while second is horizontal margin and so on.

So, in short, overriding the margin-left and margin-right specifically (like in .horizontal-margin-working) is the only way you can get to keep the vertical margin.

Set margin-left and margin-right and keep vertical margin

No, there is no way to keep the vertical margins when using the short-hand property. That is because:

  • In CSS, when two or more selectors are applicable for an element, the values that are provided in the latest selector (or more specific selector) wins for common properties. Here, margin is given both in .inner, the other class selector and so the one within .inner will get overwritten.
  • inherit (along with a length value) doesn't seem to be valid for the shorthand margin property whereas it is valid for the longhand margin-* properties and when inherit alone is specified in the shorthand. Moreover, margin: 10px is set in the .inner selector which is actually the same element (and not the parent), so inherit won't work.
  • auto is a valid value for margin but it does not keep the margin specified in a previous selector. It tells the UA to calculate and assign a suitable value. For your case, it may set the margin-top and margin-bottom to 10px but it may not also (depending on other factors).
  • When any length value (pixel or percentage) is given for the margin property, the UA decides on how to interpret the given value based on the no. of values provided. If one value is provided, that gets set to all sides, 2 values means first is vertical while second is horizontal margin and so on.

So, in short, overriding the margin-left and margin-right specifically (like in .horizontal-margin-working) is the only way you can get to keep the vertical margin.

Browser loads both shorthand CSS with px, and specific css with rem on same property?

After a lot of wasted time and confusion... It actually does render correctly in Google Chrome. feeling silly now... I overlooked the drop-down arrow to the sub-properties in the Chrome Tools. Image displays what I overlooked. Example shows multiple examples of shorthand properties and specific properties, more importantly it shows the font property working, it wasn't crossed out but it was still being overridden. Not sure why it doesn't comply with the strike through like everything else, probably due to the font-weight, variant, style properties remaining unchanged. But it works.

Doh!

Can I set the CSS border width for three borders with shorthand?

If you use shorthand, you must set all of the widths, so you won't be able to use the width applied from the .message class.

.test { border-width: 1px 0 0 0 } /* top right bottom left */

Canvas is stretched when using CSS but normal with width / height properties

It seems that the width and height attributes determine the width or height of the canvas’s coordinate system, whereas the CSS properties just determine the size of the box in which it will be shown.

This is explained in the HTML specification:

The canvas element has two attributes to control the size of the element’s bitmap: width and height. These attributes, when specified, must have values that are valid non-negative integers. The rules for parsing non-negative integers must be used to obtain their numeric values. If an attribute is missing, or if parsing its value returns an error, then the default value must be used instead. The width attribute defaults to 300, and the height attribute defaults to 150.

How can I nullify css property?

You have to reset each individual property back to its default value. It's not great, but it's the only way, given the information you've given us.

In your example, you would do:

.c1 {
height: auto;
}

You should search for each property here:

https://developer.mozilla.org/en-US/docs/Web/CSS/Reference

For example, height:

Initial value : auto

Another example, max-height:

Initial value : none


In 2017, there is now another way, the unset keyword:

.c1 {
height: unset;
}

Some documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/unset

The unset CSS keyword is the combination of the initial and inherit
keywords. Like these two other CSS-wide keywords, it can be applied to
any CSS property, including the CSS shorthand all. This keyword resets
the property to its inherited value if it inherits from its parent or
to its initial value if not. In other words, it behaves like the
inherit keyword in the first case and like the initial keyword in the
second case.

Browser support is good: http://caniuse.com/css-unset-value

How to set only vertical padding?

If I understand what you want : you're looking for a way to only assign vertical padding with padding property (and keep original horizontal padding if it's set).

So you already have the answer :

.myElement { padding-top: 20px; padding-bottom: 20px;  }

You can't do that only with padding property, or you'll need to set horizontal value.

Or, you can consider using CSS preprocessors (such as Sass or Less), it will surely helps you to achieve this.



Related Topics



Leave a reply



Submit