Loop Config Map

Simplify the use of variables and the configuration of the framework.

Because going through a single variables.scss file can be tedious and remembering every names is becoming a challenge, Loop offers a single config map.

Every data are set inside the variable $ooLoop

$ooLoop: (
  // properties
);

# Global Properties

The global properties are data to be refered to within your configuration to avoid duplicating them.

breakpoints

Map - Available breakpoints in your project.

breakpoints: (
  xs: 30em,     // 480px
  sm: 37.500em, // 600px
  md: 60em,     // 960px
  lg: 80em,     // 1280px
  xl: 120em,    // 1980px
),

screens

List - Set of responsive screens being globally used.

screens: (sm, md, lg),

palette

Map - Available colors in your project.

palette: (
  'primary': #0ea7d6,
  'secondary': #959595,
),

# Props Property

The props property is reserved to pass a map of CSS properties within the config.
The properties are written in css kebab-case.

... : (
  props: (
    font-size: 1.6em,
    line-height: 1.375,
  )
),

When a CSS value is multiple (containing commas), make sure to wrap the whole value between parenthesis.

// parenthesis wrapping CSS multiple value
... : (
  props: (
    font-family: ('Helvetica Neue', 'Helvetica', 'Arial', sans-serif),
    transition: (background-color 300ms ease-in-out, border-color 300ms ease-in-out)
  )
),

Core settings (body, headings, paragraph...) are mainly using the props property to provide default styling. Check the HTML elements documentation to know what they are and change them at your own will.

Responsive value

A property can accept a map of breakpoints to generate responsive values


body : (
  props: (
    font-size: (
      rt: 1rem, // root value (default)
      sm: 1.2rem, // value @sm
    )
  )
),
/* Generating */
body {
  font-size: 1rem;
}
@media (min-width: 37.500em) {
  body {
    font-size: 1.2rem;
  }
}

Pseudo-elements, States and Pseudo-selectors

Style any pseudo-elements (before, after... ) and any CSS states (hover,focus... ) and other pseudo-selectors (first-child... ) by using them as property names with a map of CSS properties as value.


... : (
  props: (
    font-size: 1rem,
    '::before': (
      content: 'Tokyo –',
      font-size: .8rem,
    ),
    ':hover': (
      text-decoration: underline,
      '::before': (
        color: #cdcdcd,
      )
    )
    ':first-child': (
      margin-top: 10px,
    )
  )
),

Child elements

Target nested elements from the key property > having as value a map of CSS selectors with CSS properties.


... : (
  props: (
    font-size: 1rem,
    '>': (
      'li': ( // targetting <li>
        margin-bottom: 10px,
      ),
      'li:last-child': ( // pseudo selector
        border-bottom: 1px solid #ccc,
      ),
      '.active': ( // classname
        font-weight: 700,
      ),
    )
  )
),

Styling pseudo-elements and child-elements are mainly used when developing components from the Loop config.


# States Property

The states property is reserved to pass a map of Element states containing CSS properties.
The properties can be written in pure css or in camelCase depending on your preferences.

Any css state is available such as active, hover, focus, visited...

... : (
  states: (
    hover: ( // CSS properties
      color: #cdcdcd,
      border: 1px solid #cdcdcd,
    ),
    focus: ( // CSS properties
      color: blue,
    ),
  )
),

Same as props, the rules for pseudo-elements and child-elements also apply to states.


# This Referer

The keyword this() refers to a value in the context of the config map.

$ooLoop: (
  palette: (
    'primary': #0ea7d6,
    'secondary': #959595,
  ),
  anchor: (
    props: (
      color: this('palette.primary'),
    )
  ),
  ...
);
/* will generate */
a {
  color: #0ea7d6;
}

Spread operator

Expand a map by referring a set of values in the context of the config map by using the operator _this()

