Media object

Introduction

A flexbox enabled version of @Stubbornella's media object

GitHub page

The media object, introduced by Nichole Sullivan, is a layout abstraction for placing fixed width content and fluid content side by side.

JigSass Media is a flexbox enabled implementation of the original, with optional fallback (See Configuration).

Installation

Using npm:

npm i -S jigsass-objects-media

Usage

First, import JigSass Objects Media to your main stylesheet:

@import 'path/to/jigsass-objects-media/scss/index';

And optionally reconfigure the defaults to your liking.

Like all other JigSass modules, JigSass Button does not automatically generate any CSS when imported. In order to use its classes, you would have to first explicitly indicate your intention to use them by enabling their generation in the associated configurations map, leaving us only with CSS we need:

All JigSass Media classes are responsive-enabled, using JigSass MQ and the breakpoints defined in the $jigsass-breakpoints variable.

Based on enabled selectors in the configuration map, responsive modifiers are generated according to the following logic:

.o-media[--modifier][-[-from-{breakpoint-name}][-until-{breakpoint-name}][-misc-{breakpoint-name}]]

So, assuming the medium, large and landscape breakpoints are defined in $jigsass-breakpoints as 600px, 1024px and (orientation: landscape) respectively,

$jigsass-media-obj-conf: (
  no-breakpoint: (
    bottom: true,
  ),
  until-medium: (
    bottom: true,
  ),
  from-large-when-landscape: (
    bottom: true,
  ),
)

will generate the following classes:

  • .o-media--bottom, which is not limited to any media-query.
  • .o-media--bottom--until-medium, which will be in effect at (max-width: 37.49em) and will override styles in the default class until that point.
  • .o-media-bottom--from-large-when-landscape, which will go into effect at (min-width: 64em) and (orientation: landscape) and will override styles in the default class under these conditions.

At its simplest form, the media object is simply a fixed element next to a fluid element, filling up available space:

<div class='u-cf o-media'>
  <figure class='o-media__fig'>
    <div class='[ fpo fpo--b fpo--fig ]'></div>
  </figure>
  <div class='o-media__content fpo'>
    <p style='text-align: center'<strong>.o-media__content</strong></p>
  </div>
</div>

Like all JigSass object, JigSass Media is responsive-enabled, and an instance may be set to stack vertically by using responsive modifier classes on the container (resize window to see object stacking and unstacking):

<div class='u-cf [ o-media--from-small-until-medium o-media--from-large ]'>
  <figure class='o-media__fig'>
    <div class='[ fpo fpo--b fpo--fig ]'></div>
  </figure>
  <div class='o-media__content fpo'>
    <p style='text-align: center'>
      <strong>Media object only from small until medium and  from large on.</strong>
    </p>
  </div>
</div>

One of the media object's key features, is that it can be endlessly nested:

<! -- First level -->
<div class='u-cf o-media'>
  <figure class='o-media__fig'>
    <div class='[ fpo fpo--b fpo--fig ]'></div>
  </figure>
  <div class='o-media__content fpo'>
    <span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</span>

    <! -- Second level -->
    <div class='u-cf o-media--from-medium'>
      <figure class='o-media__fig'><div class='[ fpo fpo--b fpo--fig ]'></div></figure>
      <div class='o-media__content fpo fpo--c'>
        <span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim venia.</span>

        <! -- Third level -->
        <div class='u-cf o-media--from-medium'>
          <figure class='o-media__fig'><div class='[ fpo fpo--b fpo--fig ]'></div></figure>
          <div class='o-media__content fpo'>
            <span>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit.</span>

            <! -- fourth level -->
            <div class='u-cf o-media--from-large'>
              <figure class='o-media__fig'><div class='[ fpo fpo--b fpo--fig ]'></div></figure>
              <div class='o-media__content fpo fpo--c'>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
              </div>
            </div>
            <div class='u-cf o-media--from-large o-media--rev--from-large'>
              <figure class='o-media__fig'><div class='[ fpo fpo--b fpo--fig ]'></div></figure>
              <div class='o-media__content fpo fpo--d'>
                <strong>Media objects can also be reversed</strong> Media Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
              </div>
            </div>
          </div>
        </div>
      </div>
  </div>
</div>

JigSass Media also offers vertical alignment modifiers (middle, bottem) and a reverse modifier.

License: MIT

CSS Outpout

By default, JigSass Media does not generate any CSS output when imported into a stylesheet. CSS output must be enabled on a per-selector basis, inside the dedicated configuration map:

$jigsass-media-obj-config

Type: Map

Configuration map for enabling generation of media object and modifier classes.

Default:

$jigsass-media-obj-conf: (
  no-breakpoint: (
    no-modifier: false,
    middle: false,
    bottom: false,
    rev: false,
  ),
);

Example:

