One of the more cumbersome things to write in CSS is position offsets.

  .cover-something {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}

Have you ever had to write something like that? Some of us even try to sort our properties alphabetically.

  .cover-something {
    bottom: 0;
    left: 0;
    position: absolute;
    right: 0;
    top: 0;
}

Yikes! Once we stuff more properties into that rule, whatever concept we had hoped to convey is probably lost.


This weekend, I was pleasantly surprised to see the CSSWG tackling this issue.

We need a name for a shorthand for the top/left/bottom/right properties. Ideas?
@csswg

Shorthands? I love shorthands! Immediately, there was a great suggestion to extend the position property.

1. Make position a shortcut, e.g. `position: absolute 1px 7px 9px 1px`. 2. Add long name for current position (e.g. position-mode).
@ashmind

The gist of that means position would accept clockwise values, just like margin and padding. This means shorthand values like:

  .cover-something {
    position: absolute 0;
}

Pretty clean, huh! However, the CSSWG reminded us of one very important reason this can’t ever happen.

We can't make an existing property a shorthand for a property it doesn't currently shorthand, because then it would reset that property.
@csswg

Good grief. Very well, the next suggestion was to use a new property — offset.

  .cover-something {
    offset: 0;
    position: absolute;
}

But that bubble was also burst pretty quickly.

Issue is that the current proposal, 'offset', conflicts with the properties in https://drafts.fxtf.org/motion/
@csswg

Ugh. Fine! What if we hypenate it?

box-offset
@valtlai

I really like this.

With box-offset, we might have something to work with. Well done, everyone!


But we’re not out of the woods yet. Jake Archibald reminded us of a weakness with those clock-wise shorthand properties.

Put it this way: I frequently set top & left together. I sometimes set all to 0, but aside from that, I rarely want t/b l/r to be the same.
@jaffathecake

Setting the top and left properties would mean developers choose between writing 2 longhand properties or resetting all offsets to use the shorthand.

  .inset-from-the-top-left {
    offset: 10px auto auto 10px;
    position: absolute;
}

That doesn’t look super great. Shorthands overwrite everything, which means any previous right or bottom properties would have to be redeclared. Also, if top and left are meant to convey the same value, the visual separation means that concept is somewhat lost.

Still, these are all problems we already deal with when using margin or padding.


I think we could define a non-destructive shorthand that preserves offset relationships. It might even let us use position.

The secret lies in CSS Grids.

  .container {
    grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
    grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
}

Those words in the brackets represent something called “custom identifiers”. So, what if we applied custom identifiers to position offsets?

  .inset-from-the-top-left {
    position: absolute [top left] 0;
}

  .cover-everything {
    position: absolute [top right bottom left] 0;
}

Pretty clear, I think. Still, that second example is not zesty. Maybe we could just omit the names when writing all of them.

  .cover-everything {
    position: absolute [] 0;
}

And why bother with writing out full names anyway?

  .inset-from-the-top-left {
    position: absolute [tl] 0;
}

That looks useful.

And remember, none of this requires us to re-use the position property. This idea could still work with box-offset!


Okay, nerd alert. I don’t know about you, but when I try to imagine future web standards I also try to apply everything I know about other emerging standards.

For instance, I understand we’re trying to get away from the whole left and right thing and instead call it inline start and inline end. Similarly, top and bottom are block start and block end. Well, good news — our identifier pattern still works!

  .inset-from-the-top-left {
    position: absolute [block-start inline-start] 0;
}

Or why not:

  .inset-from-the-top-left {
    position: absolute [start] 0;
}

Or hey why not:

  .inset-from-the-top-left {
    position: absolute [s] 0; /* aww yiss */
}

All together, if we adopt this block/inline + start/end syntax, we get the following identifiers:

Position Offset Identifier Legacy Properties
inline i left,right
block b top,bottom
start s left,top
end e right,bottom
inline start is left,
inline end ie right
block start bs top
block end be bottom
inline start + block isb left,top,bottom
inline end + block ieb right,top,bottom
inline + block start ibs left,right,top
inline + black end ibe left,right,bottom
all offsets (empty) left,right,top,bottom

Do you think this could solve real problems? What sorts of problems do you think it might create?