Bug 1542178 - Derive ToResolvedValue. r=heycam
authorEmilio Cobos Álvarez <emilio@crisal.io>
Wed, 10 Apr 2019 12:10:26 +0000
changeset 468798 79752758fc82bda5a89bd3a3860fc20aea10d72f
parent 468797 b8e84c48c6720e03b24170671b502ec306939bf3
child 468799 11dcdb94e2faab73048c25a0802105d8e97d0f14
push id112755
push userdvarga@mozilla.com
push dateWed, 10 Apr 2019 22:06:41 +0000
treeherdermozilla-inbound@606f85641d0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1542178
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1542178 - Derive ToResolvedValue. r=heycam Differential Revision: https://phabricator.services.mozilla.com/D26783
servo/components/style/macros.rs
servo/components/style/properties/helpers.mako.rs
servo/components/style/values/computed/align.rs
servo/components/style/values/computed/angle.rs
servo/components/style/values/computed/box.rs
servo/components/style/values/computed/font.rs
servo/components/style/values/computed/image.rs
servo/components/style/values/computed/length.rs
servo/components/style/values/computed/mod.rs
servo/components/style/values/computed/percentage.rs
servo/components/style/values/computed/text.rs
servo/components/style/values/computed/time.rs
servo/components/style/values/generics/background.rs
servo/components/style/values/generics/basic_shape.rs
servo/components/style/values/generics/border.rs
servo/components/style/values/generics/box.rs
servo/components/style/values/generics/color.rs
servo/components/style/values/generics/column.rs
servo/components/style/values/generics/counters.rs
servo/components/style/values/generics/easing.rs
servo/components/style/values/generics/effects.rs
servo/components/style/values/generics/flex.rs
servo/components/style/values/generics/font.rs
servo/components/style/values/generics/gecko.rs
servo/components/style/values/generics/grid.rs
servo/components/style/values/generics/image.rs
servo/components/style/values/generics/length.rs
servo/components/style/values/generics/mod.rs
servo/components/style/values/generics/position.rs
servo/components/style/values/generics/rect.rs
servo/components/style/values/generics/size.rs
servo/components/style/values/generics/svg.rs
servo/components/style/values/generics/text.rs
servo/components/style/values/generics/transform.rs
servo/components/style/values/generics/ui.rs
servo/components/style/values/generics/url.rs
servo/components/style/values/mod.rs
servo/components/style/values/specified/align.rs
servo/components/style/values/specified/background.rs
servo/components/style/values/specified/border.rs
servo/components/style/values/specified/box.rs
servo/components/style/values/specified/font.rs
servo/components/style/values/specified/list.rs
servo/components/style/values/specified/mod.rs
servo/components/style/values/specified/motion.rs
servo/components/style/values/specified/outline.rs
servo/components/style/values/specified/position.rs
servo/components/style/values/specified/svg.rs
servo/components/style/values/specified/svg_path.rs
servo/components/style/values/specified/table.rs
servo/components/style/values/specified/text.rs
servo/components/style/values/specified/ui.rs
servo/components/style_derive/lib.rs
--- a/servo/components/style/macros.rs
+++ b/servo/components/style/macros.rs
@@ -75,16 +75,17 @@ macro_rules! define_keyword_type {
             Copy,
             MallocSizeOf,
             PartialEq,
             SpecifiedValueInfo,
             ToAnimatedValue,
             ToAnimatedZero,
             ToComputedValue,
             ToCss,
+            ToResolvedValue,
             ToShmem,
         )]
         pub struct $name;
 
         impl fmt::Debug for $name {
             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 f.write_str($css)
             }
--- a/servo/components/style/properties/helpers.mako.rs
+++ b/servo/components/style/properties/helpers.mako.rs
@@ -123,18 +123,25 @@
             /// The generic type defining the value for this property.
             ///
             /// Making this type generic allows the compiler to figure out the
             /// animated value for us, instead of having to implement it
             /// manually for every type we care about.
             % if separator == "Comma":
             #[css(comma)]
             % endif
-            #[derive(Clone, Debug, MallocSizeOf, PartialEq, ToAnimatedValue,
-                     ToCss)]
+            #[derive(
+                Clone,
+                Debug,
+                MallocSizeOf,
+                PartialEq,
+                ToAnimatedValue,
+                ToResolvedValue,
+                ToCss,
+            )]
             pub struct List<T>(
                 % if not allow_empty:
                 #[css(iterable)]
                 % else:
                 #[css(if_empty = "none", iterable)]
                 % endif
                 % if allow_empty and allow_empty != "NotInitial":
                 pub Vec<T>,
@@ -420,18 +427,30 @@
         ]}
         keyword = keyword=Keyword(name, values, **keyword_kwargs)
     %>
     <%call expr="longhand(name, keyword=Keyword(name, values, **keyword_kwargs), **kwargs)">
         use crate::properties::longhands::system_font::SystemFont;
 
         pub mod computed_value {
             #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
-            #[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse,
-                     PartialEq, SpecifiedValueInfo, ToCss, ToShmem)]
+            #[derive(
+                Clone,
+                Copy,
+                Debug,
+                Eq,
+                Hash,
+                MallocSizeOf,
+                Parse,
+                PartialEq,
+                SpecifiedValueInfo,
+                ToCss,
+                ToResolvedValue,
+                ToShmem,
+            )]
             pub enum T {
             % for value in keyword.values_for(product):
                 ${to_camel_case(value)},
             % endfor
             }
 
             ${gecko_keyword_conversion(keyword, keyword.values_for(product), type="T", cast_to="i32")}
         }
@@ -583,27 +602,37 @@
             #[parse(aliases = "${','.join(aliases)}")]
             % endif
             % endif
             ${to_camel_case(variant)},
             % endfor
         </%def>
         % if extra_specified:
             #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
-            #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq,
-                     SpecifiedValueInfo, ToCss, ToShmem)]
+            #[derive(
+                Clone,
+                Copy,
+                Debug,
+                Eq,
+                MallocSizeOf,
+                Parse,
+                PartialEq,
+                SpecifiedValueInfo,
+                ToCss,
+                ToShmem,
+            )]
             pub enum SpecifiedValue {
                 ${variants(keyword.values_for(product) + extra_specified.split(), bool(extra_specified))}
             }
         % else:
             pub use self::computed_value::T as SpecifiedValue;
         % endif
         pub mod computed_value {
             #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
-            #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToCss)]
+            #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToCss, ToResolvedValue)]
             % if not extra_specified:
             #[derive(Parse, SpecifiedValueInfo, ToComputedValue, ToShmem)]
             % endif
             pub enum T {
                 ${variants(data.longhands_by_name[name].keyword.values_for(product), not extra_specified)}
             }
         }
         #[inline]
--- a/servo/components/style/values/computed/align.rs
+++ b/servo/components/style/values/computed/align.rs
@@ -28,17 +28,17 @@ pub use super::specified::{AlignSelf, Ju
 /// the special case in `StyleAdjuster` instead, only when the result of the
 /// computation would vary.
 ///
 /// Note that we also need to special-case this property in matching.rs, in
 /// order to properly handle changes to the legacy keyword... This all kinda
 /// sucks :(.
 ///
 /// See the discussion in https://bugzil.la/1384542.
-#[derive(Clone, Copy, Debug, Eq, PartialEq, ToCss)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq, ToCss, ToResolvedValue)]
 pub struct JustifyItems {
     /// The specified value for the property. Can contain the bare `legacy`
     /// keyword.
     #[css(skip)]
     pub specified: specified::JustifyItems,
     /// The computed value for the property. Cannot contain the bare `legacy`
     /// keyword, but note that it could contain it in combination with other
     /// keywords like `left`, `right` or `center`.
--- a/servo/components/style/values/computed/angle.rs
+++ b/servo/components/style/values/computed/angle.rs
@@ -9,17 +9,17 @@ use crate::values::CSSFloat;
 use crate::Zero;
 use std::f64::consts::PI;
 use std::fmt::{self, Write};
 use std::{f32, f64};
 use style_traits::{CssWriter, ToCss};
 
 /// A computed angle in degrees.
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
-#[derive(Add, Animate, Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, ToAnimatedZero)]
+#[derive(Add, Animate, Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, ToAnimatedZero, ToResolvedValue)]
 pub struct Angle(CSSFloat);
 
 impl ToCss for Angle {
     fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
     where
         W: Write,
     {
         self.degrees().to_css(dest)?;
--- a/servo/components/style/values/computed/box.rs
+++ b/servo/components/style/values/computed/box.rs
@@ -44,16 +44,17 @@ pub type Perspective = GenericPerspectiv
     Eq,
     FromPrimitive,
     Hash,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToCss,
+    ToResolvedValue,
 )]
 #[repr(u8)]
 /// A computed value for the `float` property.
 pub enum Float {
     Left,
     Right,
     None,
 }
@@ -113,16 +114,17 @@ impl ToComputedValue for SpecifiedFloat 
     Eq,
     FromPrimitive,
     Hash,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToCss,
+    ToResolvedValue,
 )]
 /// A computed value for the `clear` property.
 pub enum Clear {
     None,
     Left,
     Right,
     Both,
 }
@@ -173,17 +175,17 @@ impl ToComputedValue for SpecifiedClear 
             Clear::Both => SpecifiedClear::Both,
         }
     }
 }
 
 /// A computed value for the `resize` property.
 #[allow(missing_docs)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
-#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, ToCss)]
+#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, ToCss, ToResolvedValue)]
 #[repr(u8)]
 pub enum Resize {
     None,
     Both,
     Horizontal,
     Vertical,
 }
 
--- a/servo/components/style/values/computed/font.rs
+++ b/servo/components/style/values/computed/font.rs
@@ -35,17 +35,17 @@ pub use crate::values::computed::Length 
 pub use crate::values::specified::font::{FontSynthesis, MozScriptSizeMultiplier};
 pub use crate::values::specified::font::{XLang, XTextZoom};
 
 /// A value for the font-weight property per:
 ///
 /// https://drafts.csswg.org/css-fonts-4/#propdef-font-weight
 ///
 /// This is effectively just a `Number`.
-#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
+#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, ToCss, ToResolvedValue)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 pub struct FontWeight(pub Number);
 
 impl Hash for FontWeight {
     fn hash<H: Hasher>(&self, hasher: &mut H) {
         hasher.write_u64((self.0 * 10000.).trunc() as u64);
     }
 }
@@ -69,16 +69,17 @@ impl ToAnimatedValue for FontWeight {
     Clone,
     ComputeSquaredDistance,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     ToAnimatedZero,
     ToCss,
+    ToResolvedValue,
 )]
 /// The computed value of font-size
 pub struct FontSize {
     /// The size.
     pub size: NonNegativeLength,
     /// If derived from a keyword, the keyword and additional transformations applied to it
     #[css(skip)]
     pub keyword_info: Option<KeywordInfo>,
@@ -169,17 +170,17 @@ impl ToAnimatedValue for FontSize {
     fn from_animated_value(animated: Self::AnimatedValue) -> Self {
         FontSize {
             size: animated.clamp(),
             keyword_info: None,
         }
     }
 }
 
-#[derive(Clone, Debug, Eq, PartialEq)]
+#[derive(Clone, Debug, Eq, PartialEq, ToResolvedValue)]
 #[cfg_attr(feature = "servo", derive(Hash, MallocSizeOf))]
 /// Specifies a prioritized list of font family names or generic family names.
 pub struct FontFamily {
     /// The actual list of family names.
     pub families: FontFamilyList,
     /// Whether this font-family came from a specified system-font.
     pub is_system_font: bool,
 }
@@ -216,17 +217,17 @@ impl ToCss for FontFamily {
         for family in iter {
             dest.write_str(", ")?;
             family.to_css(dest)?;
         }
         Ok(())
     }
 }
 
-#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToShmem)]
+#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToResolvedValue, ToShmem)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 /// The name of a font family of choice
 pub struct FamilyName {
     /// Name of the font family
     pub name: Atom,
     /// Syntax of the font family
     pub syntax: FontFamilyNameSyntax,
 }
@@ -259,47 +260,47 @@ impl ToCss for FamilyName {
                     serialize_identifier(ident, dest)?;
                 }
                 Ok(())
             },
         }
     }
 }
 
-#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToShmem)]
+#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToResolvedValue, ToShmem)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 /// Font family names must either be given quoted as strings,
 /// or unquoted as a sequence of one or more identifiers.
 #[repr(u8)]
 pub enum FontFamilyNameSyntax {
     /// The family name was specified in a quoted form, e.g. "Font Name"
     /// or 'Font Name'.
     Quoted,
 
     /// The family name was specified in an unquoted form as a sequence of
     /// identifiers.
     Identifiers,
 }
 
-#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToCss)]
+#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToCss, ToResolvedValue)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize, Hash))]
 /// A set of faces that vary in weight, width or slope.
 pub enum SingleFontFamily {
     /// The name of a font family of choice.
     FamilyName(FamilyName),
     /// Generic family name.
     Generic(GenericFontFamily),
 }
 
 /// A generic font-family name.
 ///
 /// The order here is important, if you change it make sure that
 /// `gfxPlatformFontList.h`s ranged array and `gfxFontFamilyList`'s
 /// sSingleGenerics are updated as well.