$jigsass-media-obj-conf: (
  no-breakpoint: (
    no-modifier: true,  // Enables generation of the `.o-media`
                        // class outside of any media query.
    foo: true,          // Enables generation of the `.o-media--foo`
                        // modifier class outside of any media query.
  ),
  from-<bp-name>: (
    no-modifier: true,  // Enables generation of the `.o-media--from-<bp-name>`
                        // class inside a min-width media query
                        // defined ins `$jigsass-breakpoints.length`.
    foo: true,          // Enables generation of the `.o-media--foo--from-<bp-name>`
                        // class inside a min-width media query
                        // defined ins `$jigsass-breakpoints.length`.
  ),
  until-<bp-name>: (
    no-modifier: true,  // Enables generation of the `.o-media--until-<bp-name>`
                        // class inside a max-width media query
                        // defined ins `$jigsass-breakpoints.length`.
  foo: true,          // Enables generation of the `.o-media--foo--until-<bp-name>`
                        // class inside a max-width media query
                        // defined ins `$jigsass-breakpoints.length`.
  ),
  when-<bp-name>: (
    no-modifier: true,  // Enables generation of the `.o-media--when-<bp-name>`
                        // class inside a misc media query
                        // defined ins `$jigsass-breakpoints.features`.
    foo: true,          // Enables generation of the `.o-media--foo--when-<bp-name>`
                        // class inside a misc media query
                        // defined ins `$jigsass-breakpoints.features`.
  ),
  from-<bp-name>-until-<bp-name>: (...);
  from-<bp-name>-when-<bp-name>: (...);
  until-<bp-name>-when-<bp-name>: (...);
  from-<bp-name>-until-<bp-name>-when-<bp-name>: (...);
);

Configuration

JigSass Media allows for some modification through tweaking configuration variable. To override the default values, predefine them to your own needs before importing this file.

Flexbox support

$jigsass-media-flexbox

Type: Boolean

Determines if flexbox should be enabled, where relevant

Default: true

Flexbox Fallback

$jigsass-media-flexbox-fallback

Type: Boolean or String

Determines if flexbox fallback should be included and the qualifier class to use if so (e.g, .no-flexbox when using Modernizr defaults)

Set to false to disable fallback altogether, and to a class-name (sans the leading .) used as the qualifier class if fallback is desirable.

Default: 'no-flexbox'

Base

A flexbox enabled implementation of Nicole sullivan's media object with optional fallback

Used to create a container with a fixed-width element at one end, and a fluid width container next to it.

  <div class='u-cf o-media'>
    <figure class='o-media__fig'>
      <div class='[ fpo fpo--b fpo--fig ]'></div>
    </figure>
    <div class='o-media__content fpo'>
      <p style='text-align: center'<strong>.o-media__content</strong></p>
    </div>
  </div>

A media object may be set to stack vertically by using responsive modifier classes on the container (resize window to see object stacking and unstacking):

  <div class='u-cf [ o-media--from-small-until-medium o-media--from-large ]'>
    <figure class='o-media__fig'>
      <div class='[ fpo fpo--b fpo--fig ]'></div>
    </figure>
    <div class='o-media__content fpo'>
      <p style='text-align: center'>
        <strong>Media object only from small until medium and  from large on.</strong>
      </p>
    </div>
  </div>

CSS Output

  // When flexbox is enabled
  .o-media {
    display: flex;
  }
  .o-media > .o-media__content {
    flex: 1 1 auto;
  }


  // When flexbox fallback is enabled
  .u-clearfix { ... }
  .no-flexbox .o-media {
    display: block;
  }

  .no-flexbox .o-media > .o-media__fig {
    @include jigsass-bidi(float, start);
    display: block;
  }

  .no-flexbox .o-media > .o-media__fig img {
    vertical-align: top;
  }

  .no-flexbox .o-media > .o-media__content {
    display: table-cell;
    max-width: 100%;
    width: 100000px;
  }


  // When flexbox is disabled
  .u-clearfix { ... }

  .o-media {
    display: block;
  }

  .o-media > .o-media__fig {
    @include jigsass-bidi(float, start);
    display: block;
  }

  .o-media > .o-media__fig img {
    vertical-align: top;
  }

  .o-media > .o-media__content {
    display: table-cell;
    max-width: 100%;
    width: 100000px;
  }

Middle Aligned

A media object with items aligned to the vertical middle.

  <div class='u-cf [ o-media o-media--middle ]'>
    <figure class='o-media__fig'>
      <div class='[ fpo fpo--b fpo--fig ]'></div>
    </figure>
    <div class='o-media__content fpo'>
      <p style='text-align: center'<strong>.o-media__content</strong></p>
    </div>
  </div>

Can also be applying responsively:

  <div class='u-cf [ o-media o-media--middle--from-small-until-medium o-media--middle--from-large ]'>
    <figure class='o-media__fig'>
      <div class='[ fpo fpo--b fpo--fig ]'></div>
    </figure>
    <div class='o-media__content fpo'>
      <p style='text-align: center'>
        <strong>Middle aligned only from small until medium and  from large on.</strong>
      </p>
    </div>
  </div>