$ooLoop: (
  palette: (
    'primary': #0ea7d6,
    'secondary': #959595,
  ),

  // utilities
  color: (
    font: (
      prefix: 'color',
      property: 'color',
      values: (
        _this('palette'),
        (
          'danger': red,
        )
      )
    )
  ),
  ...
);
/* will generate */
.color-primary   { color: #0ea7d6 }
.color-secondary { color: #959595 }
.color-danger    { color: red }

In the case where the expansion is targetting a single value, the last crumb of the path will be used as the name of its value.

$ooLoop: (
  palette: (
    'primary': #0ea7d6,
    'secondary': #959595,
  ),

  // utilities
  color: (
    font: (
      prefix: 'color',
      property: 'color',
      values: (
        _this('palette.primary'),
        (
          'danger': red,
        )
      )
    )
  ),
  ...
);
/* will generate */
.color-primary { color: #0ea7d6 }
.color-danger  { color: red }

Chaining

Add as many spreads as needed

$ooLoop: (
  palette: (
    'primary': #0ea7d6,
    'secondary': #959595,
    'warning': #f7f3c8,
  ),

  // utilities
  color: (
    font: (
      prefix: 'color',
      property: 'color',
      values: (
        _this('palette.primary'),
        _this('palette.secondary'),
        (
          'danger': red,
        )
      )
    )
  ),
  ...
);
/* will generate */
.color-primary { color: #0ea7d6 }
.color-secondary { color: #959595 }
.color-danger  { color: red }

Aliases

The config map not being initialized, the use of sass functions along with the keyword this cannot be performed. They are however working with regular values.

$ooLoop: (
  palette: (
    'primary': #0ea7d6,
    'secondary': #959595,
  ),
  anchor: (
    props: (
      color: this('palette.primary'),
    ),
    states: (
      hover: (
        // this will throw an error
        color: darken(this('anchor.props.color'), 12%),
      ),
      focus: (
        // this works fine
        color: darken(#0ea7d6, 12%);
      )
    )
  ),
  ...
);

Aliases will help you overcome this problem and avoid repeating values already set. At this stage, the few available are ooDarken and ooLighten.

$ooLoop: (
  palette: (
    'primary': #0ea7d6,
    'secondary': #959595,
  ),
  anchor: (
    props: (
      color: this('palette.primary'),
    ),
    states: (
      hover: (
        color: ooDarken(this('anchor.props.color'), 12%),
      ),
      focus: this('anchor.states.hover'),
    )
  ),
  ...
);

# Access Data

Access any data of the config map during your development.

oo($path)

Function - Get values from Loop config.

  • $path (string)
    Concatenated path to a Loop config property.
    When accessing a value from props, the kebab-case css property can be targetting with a camelCase name.
$ooLoop: (
  palette: (
    'primary': #0ea7d6,
    'secondary': #959595,
  ),
  body: (
    props: (
      font-family: ('Helvetica Neue', Helvetica), // kebab-case
    )
  ),
  ...
);
.hero {
 display: flex;
 height: 400px;

 /* Access kebab-case from camelCase */
 font-family: oo('body.props.fontFamily');

 background-color: oo('palette.primary');
} 

Make sure to use oo() after the initialization of the config map to have all the updated data.


# Store

Add your own data to the config map through the property store to reuse them anywhere in your project.

Those data will not generate any CSS rules, It's just a way to set and access your project global values during your development.

$ooLoop: ooSet('store', (
  fontFamily: (
    serif: (Georgia, serif)
  ),
));
@include ooCreate();
.hero {
  display: flex;
  height: 400px;
  font-family: oo('store.fontFamily.serif');
}
/* Will generate */
.hero {
  display: flex;
  height: 400px;
  font-family: Georgia, serif;
}

On the contrary not passing by store may generate extra rules.

$ooLoop: ooSet('typo.fontFamily', (
  values: (
    serif: (Georgia, serif)
  ),
));
@include ooCreate();
.hero {
  display: flex;
  height: 400px;
  font-family: oo('typo.fontFamily.values.serif');
}
/* Will generate */
.font-serif { font-family: Georgia, serif; !important }

.hero {
  display: flex;
  height: 400px;
  font-family: Georgia, serif;
}

Start using Loop << >> Use what you need