Mixin for Offset Positioning

If there is one shorthand CSS dramatically misses, it is the one making it possible to define the position property, as well as the four offset properties (top, right, bottom, left).

Fortunately, this is typically something that can be solved with a CSS preprocessor such as Sass. We only have to build a simple mixin to save us from declaring the 5 properties manually.

/// Shorthand mixin for offset positioning
/// @param {String} $position - Either `relative`, `absolute` or `fixed`
/// @param {Length} $top [null] - Top offset
/// @param {Length} $right [null] - Right offset
/// @param {Length} $bottom [null] - Bottom offset
/// @param {Length} $left [null] - Left offset
@mixin position($position, $top: null, $right: null, $bottom: null, $left: null) {
  position: $position;
  top: $top;
  right: $right;
  bottom: $bottom;
  left: $left;
}

Now the thing is we rely on named arguments when using this mixin to avoid having to set them all when only one or two are desired. Consider the following code:

.foo {
  @include position(absolute, $top: 1em, $left: 50%);
}

... which compiles into:

.foo {
  position: absolute;
  top: 1em;
  left: 50%;
}

Indeed, Sass never outputs a property that has a value of null.

Simplifying the API

We could move the type of position to the mixin name instead of having to define it as first argument. To do so, we need three extra mixins that will serve as aliases to the `position` mixin we just defined.

/// Shorthand mixin for absolute positioning
/// Serves as an alias for `position(absolute, ...)`
/// @param {Arglist} $args - Offsets
/// @require {mixin} position
@mixin absolute($args...) {
  @include position(absolute, $args...);
}

/// Shorthand mixin for relative positioning
/// Serves as an alias for `position(relative, ...)`
/// @param {Arglist} $args - Offsets
/// @require {mixin} position
@mixin relative($args...) {
  @include position(relative, $args...);
}

/// Shorthand mixin for fixed positioning
/// Serves as an alias for `position(fixed, ...)`
/// @param {Arglist} $args - Offsets
/// @require {mixin} position
@mixin fixed($args...) {
  @include position(fixed, $args...);
}

Rewriting our previous example:

.foo {
  @include absolute($top: 1em, $left: 50%);
}

Going further

If you want a syntax closer to the one proposed by Nib (Stylus' framework), I recommend you have a look at this article.

.foo {
  @include absolute(top 1em left 50%);
}

Comments

  1. User Avatar
    Federico Brigante
    Permalink to comment#

    What problem are we trying to solve? Keystrokes count? Use Hayaku or Emmet.io

    @include position(absolute, $top: 1em, $left: 50%);
    

    is done by typing:

    pa[tab]t1e[tab]l50p[tab]
    

    The output is plain CSS and you got there with 12 plain keystrokes and no need for a mixin to maintain.

    • User Avatar
      Gerben van Dijk
      Permalink to comment#

      In my opinion mixin maintainance is a non-argument – as it enables you to be more flexible in the future.

      Case:

      It might be that there will be a new css property or so, related to this specific situation.
      When using a mixin, you’d only have to add that line to the mixin, in some situations add instances of that mixin
      In my opinion, the above is certainly easier to locate all places where a certain mixin is used then to trace back all places in your code where you use the technique without a mixin.

      So, actually a maintanance plus – I guess you could always use Emmet or something similar but that kind of defeats the purpose of a mixin. I agree that we don’t need a mixin for everything, and I can see that this one might be too simple for some to use a mixin for. But I can also see that ease of use is enough of a use case for most people :)

    • User Avatar
      Larry Gerndt
      Permalink to comment#

      wow, thanks for steering me away from Hayaku or Emmet.io! I mean seriously, that syntax is nearing RegEx madness.

    • User Avatar
      Pavel
      Permalink to comment#

      Larry… you don’t use auto-completions in your text editor? Really?

      That’s not syntax… it’s a sequence of keystrokes. You type that and get plain CSS

      Feel free not to save time by not using the Emmet that Chris himself recommends

Submit a Comment

Posting Code

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.

icon-anchoricon-closeicon-emailicon-linkicon-logo-staricon-menuicon-nav-guideicon-searchicon-staricon-tag