CSS Output

  // When flexbox is enabled
  .o-media--middle { align-items: center; }

  // When flexbox fallback is enabled
  .no-flexbox .o-media--middle { display: table; }

  .no-flexbox .o-media--middle > .o-media__fig {
    display: inline-block;
    float: none;
  }
  .no-flexbox .o-media--middle > .o-media__fig,
  .no-flexbox .o-media--middle > .o-media__content {
    vertical-align: middle;
  }


  // When flexbox is disabled
  .o-media--middle { display: table; }

  .o-media--middle > .o-media__fig {
    display: inline-block;
    float: none;
  }
  .o-media--middle > .o-media__fig,
  .o-media--middle > .o-media__content {
    vertical-align: middle;
  }

Bottom Aligned

A media object with items aligned to the vertical bottom.

  <div class='u-cf [ o-media o-media--bottom ]'>
    <figure class='o-media__fig'>
      <div class='[ fpo fpo--b fpo--fig ]'></div>
    </figure>
    <div class='o-media__content fpo'>
      <p style='text-align: center'<strong>.o-media__content</strong></p>
    </div>
  </div>

Can also be applying responsively:

  <div class='u-cf [ o-media o-media--bottom--from-small-until-medium o-media--bottom--from-large ]'>
    <figure class='o-media__fig'>
      <div class='[ fpo fpo--b fpo--fig ]'></div>
    </figure>
    <div class='o-media__content fpo'>
      <p style='text-align: center'>
        <strong>Bottom aligned only from small until medium and  from large on.</strong>
      </p>
    </div>
  </div>

CSS Output

  // When flexbox is enabled
  .o-media--bottom { align-items: flex-end; }

  // When flexbox fallback is enabled
  .no-flexbox .o-media--bottom { display: table; }

  .no-flexbox .o-media--bottom > .o-media__fig {
    display: inline-block;
    float: none;
  }
  .no-flexbox .o-media--bottom > .o-media__fig,
  .no-flexbox .o-media--bottom > .o-media__content {
    vertical-align: bottom;
  }


  // When flexbox is disabled
  .o-media--bottom { display: table; }

  .o-media--bottom > .o-media__fig {
    display: inline-block;
    float: none;
  }
  .o-media--bottom > .o-media__fig,
  .o-media--bottom > .o-media__content {
    vertical-align: bottom;
  }

Reversed

A media object in which elements are displayed opposite of their position in the source order.

  <div class='u-cf [ o-media o-media--rev ]'>
    <figure class='o-media__fig'>
      <div class='[ fpo fpo--b fpo--fig ]'></div>
    </figure>
    <div class='o-media__content fpo'>
      <p style='text-align: center'<strong>I am actually second in the source order</strong></p>
    </div>
  </div>

Can also be applying responsively:

  <div class='u-cf [ o-media o-media--rev--from-small-until-medium o-media--rev--from-large ]'>
    <figure class='o-media__fig'>
      <div class='[ fpo fpo--b fpo--fig ]'></div>
    </figure>
    <div class='o-media__content fpo'>
      <p style='text-align: center'>
        <strong>Reversed only from small until medium and  from large on.</strong><br />
        I am actually second in the dource order...
      </p>
    </div>
  </div>

CSS Output

  // When flexbox is enabled
  .o-media--rev { flex-direction: row-reverse; }

  // When flexbox fallback is enabled
  .no-flexbox .o-media--rev { direction: (ltr|rtl); }
  .no-flexbox .o-media--rev > * { direction: (rtl|ltr); }

  // When flexbox is disabled
  .o-media--rev { direction: (ltr|rtl); }
  .o-media--rev > * { direction: (rtl|ltr); }

Clearfix Util

Introduction

Force an element to clear its floated child element and prevent its layout from collapsing.

Installation

Using npm:

npm i -S jigsass-utils-clearfix

Usage

Import JigSass Utils Clearfix into your main scss file near its very end, together with all other utilities (utilities should always be the last to be imported).

@import 'path/to/jigsass-utils-clearfix/scss/index';

Importing the file will not create any styles by itself. You would need to indicate that the .u-cf class should actually be generated in each component or object it is used in:

// _c.foo.scss
.foo {
  @include jigsass-util(u-cf);

  ...
}
// _c.bar.scss
.bar {
  @include jigsass-util(u-cf);

  ...
}
// _c.baz.scss
.baz {
  @include jigsass-util(u-cf);

  ...
}

Doing so helps us a great deal with portability, as no matter where we import component or object partials, the correct utility classes will be generated. Think of it as a poor man's dependency management.

Developer communication is also assisted by including "dependencies" wherever they are required, as anyone going through a partial, can easily understand how it should be marked up with just a glance.

As far as bloat goes, just don't worry about it - the actual styles will only be generated once, at the location in the cascade where the Jigsass Clearfix partial was imported into the main file: