diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,14 @@
 CHANGELOG
 
+  0.16.0:
+    - Add grid size and location support.
+    - Derive `Stretch` for justified content
+    - Add `AspectRatio`
+    - Promote `not` to a type class
+    - Render CSS refinements
+    - Bugfixes & improved test suite
+    Thanks to Leonard Monnier, Yoo Chung, Skyfold, qwbarch, David Fox
+
   0.15.0:
     - Add `all` media type.
     - Support `prefers-color-scheme` media feature.
diff --git a/clay.cabal b/clay.cabal
--- a/clay.cabal
+++ b/clay.cabal
@@ -1,5 +1,5 @@
 Name:     clay
-Version:  0.15.0
+Version:  0.16.0
 Synopsis: CSS preprocessor as embedded Haskell.
 Description:
   Clay is a CSS preprocessor like LESS and Sass, but implemented as an embedded
@@ -77,7 +77,7 @@
     Clay.Transition
 
   Build-Depends:
-    base  >= 4.11 && < 4.20,
+    base  >= 4.11 && < 4.22,
     mtl   >= 1,
     text  >= 0.11
   GHC-Options: -Wall -Wcompat
@@ -89,7 +89,7 @@
   Build-Tools: hspec-discover
   main-is: Spec.hs
   Build-Depends:
-    base                 >= 4.11  && < 4.20,
+    base                 >= 4.11  && < 4.22,
     mtl                  >= 1,
     text                 >= 0.11,
     hspec                >= 2.2.0,
diff --git a/src/Clay/Color.hs b/src/Clay/Color.hs
--- a/src/Clay/Color.hs
+++ b/src/Clay/Color.hs
@@ -178,10 +178,10 @@
 instance Val Color where
   value clr =
     case clr of
-      Rgba r g b 1.0 -> Value $mconcat ["#",  p' r, p' g, p' b]
-      Rgba r g b a   -> Value $mconcat ["rgba(", p r, ",", p g, ",", p b, ",", ah a, ")"]
-      Hsla h s l 1.0 -> Value $mconcat ["hsl(",  p h, ",", f s, ",", f l,            ")"]
-      Hsla h s l a   -> Value $mconcat ["hsla(", p h, ",", f s, ",", f l, ",", ah a, ")"]
+      Rgba r g b 1.0 -> Value $ mconcat ["#",  p' r, p' g, p' b]
+      Rgba r g b a   -> Value $ mconcat ["rgba(", p r, ",", p g, ",", p b, ",", ah a, ")"]
+      Hsla h s l 1.0 -> Value $ mconcat ["hsl(",  p h, ",", f s, ",", f l,            ")"]
+      Hsla h s l a   -> Value $ mconcat ["hsla(", p h, ",", f s, ",", f l, ",", ah a, ")"]
       Other o        -> o
     where p  = fromString . show
           p' = fromString . printf "%02x"
diff --git a/src/Clay/Flexbox.hs b/src/Clay/Flexbox.hs
--- a/src/Clay/Flexbox.hs
+++ b/src/Clay/Flexbox.hs
@@ -109,7 +109,7 @@
 
 newtype JustifyContentValue = JustifyContentValue Value
   deriving (Val, Other, Inherit, Center, FlexEnd
-          , FlexStart, SpaceAround, SpaceBetween, SpaceEvenly)
+          , FlexStart, SpaceAround, SpaceBetween, SpaceEvenly, Stretch)
 
 justifyContent :: JustifyContentValue -> Css
 justifyContent = key "justify-content"
diff --git a/src/Clay/Geometry.hs b/src/Clay/Geometry.hs
--- a/src/Clay/Geometry.hs
+++ b/src/Clay/Geometry.hs
@@ -7,6 +7,12 @@
 -- * Sizing.
 , width, height, minWidth, minHeight, maxWidth, maxHeight
 
+-- ** Aspect ratio.
+, AspectRatio
+, aspectRatio
+, (%)
+, withFallback
+
 -- * Padding.
 , padding
 , paddingTop, paddingLeft, paddingRight, paddingBottom
@@ -17,6 +23,9 @@
 )
 where
 
+import qualified Data.Ratio as R
+import Data.String (fromString)
+import Clay.Common
 import Clay.Property
 import Clay.Stylesheet
 import Clay.Size
@@ -42,6 +51,100 @@
 
 -------------------------------------------------------------------------------
 
+-- | Represents an aspect ratio for use with 'aspectRatio'.
+--
+-- A fixed ratio can be formed from two integers:
+--
+-- >>> let _ = 4%3 :: AspectRatio
+--
+-- An aspect ratio can also be converted from a 'Rational':
+--
+-- >>> let _ = fromRational 0.5 :: AspectRatio
+--
+data AspectRatio = AspectRatio Rational
+                 | AspectRatioValue Value
+                 | AspectRatioWithFallback (AspectRatio, AspectRatio)
+
+instance Auto AspectRatio where auto = AspectRatioValue auto
+instance Inherit AspectRatio where inherit = AspectRatioValue inherit
+instance Initial AspectRatio where initial = AspectRatioValue initial
+instance Unset AspectRatio where unset = AspectRatioValue unset
+instance Other AspectRatio where other = AspectRatioValue
+
+-- | An 'AspectRatio' can be converted from an 'Integer',
+-- but other operations are not supported.
+instance Num AspectRatio where
+  fromInteger = AspectRatio . toRational
+  (+)    = error   "plus not implemented for AspectRatio"
+  (*)    = error  "times not implemented for AspectRatio"
+  abs    = error    "abs not implemented for AspectRatio"
+  signum = error "signum not implemented for AspectRatio"
+  negate = error "negate not implemented for AspectRatio"
+
+-- | An 'AspectRatio' can be converted from a 'Rational',
+-- but other operations are not supported.
+instance Fractional AspectRatio where
+  fromRational = AspectRatio
+  recip  = error  "recip not implemented for AspectRatio"
+
+instance Val AspectRatio where
+  value (AspectRatioValue v) = v
+  value (AspectRatio r) = v
+    where v = fromString $ numerator <> "/" <> denominator :: Value
+          numerator = show (R.numerator r)
+          denominator = show (R.denominator r)
+  value (AspectRatioWithFallback (a, b)) = value a <> " " <> value b
+
+-- | Defines the width to height ratio of an element.
+-- At least one of the width or height must be of automatic size,
+-- otherwise the aspect ratio will be ignored.
+--
+-- It can be given a fixed ratio of the width to the height:
+--
+-- >>> renderWith compact [] $ aspectRatio (4%3)
+-- "{aspect-ratio:4/3}"
+--
+-- It can also be the intrinsic aspect ratio for the element:
+--
+-- >>> renderWith compact [] $ aspectRatio auto
+-- "{aspect-ratio:auto}"
+--
+-- It can be told to use the intrinsic aspect ratio for the element,
+-- but to use a fixed ratio while it is unknown or if the element does not have one:
+--
+-- >>> renderWith compact [] $ aspectRatio $ auto `withFallback` (4%3)
+-- "{aspect-ratio:auto 4/3}"
+--
+-- Corresponds to the
+-- [@aspect-ratio@](https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio)
+-- property in CSS.
+aspectRatio :: AspectRatio -> Css
+aspectRatio = key "aspect-ratio"
+
+-- | The aspect ratio of the width to the height for use with 'aspectRatio'.
+--
+-- Note that this is /not/ the same @%@ operator from the "Data.Ratio" module,
+-- although they do both semantically represent ratios.  The same symbol is used
+-- to signify that the return value is a ratio.
+(%) :: Integer -> Integer -> AspectRatio
+(%) m n = fromRational $ (R.%) m n
+
+-- The same as the normal % operator.
+infixl 7 %
+
+-- | Returns an aspect ratio specifying that the intrinsic aspect
+-- ratio should be used, but when it is unknown or there is none,
+-- a fixed ratio can be used as a fallback.
+withFallback :: AspectRatio -> AspectRatio -> AspectRatio
+withFallback x@(AspectRatioValue "auto") y@(AspectRatio _) =
+  AspectRatioWithFallback (x, y)
+withFallback x@(AspectRatio _) y@(AspectRatioValue "auto") =
+  AspectRatioWithFallback (x, y)
+withFallback _ _ =
+  error "Arguments for aspectRatio . withFallback must be auto and a ratio in either order"
+
+-------------------------------------------------------------------------------
+
 padding :: Size a -> Size a -> Size a -> Size a -> Css
 padding a b c d = key "padding" (a ! b ! c ! d)
 
@@ -63,4 +166,3 @@
 marginLeft    = key "margin-left"
 marginRight   = key "margin-right"
 marginBottom  = key "margin-bottom"
-
diff --git a/src/Clay/Grid.hs b/src/Clay/Grid.hs
--- a/src/Clay/Grid.hs
+++ b/src/Clay/Grid.hs
@@ -1,7 +1,70 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FunctionalDependencies #-}
 {-# LANGUAGE OverloadedStrings #-}
--- | Partial implementation of <https://alligator.io/css/css-grid-layout-grid-areas grid area CSS API>.
+{-# LANGUAGE ExtendedDefaultRules #-}
+{-# OPTIONS_GHC -Wno-type-defaults #-}
+
+-- | Partial implementation of
+-- | <https://alligator.io/css/css-grid-layout-grid-areas grid area CSS API>.
+module Clay.Grid
+(
+    -- * Grid
+    --
+    -- $gridIntro
+    gridGap
+  , gridTemplateColumns
+
+    -- * Size and location
+    --
+    -- $sizeAndLocationIntro
+
+    -- ** Data types and type classes
+  , GridLine
+  , ToGridLine
+  , GridLines2
+  , ToGridLines2
+  , GridLines4
+  , ToGridLines4
+  , OneGridLine
+  , TwoGridLines
+  , ThreeGridLines
+  , FourGridLines
+  , CustomIdentGrid
+  , customIdentToText
+  , partialMkCustomIdentGrid
+  , ToSpan
+
+    -- ** Style properties
+    --
+    -- $invalidValues
+  , gridArea
+  , gridColumn
+  , gridColumnStart
+  , gridColumnEnd
+  , gridRow
+  , gridRowStart
+  , gridRowEnd
+
+    -- ** Keywords
+  , (//)
+  , span_
+)
+where
+
+import qualified Clay.Common as Com
+import           Clay.Property (Val, Value, noCommas, value)
+import           Clay.Size (Size)
+import           Clay.Stylesheet (Css, key)
+import           Data.Char (isNumber)
+import           Data.Text (Text)
+import qualified Data.Text as T
+import           Prelude
+
+-- $gridIntro
+-- @grid-gap@ and @grid-template@ CSS properties.
 --
--- For instance, you want to generate the following CSS:
+-- === Example
+-- For the below CSS code:
 --
 -- @
 -- .grid1 {
@@ -24,7 +87,7 @@
 -- }
 -- @
 --
--- The corresponding clay code:
+-- The corresponding clay code is:
 --
 -- @
 --  ".grid1" ? do
@@ -39,16 +102,7 @@
 --    gridGap $ rem 1
 --    width maxContent
 -- @
-module Clay.Grid
-( gridGap
-, gridTemplateColumns
-)
-where
 
-import Clay.Property
-import Clay.Size
-import Clay.Stylesheet
-
 -- | Property sets the gaps (gutters) between rows and columns.
 gridGap :: Size a -> Css
 gridGap = key "grid-gap"
@@ -56,3 +110,666 @@
 -- | Property defines the line names and track sizing functions of the grid columns.
 gridTemplateColumns :: [Size a] -> Css
 gridTemplateColumns = key "grid-template-columns" . noCommas
+
+-- $sizeAndLocationIntro
+--
+-- == CSS documentation
+-- The below functions are based on
+-- [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/CSS)
+-- CSS documentation.
+--
+-- === __Naming note__
+-- In this documentation, as the functions are polymorphic we sometimes
+-- refer to the CSS types as used in the
+-- [mdm web docs_](https://developer.mozilla.org/en-US/docs/Web/CSS)
+-- rather than the Haskell types.
+-- For example, @grid-line@ is used instead of 'GridLine' as a the argument
+-- might be provided as a 'GridLine' but also as an 'Integer', 'String', etc.
+--
+-- == Pragma
+-- #pragma#
+-- If you want to avoid specifying the types of the arguments, enable
+-- the @ExtendedDefaultRules@ GHC language pragma as well as the
+-- @-Wno-type-defaults@ GHC option to avoid compilation warnings.
+--
+-- @
+-- {-# LANGUAGE ExtendedDefaultRules #-}
+-- {-# OPTIONS_GHC -Wno-type-defaults #-}
+-- @
+--
+-- === __Examples__
+-- With the above enabled, you can write:
+--
+-- >> gridRowStart 2
+--
+-- >> gridRowStart "somegridarea"
+--
+-- If you do not enable those, then you must write:
+--
+-- >> gridRowStart (2 :: Integer)
+--
+-- >> gridRowStart ("somegridarea" :: String)
+--
+-- === __Note__
+-- If you decide to enable the above, it is advisable to have your Clay
+-- CSS code in its own module, so the behaviour of the rest of your code
+-- is not affected.
+--
+-- == Examples
+-- Examples are provided through the documentation for the various functions.
+-- Further examples can be found in the source code of the test suite
+-- in the GridSpec.hs module.
+
+-- | A @grid-line@ value.
+--
+-- A @grid-line@ value specifies a size and location in a grid.
+--
+-- === __Note__
+-- To know more about @grid-line@ value, see for example the documentation of
+-- the [grid-row-start](https://developer.mozilla.org/en-US/docs/Web/CSS/grid-row-start)
+-- CSS property.
+data GridLine
+
+  -- | 'Integer' value.
+  --
+  -- __NOTE:__ 'Integer' value of 0 is invalid.
+  = Coordinate Integer
+
+  -- | @custom-ident@ with an optional 'Integer' value.
+  --
+  -- __NOTE:__ 'Integer' value of 0 is invalid.
+  | GridLineCustomIdent CustomIdentGrid (Maybe Integer)
+
+  -- | @span@ CSS keyword with an optional @custom-ident@
+  -- | and/or 'Integer' value.
+  --
+  -- __NOTE:__ negative 'Integer' or 0 are invalid.
+  | Span (Maybe CustomIdentGrid) (Maybe Integer)
+
+  -- | Other grid line values: @auto@, @inherit@, @initial@, @unset@.
+  | OtherGridLine Value
+  deriving (Eq, Show)
+
+class ToGridLine a where
+  -- | Convert the provided type to a 'GridLine'.
+  toGridLine :: a -> GridLine
+
+instance ToGridLine GridLine where
+  toGridLine = id
+
+instance ToGridLine Integer where
+  -- | __NOTE:__ 'Integer' value of 0 is invalid.
+  toGridLine = Coordinate
+
+-- | @custom-ident@ value.
+instance ToGridLine CustomIdentGrid where
+  toGridLine x = GridLineCustomIdent x Nothing
+
+-- | @custom-ident@ value.
+instance ToGridLine String where
+  toGridLine = toGridLine . partialMkCustomIdentGrid . T.pack
+
+-- | Both @custom-ident@ and `Integer` values, provided as a pair.
+--
+-- __NOTE:__ 'Integer' value of 0 is invalid.
+instance ToGridLine (CustomIdentGrid, Integer) where
+  toGridLine (x, y) = GridLineCustomIdent x (Just y)
+
+-- | Both @custom-ident@ and `Integer` values, provided as a pair.
+--
+-- __NOTE:__ 'Integer' value of 0 is invalid.
+instance ToGridLine (String, Integer) where
+  toGridLine (x, y) = toGridLine (partialMkCustomIdentGrid $ T.pack x, y)
+
+-- | One or two @grid-line@ values.
+data GridLines2
+    -- | One @grid-line@ value.
+  = One2 OneGridLine
+    -- | Two @grid-line@ values.
+  | Two2 TwoGridLines
+
+class ToGridLines2 a where
+
+  -- | Convert the provided type to 'GridLines2' (one or two @grid-line@ values).
+  toGridLines2 :: a -> GridLines2
+
+-- | One @grid-line@ value.
+instance ToGridLines2 GridLine where
+  toGridLines2 = One2 . OneGridLine
+
+-- | One @grid-line@ value.
+instance ToGridLines2 OneGridLine where
+  toGridLines2 = One2
+
+-- | Two @grid-line@ values.
+instance ToGridLines2 TwoGridLines where
+  toGridLines2 = Two2
+
+-- | One or two @grid-line@ values.
+instance ToGridLines2 GridLines2 where
+  toGridLines2 = id
+
+-- | One 'Integer' value.
+--
+-- __NOTE:__ 'Integer' value of 0 is invalid.
+instance ToGridLines2 Integer where
+  toGridLines2 = toGridLines2 . toGridLine
+
+-- | One @custom-ident@ value.
+instance ToGridLines2 CustomIdentGrid where
+  toGridLines2 = toGridLines2 . toGridLine
+
+-- | One @custom-ident@ value.
+instance ToGridLines2 String where
+  toGridLines2 = toGridLines2 . toGridLine
+
+-- | One time both a @custom-ident@ and 'Integer' values, provided as a pair.
+--
+-- __NOTE:__ 'Integer' value of 0 is invalid.
+instance ToGridLines2 (CustomIdentGrid, Integer) where
+  toGridLines2 = toGridLines2 . toGridLine
+
+-- | One time both a @custom-ident@ and 'Integer' values, provided as a pair.
+--
+-- __NOTE:__ 'Integer' value of 0 is invalid.
+instance ToGridLines2 (String, Integer) where
+  toGridLines2 = toGridLines2 . toGridLine
+
+-- | One, two, three or four @grid-line@ values.
+data GridLines4
+
+    -- | One @grid-line@ value.
+  = One4 OneGridLine
+
+    -- | Two @grid-line@ values.
+  | Two4 TwoGridLines
+
+    -- | Three @grid-line@ values.
+  | Three4 ThreeGridLines
+
+    -- | Four @grid-line@ values.
+  | Four4 FourGridLines
+
+class ToGridLines4 a where
+  -- | Convert the provided type to 'GridLines4'
+  -- (one, two, three or four @grid-line@ values).
+  toGridLines4 :: a -> GridLines4
+
+-- | One @grid-line@ value.
+instance ToGridLines4 GridLine where
+  toGridLines4 = One4 . OneGridLine
+
+-- | One @grid-line@ value.
+instance ToGridLines4 OneGridLine where
+  toGridLines4 = One4
+
+-- | Two @grid-line@ values.
+instance ToGridLines4 TwoGridLines where
+  toGridLines4 = Two4
+
+-- | Three @grid-line@ values.
+instance ToGridLines4 ThreeGridLines where
+  toGridLines4 = Three4
+
+-- | Four @grid-line@ values.
+instance ToGridLines4 FourGridLines where
+  toGridLines4 = Four4
+
+-- | One, two, three or four @grid-line@ values.
+instance ToGridLines4 GridLines4 where
+  toGridLines4 = id
+
+-- | One 'Integer' value.
+--
+-- __NOTE:__ 'Integer' value of 0 is invalid.
+instance ToGridLines4 Integer where
+  toGridLines4 = toGridLines4 . toGridLine
+
+-- | One @custom-ident@ value.
+instance ToGridLines4 CustomIdentGrid where
+  toGridLines4 = toGridLines4 . toGridLine
+
+-- | One @custom-ident@ value.
+instance ToGridLines4 String where
+  toGridLines4 = toGridLines4 . toGridLine
+
+-- | One time both a @custom-ident@ and 'Integer' values, provided as a pair.
+--
+-- __NOTE:__ 'Integer' value of 0 is invalid.
+instance ToGridLines4 (CustomIdentGrid, Integer) where
+  toGridLines4 = toGridLines4 . toGridLine
+
+-- | One time both a @custom-ident@ and 'Integer' values, provided as a pair.
+--
+-- __NOTE:__ 'Integer' value of 0 is invalid.
+instance ToGridLines4 (String, Integer) where
+  toGridLines4 = toGridLines4 . toGridLine
+
+-- | One 'GridLine' value.
+newtype OneGridLine = OneGridLine GridLine
+
+-- | Two 'GridLine' values.
+data TwoGridLines = TwoGridLines GridLine GridLine
+
+-- | Three 'GridLine' values.
+data ThreeGridLines = ThreeGridLines GridLine GridLine GridLine
+
+-- | Four 'GridLine' values.
+data FourGridLines = FourGridLines GridLine GridLine GridLine GridLine
+
+-- | CSS @custom-ident@.
+--
+-- The data constructor is not exported. Use the 'partialMkCustomIdentGrid'
+-- smart constructor to create a 'CustomIdentGrid'.
+--
+-- === __Note__
+-- In CSS, some values for @custom-ident@ are invalid depending on the CSS
+-- property the @custom-ident@ is used with.
+-- Consequently, the @custom-ident@ is only for CSS grid.
+newtype CustomIdentGrid = CustomIdentGrid Text deriving (Eq, Ord, Read, Show)
+
+-- | Convert a 'CustomIdentGrid' to 'Text'.
+--
+-- === __Note__
+-- The function is defined on its own as the newtype constructor
+-- of 'CustomIdentGrid'is not exported.
+customIdentToText :: CustomIdentGrid -> Text
+customIdentToText (CustomIdentGrid x) = x
+
+-- | Create a 'CustomIdentGrid'.
+--
+-- __WARNING__: this function is partial. An error will be raised if:
+--
+-- * "span" is provided as a value (this is a reserved keyword in this context)
+-- * a number is provided as first character
+-- * __If__ a hyphen (-) is provided as first character:
+--
+--     ** a number is provided as second character
+--     ** a hyphen (-) is provided as second character.
+--
+-- === __Note__
+-- The above is a partial implementation of the CSS custom-ident naming rules.
+-- If you stick to the following charset @[a-zA-z0-9-_]@ the checks will be effective
+-- and your CSS custom-ident will be a valid one.
+-- On the other hand, the following will not be checked:
+--
+-- * character escaping (for example @\?@) or unicode
+-- * characters provided as hexadecimal number (for example @\0x03BB@)
+-- * characters outside of the above charset.
+--
+-- More information regarding this topic can be found on
+-- [mdm web docs_](https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident)
+partialMkCustomIdentGrid :: Text -> CustomIdentGrid
+partialMkCustomIdentGrid "span" = error "Custom-ident for a grid property cannot be named span"
+partialMkCustomIdentGrid txt = checkText
+  where
+    checkText = checkHead (fst unconsTxt)
+
+    checkHead :: Char -> CustomIdentGrid
+    checkHead c
+      | isNumber c = error "Custom-ident cannot start with a number"
+      | c == '-'   = checkSecond second
+      | otherwise  = CustomIdentGrid txt
+
+    checkSecond (Just s)
+      | s == '-' =
+          error "Custom-ident cannot start with two hyphens"
+      | isNumber s =
+          error "Custom-ident cannot start with a hyphen followed by a number"
+      | otherwise = CustomIdentGrid txt
+    checkSecond Nothing = CustomIdentGrid txt
+
+    unconsTxt = case T.uncons txt of
+      Nothing -> error "Custom-ident cannot be empty"
+      Just (f, r) -> (f, r)
+
+    second :: Maybe Char
+    second = fst <$> T.uncons (snd unconsTxt)
+
+-- $invalidValues
+--
+-- #partial#
+-- The below functions are partial. They will raise an error if
+-- provided with a @grid-line@ value which is:
+--
+-- * an 'Integer' value of 0
+-- * a pair with an 'Integer' component of value 0
+-- * a 'span_' function provided with an 'Integer' value of 0 or negative
+-- * a 'span_' function provided with a pair value with
+-- an 'Integer' component of 0 or negative.
+-- * an invalid @custom-ident@ value, see 'partialMkCustomIdentGrid'.
+
+-- | Property shorthand specifies a grid item's size and location
+-- within a grid.
+--
+-- One to four @grid-line@ values can be specified.
+-- Grid-line values must be separated by a '(//)' operator.
+--
+-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".
+--
+-- ==== __Examples__
+--
+-- The below examples assume that the @ExtendedDefaultRules@ GHC language
+-- pragma is enabled. See above "Clay.Grid#pragma".
+--
+-- > gridArea (auto :: GridLine)
+--
+-- > gridArea "somegridarea"
+--
+-- > gridArea $ ("somegridarea", 4) // ("someothergridarea", 2)
+--
+-- > gridArea $ 1 // 3 // 4
+gridArea :: ToGridLines4 a => a -> Css
+gridArea x = key "grid-area" (partialToGridLines4 x)
+
+-- | Property shorthand specifies a grid item's size and location
+-- within a grid column.
+--
+-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".
+--
+-- ==== __Examples__
+--
+-- The below examples assume that the @ExtendedDefaultRules@ GHC language
+-- pragma is enabled. See above "Clay.Grid#pragma".
+--
+-- > gridColumn (auto :: GridLine)
+--
+-- > gridColumn $ span_ 3
+--
+-- > gridColumn $ span_ ("somegridarea", 5)
+--
+-- > gridColumn $ span_ 3 // 6
+gridColumn :: ToGridLines2 a => a -> Css
+gridColumn x = key "grid-column" (partialToGridLines2 x)
+
+-- | Property specifies a grid item's start position within the grid column.
+--
+-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".
+--
+-- ==== __Examples__
+--
+-- The below examples assume that the @ExtendedDefaultRules@ GHC language
+-- pragma is enabled. See above "Clay.Grid#pragma".
+--
+-- > gridColumnStart (inherit :: GridLine)
+--
+-- > gridColumnStart 2
+--
+-- > gridColumnStart ("somegridarea", 4)
+--
+-- > gridColumnStart $ span_ ("somegridarea", 5)
+gridColumnStart :: ToGridLine a => a -> Css
+gridColumnStart x = key "grid-column-start" (partialToGridLine x)
+
+-- | Property specifies a grid item's end position within the grid column.
+--
+-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".
+--
+-- ==== __Examples__
+--
+-- The below examples assume that the @ExtendedDefaultRules@ GHC language
+-- pragma is enabled. See above "Clay.Grid#pragma".
+--
+-- > gridColumnEnd (initial :: GridLine)
+--
+-- > gridColumnEnd 2
+--
+-- > gridColumnEnd "somegridarea"
+--
+-- > gridColumnEnd $ span_ "somegridarea"
+gridColumnEnd :: ToGridLine a => a -> Css
+gridColumnEnd x = key "grid-column-end" (partialToGridLine x)
+
+-- | Property shorthand specifies a grid item's size and location
+-- within a grid row.
+--
+-- One or two @grid-line@ values can be specified.
+-- @grid-line@ values must be separated by a '(//)' operator.
+--
+-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".
+--
+-- ==== __Examples__
+--
+-- The below examples assume that the @ExtendedDefaultRules@ GHC language
+-- pragma is enabled. See above "Clay.Grid#pragma".
+--
+-- > gridRow (unset :: GridLine)
+--
+-- > gridRow $ span_ 3
+--
+-- > gridRow $ span_ 3 // 6
+--
+-- > gridRow $ span_ ("somegridarea", 5) // span_ 2
+gridRow :: ToGridLines2 a => a -> Css
+gridRow x = key "grid-row" (partialToGridLines2 x)
+
+-- | Property specifies a grid item's start position within the grid row.
+--
+-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".
+--
+-- ==== __Examples__
+--
+-- The below examples assume that the @ExtendedDefaultRules@ GHC language
+-- pragma is enabled. See above "Clay.Grid#pragma".
+--
+-- > gridRowStart (initial :: GridLine)
+--
+-- > gridRowStart (-2)
+--
+-- > gridRowStart $ span_ "somegridarea"
+--
+-- > gridRowStart "somegridarea"
+gridRowStart :: ToGridLine a => a -> Css
+gridRowStart x = key "grid-row-start" (partialToGridLine x)
+
+-- | Property specifies a grid item's end position within the grid row.
+--
+-- __WARNING:__ this function is partial. See above "Clay.Grid#partial".
+--
+-- ==== __Examples__
+--
+-- The below examples assume that the @ExtendedDefaultRules@ GHC language
+-- pragma is enabled. See above "Clay.Grid#pragma".
+--
+-- > gridRowEnd (auto :: GridLine)
+--
+-- > gridRowEnd (-2)
+--
+-- > gridRowEnd ("somegridarea", 4)
+--
+-- > gridRowEnd $ span_ 3
+gridRowEnd :: ToGridLine a => a -> Css
+gridRowEnd x = key "grid-row-end" (partialToGridLine x)
+
+class Slash a r | a -> r where
+  -- | `/` CSS operator.
+  -- Separates @grid-line@ values.
+  (//) :: ToGridLine b => a -> b -> r
+
+instance Slash GridLine TwoGridLines where
+  x // y = TwoGridLines x (toGridLine y)
+
+instance Slash Integer TwoGridLines where
+  x // y = TwoGridLines (toGridLine x) (toGridLine y)
+
+instance Slash CustomIdentGrid TwoGridLines where
+  x // y = TwoGridLines (toGridLine x) (toGridLine y)
+
+instance Slash String TwoGridLines where
+  x // y = TwoGridLines (toGridLine x) (toGridLine y)
+
+instance Slash (CustomIdentGrid, Integer) TwoGridLines where
+  x // y = TwoGridLines (toGridLine x) (toGridLine y)
+
+instance Slash (String, Integer) TwoGridLines where
+  x // y = TwoGridLines (toGridLine x) (toGridLine y)
+
+instance Slash TwoGridLines ThreeGridLines where
+  (TwoGridLines xx xy) // y = ThreeGridLines xx xy (toGridLine y)
+
+instance Slash ThreeGridLines FourGridLines where
+  (ThreeGridLines xx xy xz) // y = FourGridLines xx xy xz (toGridLine y)
+
+class ToSpan a where
+
+  -- | @span@ CSS keyword, contributes to the grid item's placement.
+  span_ :: a -> GridLine
+
+-- | Contributes the nth grid line to the grid item's placement.
+--
+-- __NOTE:__ negative 'Integer' or 0 values are invalid.
+instance ToSpan Integer where
+  span_ x = Span Nothing (Just x)
+
+-- | One line from the provided name is counted.
+instance ToSpan String where
+  span_ x = Span (Just . partialMkCustomIdentGrid $ T.pack x) Nothing
+
+-- | Nth lines from the provided name are counted.
+--
+-- __NOTE:__ negative 'Integer' or 0 values are invalid.
+instance ToSpan (String, Integer) where
+  span_ (x, y) = Span (Just . partialMkCustomIdentGrid $ T.pack x) (Just y)
+
+-- | Keyword indicating that the property contributes nothing
+-- to the grid item's placement.
+instance Com.Auto GridLine where
+  auto = OtherGridLine $ value ("auto" :: Text)
+
+-- | Keyword `inherit` applied to a 'GridLine'.
+instance Com.Inherit GridLine where
+  inherit = OtherGridLine $ value ("inherit" :: Text)
+
+-- | Keyword `initial` applied to a 'GridLine'.
+instance Com.Initial GridLine where
+  initial = OtherGridLine $ value ("initial" :: Text)
+
+-- | Keyword `unset` applied to a 'GridLine'.
+instance Com.Unset GridLine where
+  unset = OtherGridLine $ value ("unset" :: Text)
+
+-- | Convertion of 'GridLine' to 'Clay.Property.Value'.
+instance Val GridLine where
+  value (OtherGridLine val)       = val
+  value (Coordinate x)            = value x
+  value (GridLineCustomIdent x y) =
+    value $ customIdentToText x <> foldMap ((" " <>) . tshow) y
+  value (Span x y) =
+    value $ "span" <> foldMap ((" " <>)
+    . customIdentToText) x <> foldMap ((" " <>) . tshow) y
+
+instance Val OneGridLine where
+  value (OneGridLine x) = value x
+
+instance Val TwoGridLines where
+  value (TwoGridLines x y) =
+    value x <> value (" / " :: Text) <> value y
+
+instance Val ThreeGridLines where
+  value (ThreeGridLines x y z) =
+       value x
+    <> value (" / " :: Text) <> value y
+    <> value (" / " :: Text) <> value z
+
+instance Val FourGridLines where
+  value (FourGridLines xx xy xz yx) =
+       value xx
+    <> value (" / " :: Text) <> value xy
+    <> value (" / " :: Text) <> value xz
+    <> value (" / " :: Text) <> value yx
+
+instance Val GridLines2 where
+  value (One2 x) = value x
+  value (Two2 x) = value x
+
+instance Val GridLines4 where
+  value (One4 x)   = value x
+  value (Two4 x)   = value x
+  value (Three4 x) = value x
+  value (Four4 x)  = value x
+
+-- | Private partial function checking a 'GridLine'.
+--
+-- An error is raised when:
+-- - An 'Integer' value of 0 is provided.
+-- - A negative 'Integer' value is provided for a 'Span' constructor.
+--
+-- Otherwise, the initially provided 'GridLine' value is returned.
+partialCheckGridLine :: GridLine -> GridLine
+partialCheckGridLine gridLine = case gridLine of
+  Coordinate 0                   -> errorValue 0
+  GridLineCustomIdent _ (Just 0) -> errorValue 0
+  s@(Span _ (Just n))            -> if n < 1
+                                    then errorValue n
+                                    else s
+  _                              -> gridLine
+  where
+    errorValue n = error ("Value " ++ show n ++ " is invalid")
+
+-- | Private partial function checking 'OneGridLine'.
+--
+-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.
+partialCheckOneGridLine :: OneGridLine -> OneGridLine
+partialCheckOneGridLine (OneGridLine gridLine) =
+  OneGridLine (partialCheckGridLine gridLine)
+
+-- | Private partial function checking 'TwoGridLines'.
+--
+-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.
+partialCheckTwoGridLines :: TwoGridLines -> TwoGridLines
+partialCheckTwoGridLines (TwoGridLines gridLine1 gridLine2) =
+  TwoGridLines (partialCheckGridLine gridLine1) (partialCheckGridLine gridLine2)
+
+-- | Private partial function checking 'ThreeGridLines'.
+--
+-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.
+partialCheckThreeGridLines :: ThreeGridLines -> ThreeGridLines
+partialCheckThreeGridLines (ThreeGridLines gridLine1 gridLine2 gridLine3) =
+  ThreeGridLines
+    (partialCheckGridLine gridLine1)
+    (partialCheckGridLine gridLine2)
+    (partialCheckGridLine gridLine3)
+
+-- | Private partial function checking 'FourGridLines'.
+--
+-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.
+partialCheckFourGridLines :: FourGridLines -> FourGridLines
+partialCheckFourGridLines
+  (FourGridLines gridLine1 gridLine2 gridLine3 gridLine4) =
+    FourGridLines
+      (partialCheckGridLine gridLine1)
+      (partialCheckGridLine gridLine2)
+      (partialCheckGridLine gridLine3)
+      (partialCheckGridLine gridLine4)
+
+-- | Private partial function converting its argument to 'GridLine'.
+--
+-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.
+partialToGridLine :: ToGridLine a => a -> GridLine
+partialToGridLine = partialCheckGridLine . toGridLine
+
+-- | Private partial function converting its argument to 'GridLines2'.
+--
+-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.
+partialToGridLines2 :: ToGridLines2 a => a -> GridLines2
+partialToGridLines2 x = partialGridLine' gridLines
+  where
+    gridLines = toGridLines2 x
+    partialGridLine' (One2 gl) = One2 (partialCheckOneGridLine gl)
+    partialGridLine' (Two2 gl) = Two2 (partialCheckTwoGridLines gl)
+
+-- | Private partial function converting its argument to 'GridLines4'.
+--
+-- An error is raised if an invalid value is found, see 'partialCheckGridLine'.
+partialToGridLines4 :: ToGridLines4 a => a -> GridLines4
+partialToGridLines4 x = partialGridLine' gridLines
+  where
+    gridLines = toGridLines4 x
+    partialGridLine' (One4 gl)   = One4 (partialCheckOneGridLine gl)
+    partialGridLine' (Two4 gl)   = Two4 (partialCheckTwoGridLines gl)
+    partialGridLine' (Three4 gl) = Three4 (partialCheckThreeGridLines gl)
+    partialGridLine' (Four4 gl)  = Four4 (partialCheckFourGridLines gl)
+
+-- | Private utility function to show 'Text' instead of 'String'.
+tshow :: Show a => a -> Text
+tshow = T.pack . show
diff --git a/src/Clay/Pseudo.hs b/src/Clay/Pseudo.hs
--- a/src/Clay/Pseudo.hs
+++ b/src/Clay/Pseudo.hs
@@ -1,9 +1,11 @@
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE FlexibleInstances #-}
 module Clay.Pseudo where
 
 import Data.Text (Text)
 
-import Clay.Render (renderSelector)
+import Clay.Render (renderSelector, renderRefinement)
 import Clay.Selector
 
 import qualified Data.Text.Lazy as Lazy
@@ -64,5 +66,19 @@
 nthLastOfType n = func "nth-last-of-type" [n]
 nthOfType     n = func "nth-of-type"      [n]
 
-not :: Selector -> Refinement
-not r = func "not" [Lazy.toStrict (renderSelector r)]
+-- | The 'not' pseudo selector can be applied to both a 'Refinement'
+--
+-- > input # not checked
+-- 
+-- or a 'Selector'
+--
+-- > not p
+
+class Not a where
+  not :: a -> Refinement
+
+instance Not Selector where
+  not r = func "not" [Lazy.toStrict (renderSelector r)]
+
+instance Not Refinement where
+  not r = func "not" (Lazy.toStrict <$> renderRefinement r)
diff --git a/src/Clay/Render.hs b/src/Clay/Render.hs
--- a/src/Clay/Render.hs
+++ b/src/Clay/Render.hs
@@ -8,6 +8,7 @@
 , putCss
 , renderWith
 , renderSelector
+, renderRefinement
 , withBanner
 )
 where
@@ -119,6 +120,10 @@
 
 renderSelector :: Selector -> Lazy.Text
 renderSelector = toLazyText . selector compact
+
+-- | Render a CSS `Refinement`.
+renderRefinement :: Refinement -> [Lazy.Text]
+renderRefinement r = toLazyText . predicate <$> unFilter r
 
 -------------------------------------------------------------------------------
 