-#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, Parse, ToCss)]
+#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, Parse, ToCss, ToResolvedValue)]
 #[repr(u8)]
 #[allow(missing_docs)]
 pub enum GenericFontFamily {
     /// No generic family specified, only for internal usage.
     #[css(skip)]
     None,
     Serif,
     SansSerif,
@@ -379,17 +380,17 @@ impl SingleFontFamily {
         SingleFontFamily::FamilyName(FamilyName {
             name,
             syntax: family.mSyntax,
         })
     }
 }
 
 #[cfg(feature = "servo")]
-#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq)]
+#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToResolvedValue)]
 /// A list of SingleFontFamily
 pub struct FontFamilyList(Box<[SingleFontFamily]>);
 
 #[cfg(feature = "gecko")]
 #[derive(Clone, Debug)]
 /// A list of SingleFontFamily
 pub enum FontFamilyList {
     /// A strong reference to a Gecko SharedFontList object.
@@ -541,17 +542,17 @@ impl<'a> Iterator for FontFamilyNameIter
             Some(item)
         } else {
             None
         }
     }
 }
 
 /// Preserve the readability of text when font fallback occurs
-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
+#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, ToCss, ToResolvedValue)]
 pub enum FontSizeAdjust {
     #[animation(error)]
     /// None variant
     None,
     /// Number variant
     Number(CSSFloat),
 }
 
@@ -622,17 +623,17 @@ pub type FontFeatureSettings = FontSetti
 
 /// The computed value for font-variation-settings.
 pub type FontVariationSettings = FontSettings<VariationValue<Number>>;
 
 /// font-language-override can only have a single three-letter
 /// OpenType "language system" tag, so we should be able to compute
 /// it and store it as a 32-bit integer
 /// (see http://www.microsoft.com/typography/otspec/languagetags.htm).
-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq)]
+#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToResolvedValue)]
 #[repr(C)]
 pub struct FontLanguageOverride(pub u32);
 
 impl FontLanguageOverride {
     #[inline]
     /// Get computed default value of `font-language-override` with 0
     pub fn zero() -> FontLanguageOverride {
         FontLanguageOverride(0)
@@ -728,17 +729,17 @@ impl ToComputedValue for specified::MozS
 
     fn from_computed_value(other: &i8) -> Self {
         specified::MozScriptLevel::MozAbsolute(*other as i32)
     }
 }
 
 /// A wrapper over an `Angle`, that handles clamping to the appropriate range
 /// for `font-style` animation.
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss, ToResolvedValue)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 pub struct FontStyleAngle(pub Angle);
 
 impl ToAnimatedValue for FontStyleAngle {
     type AnimatedValue = Angle;
 
     #[inline]
     fn to_animated_value(self) -> Self::AnimatedValue {
@@ -825,17 +826,17 @@ impl ToCss for FontStyle {
             },
         }
     }
 }
 
 /// A value for the font-stretch property per:
 ///
 /// https://drafts.csswg.org/css-fonts-4/#propdef-font-stretch
-#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
+#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, ToCss, ToResolvedValue)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 pub struct FontStretch(pub NonNegativePercentage);
 
 impl FontStretch {
     /// 100%
     pub fn hundred() -> Self {
         FontStretch(NonNegativePercentage::hundred())
     }
--- a/servo/components/style/values/computed/image.rs
+++ b/servo/components/style/values/computed/image.rs
@@ -31,17 +31,17 @@ pub type Image = generic::Image<Gradient
 pub type Gradient =
     generic::Gradient<LineDirection, Length, LengthPercentage, Position, Color, Angle>;
 
 /// A computed gradient kind.
 pub type GradientKind =
     generic::GradientKind<LineDirection, Length, LengthPercentage, Position, Angle>;
 
 /// A computed gradient line direction.
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToResolvedValue)]
 pub enum LineDirection {
     /// An angle.
     Angle(Angle),
     /// A horizontal direction.
     Horizontal(X),
     /// A vertical direction.
     Vertical(Y),
     /// A corner.
--- a/servo/components/style/values/computed/length.rs
+++ b/servo/components/style/values/computed/length.rs
@@ -70,17 +70,17 @@ impl ToComputedValue for specified::Leng
     }
 }
 
 /// A `<length-percentage>` value. This can be either a `<length>`, a
 /// `<percentage>`, or a combination of both via `calc()`.
 ///
 /// https://drafts.csswg.org/css-values-4/#typedef-length-percentage
 #[allow(missing_docs)]
-#[derive(Clone, Copy, Debug, MallocSizeOf, ToAnimatedZero)]
+#[derive(Clone, Copy, Debug, MallocSizeOf, ToAnimatedZero, ToResolvedValue)]
 #[repr(C)]
 pub struct LengthPercentage {
     length: Length,
     percentage: Percentage,
     #[animation(constant)]
     pub clamping_mode: AllowedNumericType,
     /// Whether we specified a percentage or not.
     #[animation(constant)]
@@ -603,16 +603,17 @@ impl Size {
     ComputeSquaredDistance,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     PartialOrd,
     ToAnimatedValue,
     ToAnimatedZero,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C)]
 pub struct CSSPixelLength(CSSFloat);
 
 impl CSSPixelLength {
     /// Return a new CSSPixelLength.
     #[inline]
@@ -799,16 +800,17 @@ pub type NonNegativeLengthOrNumber = Gen
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(u8)]
 pub enum ExtremumLength {
     #[parse(aliases = "-moz-max-content")]
     MaxContent,
     #[parse(aliases = "-moz-min-content")]
     MinContent,
--- a/servo/components/style/values/computed/mod.rs
+++ b/servo/components/style/values/computed/mod.rs
@@ -529,17 +529,17 @@ impl From<CSSFloat> for GreaterThanOrEqu
 impl From<GreaterThanOrEqualToOneNumber> for CSSFloat {
     #[inline]
     fn from(number: GreaterThanOrEqualToOneNumber) -> CSSFloat {
         number.0
     }
 }
 
 #[allow(missing_docs)]
-#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, ToCss)]
+#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, ToCss, ToResolvedValue)]
 #[repr(C, u8)]
 pub enum NumberOrPercentage {
     Percentage(Percentage),
     Number(Number),
 }
 
 impl NumberOrPercentage {
     fn clamp_to_non_negative(self) -> Self {
--- a/servo/components/style/values/computed/percentage.rs
+++ b/servo/components/style/values/computed/percentage.rs
@@ -22,16 +22,17 @@ use style_traits::{CssWriter, ToCss};
     Default,
     MallocSizeOf,
     PartialEq,
     PartialOrd,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C)]
 pub struct Percentage(pub CSSFloat);
 
 impl Percentage {
     /// 100%
     #[inline]
--- a/servo/components/style/values/computed/text.rs
+++ b/servo/components/style/values/computed/text.rs
@@ -32,16 +32,17 @@ pub type InitialLetter = GenericInitialL
     Clone,
     ComputeSquaredDistance,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     ToAnimatedValue,
     ToAnimatedZero,
+    ToResolvedValue,
 )]
 pub struct LetterSpacing(pub Length);
 
 impl LetterSpacing {
     /// Return the `normal` computed value, which is just zero.
     #[inline]
     pub fn normal() -> Self {
         LetterSpacing(Length::zero())
@@ -97,17 +98,17 @@ impl ToComputedValue for specified::Word
     fn from_computed_value(computed: &Self::ComputedValue) -> Self {
         Spacing::Value(ToComputedValue::from_computed_value(computed))
     }
 }
 
 /// A computed value for the `line-height` property.
 pub type LineHeight = GenericLineHeight<NonNegativeNumber, NonNegativeLength>;
 
-#[derive(Clone, Debug, MallocSizeOf, PartialEq)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToResolvedValue)]
 /// text-overflow.
 /// When the specified value only has one side, that's the "second"
 /// side, and the sides are logical, so "second" means "end".  The
 /// start side is Clip in that case.
 ///
 /// When the specified value has two sides, those are our "first"
 /// and "second" sides, and they are physical sides ("left" and
 /// "right").
@@ -150,17 +151,17 @@ impl ToCss for TextOverflow {
 
 /// A struct that represents the _used_ value of the text-decoration property.
 ///
 /// FIXME(emilio): This is done at style resolution time, though probably should
 /// be done at layout time, otherwise we need to account for display: contents
 /// and similar stuff when we implement it.
 ///
 /// FIXME(emilio): Also, should be just a bitfield instead of three bytes.
-#[derive(Clone, Copy, Debug, Default, MallocSizeOf, PartialEq)]
+#[derive(Clone, Copy, Debug, Default, MallocSizeOf, PartialEq, ToResolvedValue)]
 pub struct TextDecorationsInEffect {
     /// Whether an underline is in effect.
     pub underline: bool,
     /// Whether an overline decoration is in effect.
     pub overline: bool,
     /// Whether a line-through style is in effect.
     pub line_through: bool,
 }
@@ -188,26 +189,26 @@ impl TextDecorationsInEffect {
         result.overline |= line.contains(TextDecorationLine::OVERLINE);
         result.line_through |= line.contains(TextDecorationLine::LINE_THROUGH);
 
         result
     }
 }
 
 /// computed value for the text-emphasis-style property
-#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss, ToResolvedValue)]
 pub enum TextEmphasisStyle {
     /// Keyword value for the text-emphasis-style property (`filled` `open`)
     Keyword(TextEmphasisKeywordValue),
     /// `none`
     None,
     /// String (will be used only first grapheme cluster) for the text-emphasis-style property
     String(String),
 }
 
 /// Keyword value for the text-emphasis-style property
-#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToCss, ToResolvedValue)]
 pub struct TextEmphasisKeywordValue {
     /// fill for the text-emphasis-style property
     pub fill: TextEmphasisFillMode,
     /// shape for the text-emphasis-style property
     pub shape: TextEmphasisShapeKeyword,
 }
--- a/servo/components/style/values/computed/time.rs
+++ b/servo/components/style/values/computed/time.rs
@@ -4,17 +4,17 @@
 
 //! Computed time values.
 
 use crate::values::CSSFloat;
 use std::fmt::{self, Write};
 use style_traits::{CssWriter, ToCss};
 
 /// A computed `<time>` value.
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd)]
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, ToResolvedValue)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 pub struct Time {
     seconds: CSSFloat,
 }
 
 impl Time {
     /// Creates a time value from a seconds amount.
     pub fn from_seconds(seconds: CSSFloat) -> Self {
--- a/servo/components/style/values/generics/background.rs
+++ b/servo/components/style/values/generics/background.rs
@@ -22,16 +22,17 @@ fn width_and_height_are_auto<L>(
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C, u8)]
 pub enum GenericBackgroundSize<LengthPercent> {
     /// `<width> <height>`
     ExplicitSize {
         /// Explicit width.
         width: GenericLengthPercentageOrAuto<LengthPercent>,
--- a/servo/components/style/values/generics/basic_shape.rs
+++ b/servo/components/style/values/generics/basic_shape.rs
@@ -26,16 +26,17 @@ pub type ClippingShape<BasicShape, Url> 
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum GeometryBox {
     FillBox,
     StrokeBox,
     ViewBox,
     ShapeBox(ShapeBox),
 }
@@ -54,16 +55,17 @@ pub type FloatAreaShape<BasicShape, Imag
     Eq,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum ShapeBox {
     MarginBox,
     BorderBox,
     PaddingBox,
     ContentBox,
 }
@@ -76,16 +78,17 @@ pub enum ShapeBox {
     Clone,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum ShapeSource<BasicShape, ReferenceBox, ImageOrUrl> {
     #[animation(error)]
     ImageOrUrl(ImageOrUrl),
     Shape(BasicShape, Option<ReferenceBox>),
     #[animation(error)]
     Box(ReferenceBox),
@@ -102,16 +105,17 @@ pub enum ShapeSource<BasicShape, Referen
     ComputeSquaredDistance,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum BasicShape<H, V, LengthPercentage, NonNegativeLengthPercentage> {
     Inset(
         #[css(field_bound)]
         #[shmem(field_bound)]
         InsetRect<LengthPercentage, NonNegativeLengthPercentage>,
     ),
@@ -136,16 +140,17 @@ pub enum BasicShape<H, V, LengthPercenta
     Clone,
     ComputeSquaredDistance,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToComputedValue,
+    ToResolvedValue,
     ToShmem,
 )]
 pub struct InsetRect<LengthPercentage, NonNegativeLengthPercentage> {
     pub rect: Rect<LengthPercentage>,
     #[shmem(field_bound)]
     pub round: BorderRadius<NonNegativeLengthPercentage>,
 }
 
@@ -158,16 +163,17 @@ pub struct InsetRect<LengthPercentage, N
     ComputeSquaredDistance,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToComputedValue,
+    ToResolvedValue,
     ToShmem,
 )]
 pub struct Circle<H, V, NonNegativeLengthPercentage> {
     pub position: Position<H, V>,
     pub radius: ShapeRadius<NonNegativeLengthPercentage>,
 }
 
 /// <https://drafts.csswg.org/css-shapes/#funcdef-ellipse>
@@ -179,16 +185,17 @@ pub struct Circle<H, V, NonNegativeLengt
     ComputeSquaredDistance,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToComputedValue,
+    ToResolvedValue,
     ToShmem,
 )]
 pub struct Ellipse<H, V, NonNegativeLengthPercentage> {
     pub position: Position<H, V>,
     pub semiaxis_x: ShapeRadius<NonNegativeLengthPercentage>,
     pub semiaxis_y: ShapeRadius<NonNegativeLengthPercentage>,
 }
 
@@ -201,16 +208,17 @@ pub struct Ellipse<H, V, NonNegativeLeng
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum ShapeRadius<NonNegativeLengthPercentage> {
     Length(NonNegativeLengthPercentage),
     #[animation(error)]
     ClosestSide,
     #[animation(error)]
     FarthestSide,
@@ -224,16 +232,17 @@ pub enum ShapeRadius<NonNegativeLengthPe
     Clone,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub struct Polygon<LengthPercentage> {
     /// The filling rule for a polygon.
     #[css(skip_if = "fill_is_default")]
     pub fill: FillRule,
     /// A collection of (x, y) coordinates to draw the polygon.
     #[css(iterable)]
@@ -245,16 +254,17 @@ pub struct Polygon<LengthPercentage> {
     Clone,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub struct PolygonCoord<LengthPercentage>(pub LengthPercentage, pub LengthPercentage);
 
 // https://drafts.csswg.org/css-shapes/#typedef-fill-rule
 // NOTE: Basic shapes spec says that these are the only two values, however
 // https://www.w3.org/TR/SVG/painting.html#FillRuleProperty
 // says that it can also be `inherit`
@@ -267,16 +277,17 @@ pub struct PolygonCoord<LengthPercentage
     Eq,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(u8)]
 pub enum FillRule {
     Nonzero,
     Evenodd,
 }
 
@@ -289,16 +300,17 @@ pub enum FillRule {
     Clone,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub struct Path {
     /// The filling rule for the svg path.
     #[css(skip_if = "fill_is_default")]
     #[animation(constant)]
     pub fill: FillRule,
     /// The svg path data.
--- a/servo/components/style/values/generics/border.rs
+++ b/servo/components/style/values/generics/border.rs
@@ -15,16 +15,17 @@ use style_traits::{CssWriter, ToCss};
     Clone,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum BorderImageSideWidth<LengthPercentage, Number> {
     /// `<length-or-percentage>`
     Length(LengthPercentage),
     /// `<number>`
     Number(Number),
     /// `auto`
@@ -36,16 +37,17 @@ pub enum BorderImageSideWidth<LengthPerc
     Clone,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C)]
 pub struct GenericBorderImageSlice<NumberOrPercentage> {
     /// The offsets.
     #[css(field_bound)]
     pub offsets: Rect<NumberOrPercentage>,
     /// Whether to fill the middle part.
@@ -64,16 +66,17 @@ pub use self::GenericBorderImageSlice as
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C)]
 pub struct GenericBorderCornerRadius<L>(#[css(field_bound)] #[shmem(field_bound)] pub Size2D<L>);
 
 pub use self::GenericBorderCornerRadius as BorderCornerRadius;
 
 impl<L> BorderCornerRadius<L> {
@@ -102,16 +105,17 @@ impl<L: Zero> Zero for BorderCornerRadiu
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(transparent)]
 pub struct BorderSpacing<L>(#[css(field_bound)] #[shmem(field_bound)] pub Size2D<L>);
 
 impl<L> BorderSpacing<L> {
     /// Trivially create a `BorderCornerRadius`.
     pub fn new(w: L, h: L) -> Self {
@@ -128,16 +132,17 @@ impl<L> BorderSpacing<L> {
     ComputeSquaredDistance,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToComputedValue,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C)]
 pub struct GenericBorderRadius<LengthPercentage> {
     /// The top left radius.
     #[shmem(field_bound)]
     pub top_left: GenericBorderCornerRadius<LengthPercentage>,
     /// The top right radius.
--- a/servo/components/style/values/generics/box.rs
+++ b/servo/components/style/values/generics/box.rs
@@ -13,16 +13,17 @@ use crate::values::animated::ToAnimatedZ
     ComputeSquaredDistance,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum VerticalAlign<LengthPercentage> {
     /// `baseline`
     Baseline,
     /// `sub`
     Sub,
     /// `super`
@@ -55,17 +56,25 @@ impl<L> VerticalAlign<L> {
 impl<L> ToAnimatedZero for VerticalAlign<L> {
     fn to_animated_zero(&self) -> Result<Self, ()> {
         Err(())
     }
 }
 
 /// https://drafts.csswg.org/css-animations/#animation-iteration-count
 #[derive(
-    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem,
+    Clone,
+    Debug,
+    MallocSizeOf,
+    PartialEq,
+    SpecifiedValueInfo,
+    ToComputedValue,
+    ToCss,
+    ToResolvedValue,
+    ToShmem,
 )]
 pub enum AnimationIterationCount<Number> {
     /// A `<number>` value.
     Number(Number),
     /// The `infinite` keyword.
     Infinite,
 }
 
@@ -79,16 +88,17 @@ pub enum AnimationIterationCount<Number>
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C, u8)]
 pub enum GenericPerspective<NonNegativeLength> {
     /// A non-negative length.
     Length(NonNegativeLength),
     /// The keyword `none`.
     None,
--- a/servo/components/style/values/generics/color.rs
+++ b/servo/components/style/values/generics/color.rs
@@ -94,16 +94,17 @@ impl<RGBA> From<RGBA> for Color<RGBA> {
     MallocSizeOf,
     PartialEq,
     Parse,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C, u8)]
 pub enum GenericColorOrAuto<C> {
     /// A `<color>`.
     Color(C),
     /// `auto`
     Auto,
--- a/servo/components/style/values/generics/column.rs
+++ b/servo/components/style/values/generics/column.rs
@@ -14,16 +14,17 @@
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum ColumnCount<PositiveInteger> {
     /// A positive integer.
     Integer(PositiveInteger),
     /// The keyword `auto`.
     #[animation(error)]
     Auto,
--- a/servo/components/style/values/generics/counters.rs
+++ b/servo/components/style/values/generics/counters.rs
@@ -10,17 +10,17 @@ use crate::computed_values::list_style_t
 use crate::values::generics::CounterStyleOrNone;
 #[cfg(feature = "gecko")]
 use crate::values::specified::Attr;
 use crate::values::CustomIdent;
 use std::ops::Deref;
 
 /// A name / value pair for counters.
 #[derive(
-    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem,
+    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
 )]
 pub struct CounterPair<Integer> {
     /// The name of the counter.
     pub name: CustomIdent,
     /// The value of the counter / increment / etc.
     pub value: Integer,
 }
 
@@ -29,16 +29,17 @@ pub struct CounterPair<Integer> {
     Clone,
     Debug,
     Default,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub struct CounterIncrement<I>(Counters<I>);
 
 impl<I> CounterIncrement<I> {
     /// Returns a new value for `counter-increment`.
     #[inline]
     pub fn new(counters: Vec<CounterPair<I>>) -> Self {
@@ -60,16 +61,17 @@ impl<I> Deref for CounterIncrement<I> {
     Clone,
     Debug,
     Default,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub struct CounterSetOrReset<I>(Counters<I>);
 
 impl<I> CounterSetOrReset<I> {
     /// Returns a new value for `counter-set` / `counter-reset`.
     #[inline]
     pub fn new(counters: Vec<CounterPair<I>>) -> Self {
@@ -85,17 +87,25 @@ impl<I> Deref for CounterSetOrReset<I> {
         &(self.0).0
     }
 }
 
 /// A generic value for lists of counters.
 ///
 /// Keyword `none` is represented by an empty vector.
 #[derive(
-    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem,
+    Clone,
+    Debug,
+    MallocSizeOf,
+    PartialEq,
+    SpecifiedValueInfo,
+    ToComputedValue,
+    ToCss,
+    ToResolvedValue,
+    ToShmem,
 )]
 pub struct Counters<I>(#[css(iterable, if_empty = "none")] Box<[CounterPair<I>]>);
 
 impl<I> Default for Counters<I> {
     #[inline]
     fn default() -> Self {
         Counters(vec![].into_boxed_slice())
     }
@@ -118,17 +128,26 @@ fn is_decimal(counter_type: &CounterStyl
 fn is_decimal(counter_type: &CounterStyleType) -> bool {
     *counter_type == CounterStyleOrNone::decimal()
 }
 
 /// The specified value for the `content` property.
 ///
 /// https://drafts.csswg.org/css-content/#propdef-content
 #[derive(
-    Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem,
+    Clone,
+    Debug,
+    Eq,
+    MallocSizeOf,
+    PartialEq,
+    SpecifiedValueInfo,
+    ToComputedValue,
+    ToCss,
+    ToResolvedValue,
+    ToShmem,
 )]
 pub enum Content<ImageUrl> {
     /// `normal` reserved keyword.
     Normal,
     /// `none` reserved keyword.
     None,
     /// `-moz-alt-content`.
     #[cfg(feature = "gecko")]
@@ -142,17 +161,26 @@ impl<ImageUrl> Content<ImageUrl> {
     #[inline]
     pub fn normal() -> Self {
         Content::Normal
     }
 }
 
 /// Items for the `content` property.
 #[derive(
-    Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem,
+    Clone,
+    Debug,
+    Eq,
+    MallocSizeOf,
+    PartialEq,
+    SpecifiedValueInfo,
+    ToComputedValue,
+    ToCss,
+    ToResolvedValue,
+    ToShmem,
 )]
 pub enum ContentItem<ImageUrl> {
     /// Literal string content.
     String(Box<str>),
     /// `counter(name, style)`.
     #[css(comma, function)]
     Counter(CustomIdent, #[css(skip_if = "is_decimal")] CounterStyleType),
     /// `counters(name, separator, style)`.
--- a/servo/components/style/values/generics/easing.rs
+++ b/servo/components/style/values/generics/easing.rs
@@ -13,16 +13,17 @@ use crate::values::CSSFloat;
     Clone,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[value_info(ty = "TIMING_FUNCTION")]
 #[repr(u8, C)]
 pub enum TimingFunction<Integer, Number> {
     /// `linear | ease | ease-in | ease-out | ease-in-out`
     Keyword(TimingKeyword),
     /// `cubic-bezier(<number>, <number>, <number>, <number>)`
@@ -49,16 +50,17 @@ pub enum TimingFunction<Integer, Number>
     Debug,
     Eq,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(u8)]
 pub enum TimingKeyword {
     Linear,
     Ease,
     EaseIn,
     EaseOut,
@@ -74,17 +76,27 @@ fn step_position_jump_enabled(_context: 
 #[cfg(feature = "servo")]
 fn step_position_jump_enabled(_context: &ParserContext) -> bool {
     false
 }
 
 #[allow(missing_docs)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 #[derive(
-    Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToComputedValue, ToCss, ToShmem,
+    Clone,
+    Copy,
+    Debug,
+    Eq,
+    MallocSizeOf,
+    Parse,
+    PartialEq,
+    ToComputedValue,
+    ToCss,
+    ToResolvedValue,
+    ToShmem,
 )]
 #[repr(u8)]
 pub enum StepPosition {
     #[parse(condition = "step_position_jump_enabled")]
     JumpStart,
     #[parse(condition = "step_position_jump_enabled")]
     JumpEnd,
     #[parse(condition = "step_position_jump_enabled")]
--- a/servo/components/style/values/generics/effects.rs
+++ b/servo/components/style/values/generics/effects.rs
@@ -11,16 +11,17 @@
     ComputeSquaredDistance,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub struct BoxShadow<Color, SizeLength, BlurShapeLength, ShapeLength> {
     /// The base shadow.
     pub base: SimpleShadow<Color, SizeLength, BlurShapeLength>,
     /// The spread radius.
     pub spread: ShapeLength,
     /// Whether this is an inset box shadow.
@@ -37,16 +38,17 @@ pub struct BoxShadow<Color, SizeLength, 
     ComputeSquaredDistance,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum Filter<Angle, Factor, Length, DropShadow, Url> {
     /// `blur(<length>)`
     #[css(function)]
     Blur(Length),
     /// `brightness(<factor>)`
     #[css(function)]
@@ -90,16 +92,17 @@ pub enum Filter<Angle, Factor, Length, D
     ComputeSquaredDistance,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub struct SimpleShadow<Color, SizeLength, ShapeLength> {
     /// Color.
     pub color: Color,
     /// Horizontal radius.
     pub horizontal: SizeLength,
     /// Vertical radius.
--- a/servo/components/style/values/generics/flex.rs
+++ b/servo/components/style/values/generics/flex.rs
@@ -14,16 +14,17 @@
     Debug,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C)]
 pub enum GenericFlexBasis<S> {
     /// `content`
     Content,
     /// `<width>`
     Size(S),
--- a/servo/components/style/values/generics/font.rs
+++ b/servo/components/style/values/generics/font.rs
@@ -11,17 +11,25 @@ use cssparser::Parser;
 use num_traits::One;
 use std::fmt::{self, Write};
 use std::io::Cursor;
 use style_traits::{CssWriter, KeywordsCollectFn, ParseError};
 use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss};
 
 /// https://drafts.csswg.org/css-fonts-4/#feature-tag-value
 #[derive(
-    Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
+    Clone,
+    Debug,
+    Eq,
+    MallocSizeOf,
+    PartialEq,
+    SpecifiedValueInfo,
+    ToComputedValue,
+    ToResolvedValue,
+    ToShmem,
 )]
 pub struct FeatureTagValue<Integer> {
     /// A four-character tag, packed into a u32 (one byte per character).
     pub tag: FontTag,
     /// The actual value.
     pub value: Integer,
 }
 
@@ -53,30 +61,40 @@ where
     ComputeSquaredDistance,
     Debug,
     Eq,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub struct VariationValue<Number> {
     /// A four-character tag, packed into a u32 (one byte per character).
     #[animation(constant)]
     pub tag: FontTag,
     /// The actual value.
     pub value: Number,
 }
 
 /// A value both for font-variation-settings and font-feature-settings.
 #[css(comma)]
 #[derive(
-    Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem,
+    Clone,
+    Debug,
+    Eq,
+    MallocSizeOf,
+    PartialEq,
+    SpecifiedValueInfo,
+    ToComputedValue,
+    ToCss,
+    ToResolvedValue,
+    ToShmem,
 )]
 pub struct FontSettings<T>(#[css(if_empty = "normal", iterable)] pub Box<[T]>);
 
 impl<T> FontSettings<T> {
     /// Default value of font settings as `normal`.
     #[inline]
     pub fn normal() -> Self {
         FontSettings(vec![].into_boxed_slice())
@@ -104,17 +122,26 @@ impl<T: Parse> Parse for FontSettings<T>
 
 /// A font four-character tag, represented as a u32 for convenience.
 ///
 /// See:
 ///   https://drafts.csswg.org/css-fonts-4/#font-variation-settings-def
 ///   https://drafts.csswg.org/css-fonts-4/#descdef-font-face-font-feature-settings
 ///
 #[derive(
-    Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
+    Clone,
+    Copy,
+    Debug,
+    Eq,
+    MallocSizeOf,
+    PartialEq,
+    SpecifiedValueInfo,
+    ToComputedValue,
+    ToResolvedValue,
+    ToShmem,
 )]
 pub struct FontTag(pub u32);
 
 impl ToCss for FontTag {
     fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
     where
         W: Write,
     {
@@ -258,16 +285,17 @@ impl Default for KeywordSize {
     Copy,
     Debug,
     Hash,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum FontStyle<Angle> {
     #[animation(error)]
     Normal,
     #[animation(error)]
     Italic,
     #[value_info(starts_with_keyword)]
--- a/servo/components/style/values/generics/gecko.rs
+++ b/servo/components/style/values/generics/gecko.rs
@@ -1,18 +1,28 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
 
 //! Generic types for legacy Gecko-only properties that should probably be
-//! unshipped at some point in the future.
+//! un-shipped at some point in the future.
 
 /// A generic value for scroll snap points.
 #[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
-#[derive(Clone, Copy, Debug, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem)]
+#[derive(
+    Clone,
+    Copy,
+    Debug,
+    PartialEq,
+    SpecifiedValueInfo,
+    ToComputedValue,
+    ToCss,
+    ToResolvedValue,
+    ToShmem,
+)]
 pub enum ScrollSnapPoint<LengthPercentage> {
     /// `none`
     None,
     /// `repeat(<length-or-percentage>)`
     #[css(function)]
     Repeat(LengthPercentage),
 }
 
--- a/servo/components/style/values/generics/grid.rs
+++ b/servo/components/style/values/generics/grid.rs
@@ -14,17 +14,25 @@ use cssparser::Parser;
 use std::fmt::{self, Write};
 use std::{mem, usize};
 use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
 
 /// A `<grid-line>` type.
 ///
 /// <https://drafts.csswg.org/css-grid/#typedef-grid-row-start-grid-line>
 #[derive(
-    Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
+    Clone,
+    Debug,
+    Default,
+    MallocSizeOf,
+    PartialEq,
+    SpecifiedValueInfo,
+    ToComputedValue,
+    ToResolvedValue,
+    ToShmem,
 )]
 pub struct GridLine<Integer> {
     /// Flag to check whether it's a `span` keyword.
     pub is_span: bool,
     /// A custom identifier for named lines.
     ///
     /// <https://drafts.csswg.org/css-grid/#grid-placement-slot>
     pub ident: Option<CustomIdent>,
@@ -159,16 +167,17 @@ impl Parse for GridLine<specified::Integ
     Debug,
     Eq,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum TrackKeyword {
     Auto,
     MaxContent,
     MinContent,
 }
 
@@ -180,16 +189,17 @@ pub enum TrackKeyword {
     Animate,
     Clone,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum TrackBreadth<L> {
     /// The generic type is almost always a non-negative `<length-percentage>`
     Breadth(L),
     /// A flex fraction specified in `fr` units.
     #[css(dimension)]
     Fr(CSSFloat),
@@ -206,17 +216,17 @@ impl<L> TrackBreadth<L> {
         matches!(*self, TrackBreadth::Breadth(..))
     }
 }
 
 /// A `<track-size>` type for explicit grid track sizing. Like `<track-breadth>`, this is
 /// generic only to avoid code bloat. It only takes `<length-percentage>`
 ///
 /// <https://drafts.csswg.org/css-grid/#typedef-track-size>
-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToShmem)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToResolvedValue, ToShmem)]
 pub enum TrackSize<L> {
     /// A flexible `<track-breadth>`
     Breadth(TrackBreadth<L>),
     /// A `minmax` function for a range over an inflexible `<track-breadth>`
     /// and a flexible `<track-breadth>`
     ///
     /// <https://drafts.csswg.org/css-grid/#valdef-grid-template-columns-minmax>
     #[css(function)]
@@ -364,17 +374,17 @@ where
     }
 
     Ok(())
 }
 
 /// The initial argument of the `repeat` function.
 ///
 /// <https://drafts.csswg.org/css-grid/#typedef-track-repeat>
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToShmem)]
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
 pub enum RepeatCount<Integer> {
     /// A positive integer. This is allowed only for `<track-repeat>` and `<fixed-repeat>`
     Number(Integer),
     /// An `<auto-fill>` keyword allowed only for `<auto-repeat>`
     AutoFill,
     /// An `<auto-fit>` keyword allowed only for `<auto-repeat>`
     AutoFit,
 }
@@ -399,17 +409,17 @@ impl Parse for RepeatCount<specified::In
         }
     }
 }
 
 /// The structure containing `<line-names>` and `<track-size>` values.
 ///
 /// It can also hold `repeat()` function parameters, which expands into the respective
 /// values in its computed form.
-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
 #[css(function = "repeat")]
 pub struct TrackRepeat<L, I> {
     /// The number of times for the value to be repeated (could also be `auto-fit` or `auto-fill`)
     pub count: RepeatCount<I>,
     /// `<line-names>` accompanying `<track_size>` values.
     ///
     /// If there's no `<line-names>`, then it's represented by an empty vector.
     /// For N `<track-size>` values, there will be N+1 `<line-names>`, and so this vector's
@@ -496,29 +506,30 @@ impl<L: Clone> TrackRepeat<L, specified:
     Animate,
     Clone,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum TrackListValue<LengthPercentage, Integer> {
     /// A <track-size> value.
     TrackSize(#[animation(field_bound)] TrackSize<LengthPercentage>),
     /// A <track-repeat> value.
     TrackRepeat(#[animation(field_bound)] TrackRepeat<LengthPercentage, Integer>),
 }
 
 /// The type of a `<track-list>` as determined during parsing.
 ///
 /// <https://drafts.csswg.org/css-grid/#typedef-track-list>
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToShmem)]
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
 pub enum TrackListType {
     /// [`<auto-track-list>`](https://drafts.csswg.org/css-grid/#typedef-auto-track-list)
     ///
     /// If this type exists, then the value at the index in `line_names` field in `TrackList`
     /// has the `<line-names>?` list that comes before `<auto-repeat>`. If it's a specified value,
     /// then the `repeat()` function (that follows the line names list) is also at the given index
     /// in `values` field. On the contrary, if it's a computed value, then the `repeat()` function
     /// is in the `auto_repeat` field.
@@ -530,17 +541,17 @@ pub enum TrackListType {
     /// Note that this is a subset of the normal `<track-list>`, and so it could be used in place
     /// of the latter.
     Explicit,
 }
 
 /// A grid `<track-list>` type.
 ///
 /// <https://drafts.csswg.org/css-grid/#typedef-track-list>
-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToShmem)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToShmem, ToResolvedValue)]
 pub struct TrackList<LengthPercentage, Integer> {
     /// The type of this `<track-list>` (auto, explicit or general).
     ///
     /// In order to avoid parsing the same value multiple times, this does a single traversal
     /// and arrives at the type of value it has parsed (or bails out gracefully with an error).
     #[css(skip)]
     pub list_type: TrackListType,
     /// A vector of `<track-size> | <track-repeat>` values.
@@ -604,17 +615,25 @@ impl<L: ToCss, I: ToCss> ToCss for Track
     }
 }
 
 /// The `<line-name-list>` for subgrids.
 ///
 /// `subgrid [ <line-names> | repeat(<positive-integer> | auto-fill, <line-names>+) ]+`
 /// Old spec: https://www.w3.org/TR/2015/WD-css-grid-1-20150917/#typedef-line-name-list
 #[derive(
-    Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
+    Clone,
+    Debug,
+    Default,
+    MallocSizeOf,
+    PartialEq,
+    SpecifiedValueInfo,
+    ToComputedValue,
+    ToResolvedValue,
+    ToShmem,
 )]
 pub struct LineNameList {
     /// The optional `<line-name-list>`
     pub names: Box<[Box<[CustomIdent]>]>,
     /// Indicates the line name that requires `auto-fill`
     pub fill_idx: Option<u32>,
 }
 
@@ -719,25 +738,27 @@ impl ToCss for LineNameList {
     Animate,
     Clone,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum GridTemplateComponent<L, I> {
     /// `none` value.
     None,
     /// The grid `<track-list>`
     TrackList(
         #[animation(field_bound)]
         #[compute(field_bound)]
+        #[resolve(field_bound)]
         #[shmem(field_bound)]
         TrackList<L, I>,
     ),
     /// A `subgrid <line-name-list>?`
     /// TODO: Support animations for this after subgrid is addressed in [grid-2] spec.
     #[animation(error)]
     Subgrid(LineNameList),
 }
--- a/servo/components/style/values/generics/image.rs
+++ b/servo/components/style/values/generics/image.rs
@@ -11,17 +11,17 @@ use crate::values::serialize_atom_identi
 use crate::Atom;
 use servo_arc::Arc;
 use std::fmt::{self, Write};
 use style_traits::{CssWriter, ToCss};
 
 /// An [image].
 ///
 /// [image]: https://drafts.csswg.org/css-images/#image-values
-#[derive(Clone, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem)]
+#[derive(Clone, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
 pub enum Image<Gradient, MozImageRect, ImageUrl> {
     /// A `<url()>` image.
     Url(ImageUrl),
     /// A `<gradient>` image.  Gradients are rather large, and not nearly as
     /// common as urls, so we box them here to keep the size of this enum sane.
     Gradient(Box<Gradient>),
     /// A `-moz-image-rect` image.  Also fairly large and rare.
     Rect(Box<MozImageRect>),
@@ -31,107 +31,107 @@ pub enum Image<Gradient, MozImageRect, I
     /// A paint worklet image.
     /// <https://drafts.css-houdini.org/css-paint-api/>
     #[cfg(feature = "servo")]
     PaintWorklet(PaintWorklet),
 }
 
 /// A CSS gradient.
 /// <https://drafts.csswg.org/css-images/#gradients>
-#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToShmem)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
 pub struct Gradient<LineDirection, Length, LengthPercentage, Position, Color, Angle> {
     /// Gradients can be linear or radial.
     pub kind: GradientKind<LineDirection, Length, LengthPercentage, Position, Angle>,
     /// The color stops and interpolation hints.
     pub items: Vec<GradientItem<Color, LengthPercentage>>,
     /// True if this is a repeating gradient.
     pub repeating: bool,
     /// Compatibility mode.
     pub compat_mode: CompatMode,
 }
 
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToShmem)]
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
 /// Whether we used the modern notation or the compatibility `-webkit`, `-moz` prefixes.
 pub enum CompatMode {
     /// Modern syntax.
     Modern,
     /// `-webkit` prefix.
     WebKit,
     /// `-moz` prefix
     Moz,
 }
 
 /// A gradient kind.
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToShmem)]
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
 pub enum GradientKind<LineDirection, Length, LengthPercentage, Position, Angle> {
     /// A linear gradient.
     Linear(LineDirection),
     /// A radial gradient.
     Radial(
         EndingShape<Length, LengthPercentage>,
         Position,
         Option<Angle>,
     ),
 }
 
 /// A radial gradient's ending shape.
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToShmem)]
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
 pub enum EndingShape<Length, LengthPercentage> {
     /// A circular gradient.
     Circle(Circle<Length>),
     /// An elliptic gradient.
     Ellipse(Ellipse<LengthPercentage>),
 }
 
 /// A circle shape.
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToShmem)]
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
 pub enum Circle<Length> {
     /// A circle radius.
     Radius(Length),
     /// A circle extent.
     Extent(ShapeExtent),
 }
 
 /// An ellipse shape.
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToShmem)]
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
 pub enum Ellipse<LengthPercentage> {
     /// An ellipse pair of radii.
     Radii(LengthPercentage, LengthPercentage),
     /// An ellipse extent.
     Extent(ShapeExtent),
 }
 
 /// <https://drafts.csswg.org/css-images/#typedef-extent-keyword>
 #[allow(missing_docs)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 #[derive(
-    Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToComputedValue, ToCss, ToShmem,
+    Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
 )]
 pub enum ShapeExtent {
     ClosestSide,
     FarthestSide,
     ClosestCorner,
     FarthestCorner,
     Contain,
     Cover,
 }
 
 /// A gradient item.
 /// <https://drafts.csswg.org/css-images-4/#color-stop-syntax>
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToShmem)]
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
 pub enum GradientItem<Color, LengthPercentage> {
     /// A color stop.
     ColorStop(ColorStop<Color, LengthPercentage>),
     /// An interpolation hint.
     InterpolationHint(LengthPercentage),
 }
 
 /// A color stop.
 /// <https://drafts.csswg.org/css-images/#typedef-color-stop-list>
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToShmem)]
+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
 pub struct ColorStop<Color, LengthPercentage> {
     /// The color of this stop.
     pub color: Color,
     /// The position of this stop.
     pub position: Option<LengthPercentage>,
 }
 
 /// Specified values for a paint worklet.
@@ -165,17 +165,17 @@ impl ToCss for PaintWorklet {
 }
 
 /// Values for `moz-image-rect`.
 ///
 /// `-moz-image-rect(<uri>, top, right, bottom, left);`
 #[allow(missing_docs)]
 #[css(comma, function)]
 #[derive(
-    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem,
+    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
 )]
 pub struct MozImageRect<NumberOrPercentage, MozImageRectUrl> {
     pub url: MozImageRectUrl,
     pub top: NumberOrPercentage,
     pub right: NumberOrPercentage,
     pub bottom: NumberOrPercentage,
     pub left: NumberOrPercentage,
 }
--- a/servo/components/style/values/generics/length.rs
+++ b/servo/components/style/values/generics/length.rs
@@ -21,16 +21,17 @@ use style_traits::ParseError;
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C, u8)]
 pub enum GenericLengthPercentageOrAuto<LengthPercent> {
     LengthPercentage(LengthPercent),
     Auto,
 }
 
@@ -105,16 +106,17 @@ impl<LengthPercentage: Parse> Parse for 
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C, u8)]
 pub enum GenericSize<LengthPercent> {
     LengthPercentage(LengthPercent),
     Auto,
     #[cfg(feature = "gecko")]
     #[animation(error)]
@@ -147,16 +149,17 @@ impl<LengthPercentage> Size<LengthPercen
     Copy,
     Debug,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C, u8)]
 pub enum GenericMaxSize<LengthPercent> {
     LengthPercentage(LengthPercent),
     None,
     #[cfg(feature = "gecko")]
     #[animation(error)]
@@ -183,16 +186,17 @@ impl<LengthPercentage> MaxSize<LengthPer
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C, u8)]
 pub enum GenericLengthOrNumber<L, N> {
     /// A number.
     ///
     /// NOTE: Numbers need to be before lengths, in order to parse them
     /// first, since `0` should be a number, not the `0px` length.
--- a/servo/components/style/values/generics/mod.rs
+++ b/servo/components/style/values/generics/mod.rs
@@ -39,17 +39,17 @@ pub mod text;
 pub mod transform;
 pub mod ui;
 pub mod url;
 
 // https://drafts.csswg.org/css-counter-styles/#typedef-symbols-type
 #[allow(missing_docs)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 #[derive(
-    Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToComputedValue, ToCss, ToShmem,
+    Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
 )]
 pub enum SymbolsType {
     Cyclic,
     Numeric,
     Alphabetic,
     Symbolic,
     Fixed,
 }
@@ -82,17 +82,17 @@ impl SymbolsType {
     }
 }
 
 /// <https://drafts.csswg.org/css-counter-styles/#typedef-counter-style>
 ///
 /// Since wherever <counter-style> is used, 'none' is a valid value as
 /// well, we combine them into one type to make code simpler.
 #[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
-#[derive(Clone, Debug, Eq, PartialEq, ToComputedValue, ToCss, ToShmem)]
+#[derive(Clone, Debug, Eq, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
 pub enum CounterStyleOrNone {
     /// `none`
     None,
     /// `<counter-style-name>`
     Name(CustomIdent),
     /// `symbols()`
     #[css(function)]
     Symbols(SymbolsType, Symbols),
@@ -170,16 +170,17 @@ impl SpecifiedValueInfo for CounterStyle
     Hash,
     MallocSizeOf,
     PartialEq,
     PartialOrd,
     SpecifiedValueInfo,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(transparent)]
 pub struct NonNegative<T>(pub T);
 
 impl<T: Add<Output = T>> Add<NonNegative<T>> for NonNegative<T> {
     type Output = Self;
 
@@ -208,16 +209,17 @@ impl<T: Zero> Zero for NonNegative<T> {
     Debug,
     MallocSizeOf,
     PartialEq,
     PartialOrd,
     SpecifiedValueInfo,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub struct GreaterThanOrEqualToOne<T>(pub T);
 
 /// A clip rect for clip and image-region
 #[allow(missing_docs)]
 #[derive(
     Clone,
@@ -226,16 +228,17 @@ pub struct GreaterThanOrEqualToOne<T>(pu
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[css(function = "rect", comma)]
 pub struct ClipRect<LengthOrAuto> {
     pub top: LengthOrAuto,
     pub right: LengthOrAuto,
     pub bottom: LengthOrAuto,
     pub left: LengthOrAuto,
--- a/servo/components/style/values/generics/position.rs
+++ b/servo/components/style/values/generics/position.rs
@@ -13,16 +13,17 @@
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C)]
 pub struct GenericPosition<H, V> {
     /// The horizontal component of position.
     pub horizontal: H,
     /// The vertical component of position.
     pub vertical: V,
@@ -49,16 +50,17 @@ impl<H, V> Position<H, V> {
     Debug,
     MallocSizeOf,
     PartialEq,
     Parse,
     SpecifiedValueInfo,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C, u8)]
 pub enum GenericZIndex<I> {
     /// An integer value.
     Integer(I),
     /// The keyword `auto`.
     Auto,
--- a/servo/components/style/values/generics/rect.rs
+++ b/servo/components/style/values/generics/rect.rs
@@ -17,16 +17,17 @@ use style_traits::{CssWriter, ParseError
     ComputeSquaredDistance,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToComputedValue,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C)]
 pub struct Rect<T>(pub T, pub T, pub T, pub T);
 
 impl<T> Rect<T> {
     /// Returns a new `Rect<T>` value.
     pub fn new(first: T, second: T, third: T, fourth: T) -> Self {
--- a/servo/components/style/values/generics/size.rs
+++ b/servo/components/style/values/generics/size.rs
@@ -19,16 +19,17 @@ use style_traits::{CssWriter, ParseError
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedZero,
     ToAnimatedValue,
     ToComputedValue,
+    ToResolvedValue,
     ToShmem,
 )]
 #[allow(missing_docs)]
 #[repr(C)]
 pub struct Size2D<L> {
     pub width: L,
     pub height: L,
 }
--- a/servo/components/style/values/generics/svg.rs
+++ b/servo/components/style/values/generics/svg.rs
@@ -19,16 +19,17 @@ use style_traits::{ParseError, StylePars
     ComputeSquaredDistance,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub struct SVGPaint<ColorType, UrlPaintServer> {
     /// The paint source
     pub kind: SVGPaintKind<ColorType, UrlPaintServer>,
     /// The fallback color. It would be empty, the `none` keyword or <color>.
     pub fallback: Option<Either<ColorType, None_>>,
 }
@@ -46,16 +47,17 @@ pub struct SVGPaint<ColorType, UrlPaintS
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum SVGPaintKind<ColorType, UrlPaintServer> {
     /// `none`
     #[animation(error)]
     None,
     /// `<color>`
     Color(ColorType),
@@ -139,16 +141,17 @@ impl<ColorType: Parse, UrlPaintServer: P
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum SVGLength<L> {
     /// `<length> | <percentage> | <number>`
     LengthPercentage(L),
     /// `context-value`
     #[animation(error)]
     ContextValue,
@@ -160,16 +163,17 @@ pub enum SVGLength<L> {
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum SVGStrokeDashArray<L> {
     /// `[ <length> | <percentage> | <number> ]#`
     #[css(comma)]
     Values(#[css(if_empty = "none", iterable)] Vec<L>),
     /// `context-value`
     ContextValue,
@@ -185,16 +189,17 @@ pub enum SVGStrokeDashArray<L> {
     Debug,
     MallocSizeOf,
     PartialEq,
     Parse,
     SpecifiedValueInfo,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum SVGOpacity<OpacityType> {
     /// `<opacity-value>`
     Opacity(OpacityType),
     /// `context-fill-opacity`
     #[animation(error)]
     ContextFillOpacity,
--- a/servo/components/style/values/generics/text.rs
+++ b/servo/components/style/values/generics/text.rs
@@ -14,16 +14,17 @@ use style_traits::ParseError;
     Clone,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum InitialLetter<Number, Integer> {
     /// `normal`
     Normal,
     /// `<number> <integer>?`
     Specified(Number, Option<Integer>),
 }
@@ -87,16 +88,17 @@ fn line_height_moz_block_height_enabled(
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToCss,
     ToShmem,
+    ToResolvedValue,
     Parse,
 )]
 #[repr(C, u8)]
 pub enum GenericLineHeight<N, L> {
     /// `normal`
     Normal,
     /// `-moz-block-height`
     #[cfg(feature = "gecko")]
--- a/servo/components/style/values/generics/transform.rs
+++ b/servo/components/style/values/generics/transform.rs
@@ -22,33 +22,44 @@ use style_traits::{CssWriter, ToCss};
     Clone,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[css(comma, function)]
 pub struct Matrix<T> {
     pub a: T,
     pub b: T,
     pub c: T,
     pub d: T,
     pub e: T,
     pub f: T,
 }
 
 #[allow(missing_docs)]
 #[cfg_attr(rustfmt, rustfmt_skip)]
 #[css(comma, function = "matrix3d")]
-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo,
-         ToComputedValue, ToCss, ToShmem)]
+#[derive(
+    Clone,
+    Copy,
+    Debug,
+    MallocSizeOf,
+    PartialEq,
+    SpecifiedValueInfo,
+    ToComputedValue,
+    ToCss,
+    ToResolvedValue,
+    ToShmem,
+)]
 pub struct Matrix3D<T> {
     pub m11: T, pub m12: T, pub m13: T, pub m14: T,
     pub m21: T, pub m22: T, pub m23: T, pub m24: T,
     pub m31: T, pub m32: T, pub m33: T, pub m34: T,
     pub m41: T, pub m42: T, pub m43: T, pub m44: T,
 }
 
 #[cfg_attr(rustfmt, rustfmt_skip)]
@@ -85,16 +96,17 @@ impl<T: Into<f64>> From<Matrix3D<T>> for
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C)]
 pub struct GenericTransformOrigin<H, V, Depth> {
     /// The horizontal origin.
     pub horizontal: H,
     /// The vertical origin.
     pub vertical: V,
@@ -115,17 +127,17 @@ impl<H, V, D> TransformOrigin<H, V, D> {
     }
 }
 
 fn is_same<N: PartialEq>(x: &N, y: &N) -> bool {
     x == y
 }
 
 #[derive(
-    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem,
+    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
 )]
 /// A single operation in the list of a `transform` value
 pub enum TransformOperation<Angle, Number, Length, Integer, LengthPercentage>
 where
     Angle: Zero,
     LengthPercentage: Zero,
     Number: PartialEq,
 {
@@ -222,17 +234,17 @@ where
     AccumulateMatrix {
         from_list: Transform<TransformOperation<Angle, Number, Length, Integer, LengthPercentage>>,
         to_list: Transform<TransformOperation<Angle, Number, Length, Integer, LengthPercentage>>,
         count: Integer,
     },
 }
 
 #[derive(
-    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem,
+    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
 )]
 /// A value of the `transform` property
 pub struct Transform<T>(#[css(if_empty = "none", iterable)] pub Vec<T>);
 
 impl<Angle, Number, Length, Integer, LengthPercentage>
     TransformOperation<Angle, Number, Length, Integer, LengthPercentage>
 where
     Angle: Zero,
@@ -553,16 +565,17 @@ pub fn get_normalized_vector_and_angle<T
     Clone,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedZero,
     ToComputedValue,
+    ToResolvedValue,
     ToShmem,
 )]
 /// A value of the `Rotate` property
 ///
 /// <https://drafts.csswg.org/css-transforms-2/#individual-transforms>
 pub enum Rotate<Number, Angle> {
     /// 'none'
     None,
@@ -623,16 +636,17 @@ where
     Clone,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedZero,
     ToComputedValue,
+    ToResolvedValue,
     ToShmem,
 )]
 /// A value of the `Scale` property
 ///
 /// <https://drafts.csswg.org/css-transforms-2/#individual-transforms>
 pub enum Scale<Number> {
     /// 'none'
     None,
@@ -672,16 +686,17 @@ impl<Number: ToCss + PartialEq> ToCss fo
     Clone,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 /// A value of the `translate` property
 ///
 /// https://drafts.csswg.org/css-transforms-2/#individual-transform-serialization:
 ///
 /// If a 2d translation is specified, the property must serialize with only one
 /// or two values (per usual, if the second value is 0px, the default, it must
@@ -714,16 +729,17 @@ where
     Copy,
     Debug,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum TransformStyle {
     #[cfg(feature = "servo")]
     Auto,
     Flat,
     #[css(keyword = "preserve-3d")]
     Preserve3d,
--- a/servo/components/style/values/generics/ui.rs
+++ b/servo/components/style/values/generics/ui.rs
@@ -6,17 +6,17 @@
 
 use std::fmt::{self, Write};
 use style_traits::{CssWriter, ToCss};
 use values::specified::ui::CursorKind;
 
 /// A generic value for the `cursor` property.
 ///
 /// https://drafts.csswg.org/css-ui/#cursor
-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
 pub struct Cursor<Image> {
     /// The parsed images for the cursor.
     pub images: Box<[Image]>,
     /// The kind of the cursor [default | help | ...].
     pub keyword: CursorKind,
 }
 
 impl<Image> Cursor<Image> {
@@ -39,17 +39,17 @@ impl<Image: ToCss> ToCss for Cursor<Imag
             image.to_css(dest)?;
             dest.write_str(", ")?;
         }
         self.keyword.to_css(dest)
     }
 }
 
 /// A generic value for item of `image cursors`.
-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
 pub struct CursorImage<ImageUrl, Number> {
     /// The url to parse images from.
     pub url: ImageUrl,
     /// The <x> and <y> coordinates.
     pub hotspot: Option<(Number, Number)>,
 }
 
 impl<ImageUrl: ToCss, Number: ToCss> ToCss for CursorImage<ImageUrl, Number> {
@@ -79,16 +79,17 @@ impl<ImageUrl: ToCss, Number: ToCss> ToC
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C, u8)]
 pub enum GenericScrollbarColor<Color> {
     /// `auto`
     Auto,
     /// `<color>{2}`
     Colors {
--- a/servo/components/style/values/generics/url.rs
+++ b/servo/components/style/values/generics/url.rs
@@ -13,16 +13,17 @@
     MallocSizeOf,
     PartialEq,
     Parse,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum UrlOrNone<Url> {
     /// `none`
     None,
     /// `A URL`
     Url(Url),
 }
--- a/servo/components/style/values/mod.rs
+++ b/servo/components/style/values/mod.rs
@@ -23,16 +23,17 @@ use to_shmem::impl_trivial_to_shmem;
 pub use crate::gecko::url::CssUrl;
 #[cfg(feature = "servo")]
 pub use crate::servo::url::CssUrl;
 
 pub mod animated;
 pub mod computed;
 pub mod distance;
 pub mod generics;
+pub mod resolved;
 pub mod specified;
 
 /// A CSS float value.
 pub type CSSFloat = f32;
 
 /// A CSS integer value.
 pub type CSSInteger = i32;
 
@@ -91,17 +92,17 @@ where
 {
     (value * 100.).to_css(dest)?;
     dest.write_str("%")
 }
 
 /// Convenience void type to disable some properties and values through types.
 #[cfg_attr(feature = "servo", derive(Deserialize, MallocSizeOf, Serialize))]
 #[derive(
-    Clone, Copy, Debug, PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToComputedValue, ToCss,
+    Clone, Copy, Debug, PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToComputedValue, ToCss, ToResolvedValue,
 )]
 pub enum Impossible {}
 
 // FIXME(nox): This should be derived but the derive code cannot cope
 // with uninhabited enums.
 impl ComputeSquaredDistance for Impossible {
     #[inline]
     fn compute_squared_distance(&self, _other: &Self) -> Result<SquaredDistance, ()> {
@@ -129,16 +130,17 @@ impl Parse for Impossible {
     MallocSizeOf,
     PartialEq,
     Parse,
     SpecifiedValueInfo,
     ToAnimatedValue,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum Either<A, B> {
     /// The first value.
     First(A),
     /// The second kind of value.
     Second(B),
 }
@@ -149,17 +151,17 @@ impl<A: Debug, B: Debug> Debug for Eithe
             Either::First(ref v) => v.fmt(f),
             Either::Second(ref v) => v.fmt(f),
         }
     }
 }
 
 /// <https://drafts.csswg.org/css-values-4/#custom-idents>
 #[derive(
-    Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
+    Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem,
 )]
 pub struct CustomIdent(pub Atom);
 
 impl CustomIdent {
     /// Parse an already-tokenizer identifier
     pub fn from_ident<'i>(
         location: SourceLocation,
         ident: &CowRcStr<'i>,
@@ -187,17 +189,17 @@ impl ToCss for CustomIdent {
     where
         W: Write,
     {
         serialize_atom_identifier(&self.0, dest)
     }
 }
 
 /// <https://drafts.csswg.org/css-animations/#typedef-keyframes-name>
-#[derive(Clone, Debug, MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToShmem)]
+#[derive(Clone, Debug, MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
 pub enum KeyframesName {
     /// <custom-ident>
     Ident(CustomIdent),
     /// <string>
     QuotedString(Atom),
 }
 
 impl KeyframesName {
--- a/servo/components/style/values/specified/align.rs
+++ b/servo/components/style/values/specified/align.rs
@@ -11,17 +11,17 @@ use crate::parser::{Parse, ParserContext
 use cssparser::Parser;
 use std::fmt::{self, Write};
 use style_traits::{CssWriter, KeywordsCollectFn, ParseError, SpecifiedValueInfo, ToCss};
 
 bitflags! {
     /// Constants shared by multiple CSS Box Alignment properties
     ///
     /// These constants match Gecko's `NS_STYLE_ALIGN_*` constants.
-    #[derive(MallocSizeOf, ToComputedValue, ToShmem)]
+    #[derive(MallocSizeOf, ToComputedValue, ToResolvedValue, ToShmem)]
     pub struct AlignFlags: u8 {
         // Enumeration stored in the lower 5 bits:
         /// 'auto'
         const AUTO =            structs::NS_STYLE_ALIGN_AUTO as u8;
         /// 'normal'
         const NORMAL =          structs::NS_STYLE_ALIGN_NORMAL as u8;
         /// 'start'
         const START =           structs::NS_STYLE_ALIGN_START as u8;
@@ -129,17 +129,17 @@ pub enum AxisDirection {
     Block,
     /// Inline direction.
     Inline,
 }
 
 /// Shared value for the `align-content` and `justify-content` properties.
 ///
 /// <https://drafts.csswg.org/css-align/#content-distribution>
-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToShmem)]
+#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 pub struct ContentDistribution {
     primary: AlignFlags,
     // FIXME(https://github.com/w3c/csswg-drafts/issues/1002): This will need to
     // accept fallback alignment, eventually.
 }
 
 impl ContentDistribution {
@@ -242,17 +242,17 @@ impl ContentDistribution {
             f(&["left", "right"]);
         }
     }
 }
 
 /// Value for the `align-content` property.
 ///
 /// <https://drafts.csswg.org/css-align/#propdef-align-content>
-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToShmem)]
+#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
 pub struct AlignContent(pub ContentDistribution);
 
 impl Parse for AlignContent {
     fn parse<'i, 't>(
         _: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Self, ParseError<'i>> {
         // NOTE Please also update `impl SpecifiedValueInfo` below when
@@ -282,17 +282,17 @@ impl From<AlignContent> for u16 {
     fn from(v: AlignContent) -> u16 {
         v.0.as_bits()
     }
 }
 
 /// Value for the `justify-content` property.
 ///
 /// <https://drafts.csswg.org/css-align/#propdef-justify-content>
-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToShmem)]
+#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
 pub struct JustifyContent(pub ContentDistribution);
 
 impl Parse for JustifyContent {
     fn parse<'i, 't>(
         _: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Self, ParseError<'i>> {
         // NOTE Please also update `impl SpecifiedValueInfo` below when
@@ -320,17 +320,17 @@ impl From<u16> for JustifyContent {
 #[cfg(feature = "gecko")]
 impl From<JustifyContent> for u16 {
     fn from(v: JustifyContent) -> u16 {
         v.0.as_bits()
     }
 }
 
 /// <https://drafts.csswg.org/css-align/#self-alignment>
-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToShmem)]
+#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
 pub struct SelfAlignment(pub AlignFlags);
 
 impl SelfAlignment {
     /// The initial value 'auto'
     #[inline]
     pub fn auto() -> Self {
         SelfAlignment(AlignFlags::AUTO)
     }
@@ -380,17 +380,17 @@ impl SelfAlignment {
         list_overflow_position_keywords(f);
         list_self_position_keywords(f, axis);
     }
 }
 
 /// The specified value of the align-self property.
 ///
 /// <https://drafts.csswg.org/css-align/#propdef-align-self>
-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToShmem)]
+#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
 pub struct AlignSelf(pub SelfAlignment);
 
 impl Parse for AlignSelf {
     fn parse<'i, 't>(
         _: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Self, ParseError<'i>> {
         // NOTE Please also update `impl SpecifiedValueInfo` below when
@@ -418,17 +418,17 @@ impl From<AlignSelf> for u8 {
     fn from(align: AlignSelf) -> u8 {
         (align.0).0.bits()
     }
 }
 
 /// The specified value of the justify-self property.
 ///
 /// <https://drafts.csswg.org/css-align/#propdef-justify-self>
-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToShmem)]
+#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
 pub struct JustifySelf(pub SelfAlignment);
 
 impl Parse for JustifySelf {
     fn parse<'i, 't>(
         _: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Self, ParseError<'i>> {
         // NOTE Please also update `impl SpecifiedValueInfo` below when
@@ -456,17 +456,17 @@ impl From<JustifySelf> for u8 {
     fn from(justify: JustifySelf) -> u8 {
         (justify.0).0.bits()
     }
 }
 
 /// Value of the `align-items` property
 ///
 /// <https://drafts.csswg.org/css-align/#propdef-align-items>
-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToShmem)]
+#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
 pub struct AlignItems(pub AlignFlags);
 
 impl AlignItems {
     /// The initial value 'normal'
     #[inline]
     pub fn normal() -> Self {
         AlignItems(AlignFlags::NORMAL)
     }
--- a/servo/components/style/values/specified/background.rs
+++ b/servo/components/style/values/specified/background.rs
@@ -42,33 +42,34 @@ impl Parse for BackgroundSize {
     Debug,
     Eq,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[allow(missing_docs)]
 #[value_info(other_values = "repeat-x,repeat-y")]
 pub enum BackgroundRepeatKeyword {
     Repeat,
     Space,
     Round,
     NoRepeat,
 }
 
 /// The value of the `background-repeat` property, with `repeat-x` / `repeat-y`
 /// represented as the combination of `no-repeat` and `repeat` in the opposite
 /// axes.
 ///
 /// https://drafts.csswg.org/css-backgrounds/#the-background-repeat
-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
 pub struct BackgroundRepeat(pub BackgroundRepeatKeyword, pub BackgroundRepeatKeyword);
 
 impl BackgroundRepeat {
     /// Returns the `repeat repeat` value.
     pub fn repeat() -> Self {
         BackgroundRepeat(
             BackgroundRepeatKeyword::Repeat,
             BackgroundRepeatKeyword::Repeat,
--- a/servo/components/style/values/specified/border.rs
+++ b/servo/components/style/values/specified/border.rs
@@ -35,16 +35,17 @@ use style_traits::{CssWriter, ParseError
     MallocSizeOf,
     Ord,
     Parse,
     PartialEq,
     PartialOrd,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(u8)]
 pub enum BorderStyle {
     Hidden,
     None,
     Inset,
     Groove,
@@ -259,17 +260,17 @@ pub enum BorderImageRepeatKeyword {
     Round,
     Space,
 }
 
 /// The specified value for the `border-image-repeat` property.
 ///
 /// https://drafts.csswg.org/css-backgrounds/#the-border-image-repeat
 #[derive(
-    Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
+    Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem,
 )]
 pub struct BorderImageRepeat(pub BorderImageRepeatKeyword, pub BorderImageRepeatKeyword);
 
 impl ToCss for BorderImageRepeat {
     fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
     where
         W: Write,
     {
--- a/servo/components/style/values/specified/box.rs
+++ b/servo/components/style/values/specified/box.rs
@@ -56,16 +56,17 @@ fn moz_box_display_values_enabled(contex
     FromPrimitive,
     Hash,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))]
 #[repr(u8)]
 pub enum Display {
     None = 0,
     Block,
     #[cfg(feature = "gecko")]
@@ -321,17 +322,26 @@ impl AnimationIterationCount {
     #[inline]
     pub fn one() -> Self {
         GenericAnimationIterationCount::Number(Number::new(1.0))
     }
 }
 
 /// A value for the `animation-name` property.
 #[derive(
-    Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
+    Clone,
+    Debug,
+    Eq,
+    Hash,
+    MallocSizeOf,
+    PartialEq,
+    SpecifiedValueInfo,
+    ToComputedValue,
+    ToResolvedValue,
+    ToShmem,
 )]
 #[value_info(other_values = "none")]
 pub struct AnimationName(pub Option<KeyframesName>);
 
 impl AnimationName {
     /// Get the name of the animation as an `Atom`.
     pub fn as_atom(&self) -> Option<&Atom> {
         self.0.as_ref().map(|n| n.as_atom())
@@ -377,16 +387,17 @@ impl Parse for AnimationName {
     Debug,
     Eq,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(u8)]
 pub enum ScrollSnapType {
     None,
     Mandatory,
     Proximity,
 }
@@ -401,30 +412,31 @@ pub enum ScrollSnapType {
     FromPrimitive,
     Hash,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(u8)]
 pub enum ScrollSnapAlignKeyword {
     None,
     Start,
     End,
     Center,
 }
 
 /// https://drafts.csswg.org/css-scroll-snap-1/#scroll-snap-align
 #[allow(missing_docs)]
 #[derive(
-    Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
+    Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem,
 )]
 #[repr(C)]
 pub struct ScrollSnapAlign {
     block: ScrollSnapAlignKeyword,
     inline: ScrollSnapAlignKeyword,
 }
 
 impl ScrollSnapAlign {
@@ -472,16 +484,17 @@ impl ToCss for ScrollSnapAlign {
     Debug,
     Eq,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(u8)]
 pub enum OverscrollBehavior {
     Auto,
     Contain,
     None,
 }
@@ -494,16 +507,17 @@ pub enum OverscrollBehavior {
     Debug,
     Eq,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(u8)]
 pub enum OverflowAnchor {
     Auto,
     None,
 }
 
@@ -515,26 +529,27 @@ pub enum OverflowAnchor {
     Debug,
     Eq,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(u8)]
 pub enum OverflowClipBox {
     PaddingBox,
     ContentBox,
 }
 
 #[derive(
-    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem,
+    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
 )]
 /// Provides a rendering hint to the user agent,
 /// stating what kinds of changes the author expects
 /// to perform on the element
 ///
 /// <https://drafts.csswg.org/css-will-change/#will-change>
 pub enum WillChange {
     /// Expresses no particular intent
@@ -557,17 +572,17 @@ impl WillChange {
     /// Get default value of `will-change` as `auto`
     pub fn auto() -> WillChange {
         WillChange::Auto
     }
 }
 
 bitflags! {
     /// The change bits that we care about.
-    #[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToShmem)]
+    #[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
     #[repr(C)]
     pub struct WillChangeBits: u8 {
         /// Whether the stacking context will change.
         const STACKING_CONTEXT = 1 << 0;
         /// Whether `transform` will change.
         const TRANSFORM = 1 << 1;
         /// Whether `scroll-position` will change.
         const SCROLL = 1 << 2;
@@ -652,18 +667,17 @@ impl Parse for WillChange {
             features: custom_idents.into_boxed_slice(),
             bits,
         })
     }
 }
 
 bitflags! {
     /// Values for the `touch-action` property.
-    #[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
-    #[derive(SpecifiedValueInfo, ToComputedValue, ToShmem)]
+    #[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
     /// These constants match Gecko's `NS_STYLE_TOUCH_ACTION_*` constants.
     #[value_info(other_values = "auto,none,manipulation,pan-x,pan-y")]
     #[repr(C)]
     pub struct TouchAction: u8 {
         /// `none` variant
         const NONE = 1 << 0;
         /// `auto` variant
         const AUTO = 1 << 1;
@@ -726,17 +740,17 @@ impl Parse for TouchAction {
                     Ok(TouchAction::PAN_Y)
                 }
             },
         }
     }
 }
 
 bitflags! {
-    #[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToShmem)]
+    #[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
     #[value_info(other_values = "none,strict,content,size,layout,paint")]
     #[repr(C)]
     /// Constants for contain: https://drafts.csswg.org/css-contain/#contain-property
     pub struct Contain: u8 {
         /// `none` variant, just for convenience.
         const NONE = 0;
         /// 'size' variant, turns on size containment
         const SIZE = 1 << 0;
@@ -828,17 +842,17 @@ impl Parse for Contain {
     }
 }
 
 /// A specified value for the `perspective` property.
 pub type Perspective = GenericPerspective<NonNegativeLength>;
 
 /// A given transition property, that is either `All`, a longhand or shorthand
 /// property, or an unsupported or custom property.
-#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue, ToShmem)]
+#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem)]
 pub enum TransitionProperty {
     /// A shorthand.
     Shorthand(ShorthandId),
     /// A longhand transitionable property.
     Longhand(LonghandId),
     /// A custom property.
     Custom(CustomPropertyName),
     /// Unrecognized property which could be any non-transitionable, custom property, or
@@ -1013,16 +1027,17 @@ pub enum Resize {
     Eq,
     Hash,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToCss,
     ToComputedValue,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(u8)]
 pub enum Appearance {
     /// No appearance at all.
     None,
     /// A typical dialog button.
     Button,
@@ -1365,16 +1380,17 @@ pub enum Appearance {
     Eq,
     Hash,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToCss,
     ToComputedValue,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(u8)]
 pub enum BreakBetween {
     Always,
     Auto,
     Page,
     Avoid,
@@ -1437,16 +1453,17 @@ impl BreakBetween {
     Eq,
     Hash,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToCss,
     ToComputedValue,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(u8)]
 pub enum BreakWithin {
     Auto,
     Avoid,
 }
 
@@ -1459,16 +1476,17 @@ pub enum BreakWithin {
     Eq,
     Hash,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToCss,
     ToComputedValue,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(u8)]
 pub enum Overflow {
     Visible,
     Hidden,
     Scroll,
     Auto,
--- a/servo/components/style/values/specified/font.rs
+++ b/servo/components/style/values/specified/font.rs
@@ -990,17 +990,17 @@ bitflags! {
         const SWASH = 0x10;
         /// Ornaments glyphs
         const ORNAMENTS = 0x20;
         /// Annotation forms
         const ANNOTATION = 0x40;
     }
 }
 
-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToResolvedValue, ToShmem)]
 /// Set of variant alternates
 pub enum VariantAlternates {
     /// Enables display of stylistic alternates
     #[css(function)]
     Stylistic(CustomIdent),
     /// Enables display with stylistic sets
     #[css(comma, function)]
     Styleset(#[css(iterable)] Box<[CustomIdent]>),
@@ -1015,17 +1015,17 @@ pub enum VariantAlternates {
     Ornaments(CustomIdent),
     /// Enables display of alternate annotation forms
     #[css(function)]
     Annotation(CustomIdent),
     /// Enables display of historical forms
     HistoricalForms,
 }
 
-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToShmem)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss, ToResolvedValue, ToShmem)]
 /// List of Variant Alternates
 pub struct VariantAlternatesList(
     #[css(if_empty = "normal", iterable)] pub Box<[VariantAlternates]>,
 );
 
 impl VariantAlternatesList {
     /// Returns the length of all variant alternates.
     pub fn len(&self) -> usize {
@@ -1183,17 +1183,17 @@ impl Parse for FontVariantAlternates {
 macro_rules! impl_variant_east_asian {
     {
         $(
             $(#[$($meta:tt)+])*
             $ident:ident / $css:expr => $gecko:ident = $value:expr,
         )+
     } => {
         bitflags! {
-            #[derive(MallocSizeOf, ToShmem)]
+            #[derive(MallocSizeOf, ToShmem, ToResolvedValue)]
             /// Vairants for east asian variant
             pub struct VariantEastAsian: u16 {
                 /// None of the features
                 const NORMAL = 0;
                 $(
                     $(#[$($meta)+])*
                     const $ident = $value;
                 )+
@@ -1390,17 +1390,17 @@ impl Parse for FontVariantEastAsian {
 macro_rules! impl_variant_ligatures {
     {
         $(
             $(#[$($meta:tt)+])*
             $ident:ident / $css:expr => $gecko:ident = $value:expr,
         )+
     } => {
         bitflags! {
-            #[derive(MallocSizeOf, ToShmem)]
+            #[derive(MallocSizeOf, ToResolvedValue, ToShmem)]
             /// Variants of ligatures
             pub struct VariantLigatures: u16 {
                 /// Specifies that common default features are enabled
                 const NORMAL = 0;
                 $(
                     $(#[$($meta)+])*
                     const $ident = $value;
                 )+
@@ -1612,17 +1612,17 @@ impl Parse for FontVariantLigatures {
 macro_rules! impl_variant_numeric {
     {
         $(
             $(#[$($meta:tt)+])*
             $ident:ident / $css:expr => $gecko:ident = $value:expr,
         )+
     } => {
         bitflags! {
-            #[derive(MallocSizeOf, ToShmem)]
+            #[derive(MallocSizeOf, ToResolvedValue, ToShmem)]
             /// Vairants of numeric values
             pub struct VariantNumeric: u8 {
                 /// None of other variants are enabled.
                 const NORMAL = 0;
                 $(
                     $(#[$($meta)+])*
                     const $ident = $value;
                 )+
@@ -1853,17 +1853,17 @@ impl Parse for FontFeatureSettings {
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<FontFeatureSettings, ParseError<'i>> {
         SpecifiedFontFeatureSettings::parse(context, input).map(FontFeatureSettings::Value)
     }
 }
 
 #[derive(
-    Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
+    Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem,
 )]
 /// Whether user agents are allowed to synthesize bold or oblique font faces
 /// when a font family lacks bold or italic faces
 pub struct FontSynthesis {
     /// If a `font-weight` is requested that the font family does not contain,
     /// the user agent may synthesize the requested weight from the weights
     /// that do exist in the font family.
     #[css(represents_keyword)]
@@ -2153,16 +2153,17 @@ impl Parse for VariationValue<Number> {
     Clone,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 /// text-zoom. Enable if true, disable if false
 pub struct XTextZoom(#[css(skip)] pub bool);
 
 impl Parse for XTextZoom {
     fn parse<'i, 't>(
         _: &ParserContext,
@@ -2172,17 +2173,17 @@ impl Parse for XTextZoom {
             false,
             "Should be set directly by presentation attributes only."
         );
         Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
     }
 }
 
 #[derive(
-    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem,
+    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
 )]
 /// Internal property that reflects the lang attribute
 pub struct XLang(#[css(skip)] pub Atom);
 
 impl XLang {
     #[inline]
     /// Get default value for `-x-lang`
     pub fn get_initial_value() -> XLang {
@@ -2261,17 +2262,17 @@ impl Parse for MozScriptLevel {
             return Ok(MozScriptLevel::Relative(i));
         }
         input.expect_ident_matching("auto")?;
         Ok(MozScriptLevel::Auto)
     }
 }
 
 #[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
-#[derive(Clone, Copy, Debug, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem)]
+#[derive(Clone, Copy, Debug, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
 /// Specifies the multiplier to be used to adjust font size
 /// due to changes in scriptlevel.
 ///
 /// Ref: https://www.w3.org/TR/MathML3/chapter3.html#presm.mstyle.attrs
 pub struct MozScriptSizeMultiplier(pub f32);
 
 impl MozScriptSizeMultiplier {
     #[inline]
--- a/servo/components/style/values/specified/list.rs
+++ b/servo/components/style/values/specified/list.rs
@@ -11,17 +11,17 @@ use crate::values::generics::CounterStyl
 use crate::values::CustomIdent;
 use cssparser::{Parser, Token};
 use servo_arc::Arc;
 use style_traits::{ParseError, StyleParseErrorKind};
 
 /// Specified and computed `list-style-type` property.
 #[cfg(feature = "gecko")]
 #[derive(
-    Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem,
+    Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
 )]
 pub enum ListStyleType {
     /// <counter-style> | none
     CounterStyle(CounterStyleOrNone),
     /// <string>
     String(String),
 }
 
@@ -72,29 +72,29 @@ impl Parse for ListStyleType {
         Ok(ListStyleType::String(
             input.expect_string()?.as_ref().to_owned(),
         ))
     }
 }
 
 /// A quote pair.
 #[derive(
-    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem,
+    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
 )]
 pub struct QuotePair {
     /// The opening quote.
     pub opening: Box<str>,
 
     /// The closing quote.
     pub closing: Box<str>,
 }
 
 /// Specified and computed `quotes` property.
 #[derive(
-    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem,
+    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
 )]
 pub struct Quotes(
     #[css(iterable, if_empty = "none")]
     #[ignore_malloc_size_of = "Arc"]
     pub Arc<Box<[QuotePair]>>,
 );
 
 impl Parse for Quotes {
@@ -138,16 +138,17 @@ impl Parse for Quotes {
     Eq,
     Hash,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(u8)]
 pub enum MozListReversed {
     /// the initial value
     False,
     /// exclusively used for <ol reversed> in our html.css UA sheet
     True,
--- a/servo/components/style/values/specified/mod.rs
+++ b/servo/components/style/values/specified/mod.rs
@@ -704,17 +704,17 @@ impl AllowQuirks {
         }
     }
 }
 
 /// An attr(...) rule
 ///
 /// `[namespace? `|`]? ident`
 #[derive(
-    Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
+    Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem,
 )]
 #[css(function)]
 pub struct Attr {
     /// Optional namespace prefix and URL.
     pub namespace: Option<(Prefix, Namespace)>,
     /// Attribute name
     pub attribute: Atom,
 }
--- a/servo/components/style/values/specified/motion.rs
+++ b/servo/components/style/values/specified/motion.rs
@@ -18,16 +18,17 @@ use style_traits::{ParseError, StylePars
     ComputeSquaredDistance,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedZero,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum OffsetPath {
     // We could merge SVGPathData into ShapeSource, so we could reuse them. However,
     // we don't want to support other value for offset-path, so use SVGPathData only for now.
     /// Path value for path(<string>).
     #[css(function)]
     Path(SVGPathData),
--- a/servo/components/style/values/specified/outline.rs
+++ b/servo/components/style/values/specified/outline.rs
@@ -17,16 +17,17 @@ use style_traits::ParseError;
     Eq,
     MallocSizeOf,
     Ord,
     PartialEq,
     PartialOrd,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(C, u8)]
 /// <https://drafts.csswg.org/css-ui/#propdef-outline-style>
 pub enum OutlineStyle {
     /// auto
     Auto,
     /// <border-style>
--- a/servo/components/style/values/specified/position.rs
+++ b/servo/components/style/values/specified/position.rs
@@ -53,16 +53,17 @@ pub enum PositionComponent<S> {
     Eq,
     Hash,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[allow(missing_docs)]
 pub enum X {
     Left,
     Right,
 }
 
@@ -74,16 +75,17 @@ pub enum X {
     Eq,
     Hash,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[allow(missing_docs)]
 pub enum Y {
     Top,
     Bottom,
 }
 
@@ -440,16 +442,17 @@ impl ToCss for LegacyPosition {
     Copy,
     Debug,
     Eq,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 /// Auto-placement algorithm Option
 pub enum AutoFlow {
     /// The auto-placement algorithm places items by filling each row in turn,
     /// adding new rows as necessary.
     Row,
     /// The auto-placement algorithm places items by filling each column in turn,
@@ -462,16 +465,17 @@ pub enum AutoFlow {
     Copy,
     Debug,
     Eq,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 /// Controls how the auto-placement algorithm works
 /// specifying exactly how auto-placed items get flowed into the grid
 pub struct GridAutoFlow {
     /// Specifiy how auto-placement algorithm fills each `row` or `column` in turn
     pub autoflow: AutoFlow,
     /// Specify use `dense` packing algorithm or not
@@ -562,18 +566,17 @@ impl From<GridAutoFlow> for u8 {
 
         if v.dense {
             result |= structs::NS_STYLE_GRID_AUTO_FLOW_DENSE as u8;
         }
         result
     }
 }
 
-#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
-#[derive(Clone, Debug, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem)]
 /// https://drafts.csswg.org/css-grid/#named-grid-area
 pub struct TemplateAreas {
     /// `named area` containing for each template area
     #[css(skip)]
     pub areas: Box<[NamedArea]>,
     /// The original CSS string value of each template area
     #[css(iterable)]
     pub strings: Box<[Box<str>]>,
@@ -670,33 +673,32 @@ impl Parse for TemplateAreas {
 
         TemplateAreas::from_vec(strings)
             .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
     }
 }
 
 /// Arc type for `Arc<TemplateAreas>`
 #[derive(
-    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem,
+    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
 )]
 pub struct TemplateAreasArc(#[ignore_malloc_size_of = "Arc"] pub Arc<TemplateAreas>);
 
 impl Parse for TemplateAreasArc {
     fn parse<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Self, ParseError<'i>> {
         let parsed = TemplateAreas::parse(context, input)?;
 
         Ok(TemplateAreasArc(Arc::new(parsed)))
     }
 }
 
-#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
-#[derive(Clone, Debug, PartialEq, SpecifiedValueInfo, ToShmem)]
+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToShmem)]
 /// Not associated with any particular grid item, but can
 /// be referenced from the grid-placement properties.
 pub struct NamedArea {
     /// Name of the `named area`
     pub name: Box<str>,
     /// Rows of the `named area`
     pub rows: Range<u32>,
     /// Columns of the `named area`
--- a/servo/components/style/values/specified/svg.rs
+++ b/servo/components/style/values/specified/svg.rs
@@ -124,17 +124,17 @@ const PAINT_ORDER_MASK: u8 = 0b11;
 /// Each pair can be set to FILL, STROKE, or MARKERS
 /// Lowest significant bit pairs are highest priority.
 ///  `normal` is the empty bitfield. The three pairs are
 /// never zero in any case other than `normal`.
 ///
 /// Higher priority values, i.e. the values specified first,
 /// will be painted first (and may be covered by paintings of lower priority)
 #[derive(
-    Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
+    Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem,
 )]
 pub struct SVGPaintOrder(pub u8);
 
 impl SVGPaintOrder {
     /// Get default `paint-order` with `0`
     pub fn normal() -> Self {
         SVGPaintOrder(0)
     }
@@ -233,17 +233,17 @@ impl ToCss for SVGPaintOrder {
         }
         Ok(())
     }
 }
 
 /// Specified MozContextProperties value.
 /// Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-context-properties)
 #[derive(
-    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToShmem,
+    Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, ToResolvedValue, ToShmem,
 )]
 pub struct MozContextProperties(pub CustomIdent);
 
 impl Parse for MozContextProperties {
     fn parse<'i, 't>(
         _context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<MozContextProperties, ParseError<'i>> {
--- a/servo/components/style/values/specified/svg_path.rs
+++ b/servo/components/style/values/specified/svg_path.rs
@@ -21,16 +21,17 @@ use style_traits::{CssWriter, ParseError
 #[derive(
     Clone,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToAnimatedZero,
     ToComputedValue,
+    ToResolvedValue,
     ToShmem,
 )]
 pub struct SVGPathData(Box<[PathCommand]>);
 
 impl SVGPathData {
     /// Return SVGPathData by a slice of PathCommand.
     #[inline]
     pub fn new(cmd: Box<[PathCommand]>) -> Self {
--- a/servo/components/style/values/specified/table.rs
+++ b/servo/components/style/values/specified/table.rs
@@ -12,16 +12,17 @@ use style_traits::{ParseError, StylePars
     Clone,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 /// span. for `<col span>` pres attr
 pub struct XSpan(#[css(skip)] pub i32);
 
 impl Parse for XSpan {
     // never parse it, only set via presentation attribute
     fn parse<'i, 't>(
--- a/servo/components/style/values/specified/text.rs
+++ b/servo/components/style/values/specified/text.rs
@@ -223,17 +223,17 @@ impl ToComputedValue for TextOverflow {
                 first: computed.first.clone(),
                 second: Some(computed.second.clone()),
             }
         }
     }
 }
 
 bitflags! {
-    #[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToShmem)]
+    #[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)]
     #[value_info(other_values = "none,underline,overline,line-through,blink")]
     #[repr(C)]
     /// Specified keyword values for the text-decoration-line property.
     pub struct TextDecorationLine: u8 {
         /// No text decoration line is specified.
         const NONE = 0;
         /// underline
         const UNDERLINE = 1 << 0;
@@ -360,16 +360,17 @@ impl TextDecorationLine {
     FromPrimitive,
     Hash,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[allow(missing_docs)]
 pub enum TextAlignKeyword {
     Start,
     End,
     Left,
     Right,
@@ -669,16 +670,17 @@ impl Parse for TextEmphasisStyle {
     Debug,
     Eq,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum TextEmphasisHorizontalWritingModeValue {
     /// Draw marks over the text in horizontal writing mode.
     Over,
     /// Draw marks under the text in horizontal writing mode.
     Under,
 }
@@ -690,16 +692,17 @@ pub enum TextEmphasisHorizontalWritingMo
     Debug,
     Eq,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub enum TextEmphasisVerticalWritingModeValue {
     /// Draws marks to the right of the text in vertical writing mode.
     Right,
     /// Draw marks to the left of the text in vertical writing mode.
     Left,
 }
@@ -709,16 +712,17 @@ pub enum TextEmphasisVerticalWritingMode
     Clone,
     Copy,
     Debug,
     MallocSizeOf,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 pub struct TextEmphasisPosition(
     pub TextEmphasisHorizontalWritingModeValue,
     pub TextEmphasisVerticalWritingModeValue,
 );
 
 impl TextEmphasisPosition {
@@ -810,16 +814,17 @@ impl From<TextEmphasisPosition> for u8 {
     Debug,
     Eq,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[allow(missing_docs)]
 pub enum WordBreak {
     Normal,
     BreakAll,
     KeepAll,
     /// The break-word value, needed for compat.
@@ -838,16 +843,17 @@ pub enum WordBreak {
     Debug,
     Eq,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[allow(missing_docs)]
 pub enum OverflowWrap {
     Normal,
     BreakWord,
     Anywhere,
 }
--- a/servo/components/style/values/specified/ui.rs
+++ b/servo/components/style/values/specified/ui.rs
@@ -52,17 +52,17 @@ impl Parse for CursorImage {
                 Err(_) => None,
             },
         })
     }
 }
 
 /// Specified value of `-moz-force-broken-image-icon`
 #[derive(
-    Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToShmem,
+    Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem,
 )]
 pub struct MozForceBrokenImageIcon(pub bool);
 
 impl MozForceBrokenImageIcon {
     /// Return initial value of -moz-force-broken-image-icon which is false.
     #[inline]
     pub fn false_value() -> MozForceBrokenImageIcon {
         MozForceBrokenImageIcon(false)
@@ -136,16 +136,17 @@ impl Parse for ScrollbarColor {
     Debug,
     Eq,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(u8)]
 pub enum UserSelect {
     Auto,
     Text,
     #[parse(aliases = "-moz-none")]
     None,
@@ -164,16 +165,17 @@ pub enum UserSelect {
     Eq,
     FromPrimitive,
     MallocSizeOf,
     Parse,
     PartialEq,
     SpecifiedValueInfo,
     ToComputedValue,
     ToCss,
+    ToResolvedValue,
     ToShmem,
 )]
 #[repr(u8)]
 pub enum CursorKind {
     None,
     Default,
     Pointer,
     ContextMenu,
--- a/servo/components/style_derive/lib.rs
+++ b/servo/components/style_derive/lib.rs
@@ -20,16 +20,17 @@ use proc_macro::TokenStream;
 mod animate;
 mod compute_squared_distance;
 mod parse;
 mod specified_value_info;
 mod to_animated_value;
 mod to_animated_zero;
 mod to_computed_value;
 mod to_css;
+mod to_resolved_value;
 
 #[proc_macro_derive(Animate, attributes(animate, animation))]
 pub fn derive_animate(stream: TokenStream) -> TokenStream {
     let input = syn::parse(stream).unwrap();
     animate::derive(input).into()
 }
 
 #[proc_macro_derive(ComputeSquaredDistance, attributes(animation, distance))]
@@ -57,16 +58,22 @@ pub fn derive_to_animated_zero(stream: T
 }
 
 #[proc_macro_derive(ToComputedValue, attributes(compute))]
 pub fn derive_to_computed_value(stream: TokenStream) -> TokenStream {
     let input = syn::parse(stream).unwrap();
     to_computed_value::derive(input).into()
 }
 
+#[proc_macro_derive(ToResolvedValue, attributes(resolve))]
+pub fn derive_to_resolved_value(stream: TokenStream) -> TokenStream {
+    let input = syn::parse(stream).unwrap();
+    to_resolved_value::derive(input).into()
+}
+
 #[proc_macro_derive(ToCss, attributes(css))]
 pub fn derive_to_css(stream: TokenStream) -> TokenStream {
     let input = syn::parse(stream).unwrap();
     to_css::derive(input).into()
 }
 
 #[proc_macro_derive(SpecifiedValueInfo, attributes(css, parse, value_info))]
 pub fn derive_specified_value_info(stream: TokenStream) -> TokenStream {