Paragraph styles in web design

Typographic styles exist in most of word processing, publication and design apps such as InDesign, Pages or MS Word. It’s easy to create even better functionality with Sass, for web design projects.

Working with typographic styles provides reusability, inheritance and ability to change the whole layout in a bliss.

Responsive properties

Defining the CSS properties with pre-defined breakpoint names as follows:

    font-size: (
        default:  small,
        small:    normal,
        large:    large
    )

And similarly font-weight, or any other property:

    font-weight: (
        default:  bold
        small:    normal
    )

Isn’t it wonderful?

To apply a typographic style in our stylesheet, traditionally we used a HTML class or a HTML tag:

    .headline,
    h1
    {
        font-size:...
        ...
    }

It is much better with a @mixin, were we can apply the style to any existing HTML selector without repeating the same definition in other part of the stylesheet e. g. a different Sass partial:

    .headline,
    h1 {
        @include typography(headline);
    }

    [...]

    .some-frameworks-class
    {
        @include typography(headline);
    }

All our typographic styles can live in one place, in a JSON file or a Sass map:

    $typography: (
        content: (
            font-family: sans-serif,
            line-height: 1.4,
        ),
        headline: (
            font-size: (
                default: small,
                small:   normal,
                large:   large
            ),
            font-weight: (
                default: bold
                small:   normal
            )
        )
    )

Inheritance

Inheritance can be achieved by creating a custom property, e. g. INHERIT.

    headline: (
        INHERIT: content,
        font-size: ....
    )

The properties defined in the style content, can be overridden by the definitions of the style headline in the pre-processing.

The code

////
// Typography funtion
// for Typography mixin
// 
// @param style, string name of the typographic style
//        output, map used for recursion
// @use $typography, map of typographic styles
//
// @returns map, properties of a typographic style
//
@function typography( $style, $output:() ) {
   
   $map:    $typography;
   $i:      1;
   $length: length($style);
   
   @while $length >= $i  {
      
      $map: map-get($map, nth($style, $i));
      $i: $i + 1;
   }
   
   @each $property, $value in $map {
      
      ////
      // supports multiple parents
      //
      @if $property == 'INHERIT'{ 
         
         @each $parent_style in $value {
            $output: map-merge( $output, typography($parent_style));
         }
      }
      @else { 

         $output: map-merge( $output, ($property: $value));    
      }
   }
   
   @return $output;
}


////
// Typography mixin
// 
// @param style name
// @use bp() breakpoint mixin
// @return CSS of a typographic style
//
//
@mixin typography($style){

   $output: typography($style);

   @each $property, $value in $output {
      
      @if type-of($value) != map {
         // simple property
         #{$property}: $value;
      }
      
      @else {
         // responsive property
         @each $breakpoint, $bp_value in $value {
            // default value
            @if $breakpoint == default or $breakpoint == def {
               #{$property}: $bp_value;
            }
            // double-auto breakpoint (horizontal and vertical, lower limit)
            // prefixed 'da-' in the style definition
            @else if str-starts-with($breakpoint, 'da-') {
               $breakpoint: str-slice($breakpoint, 4);
               @include bp(double-auto, $breakpoint) {
                  #{$property}: $bp_value;
               }
            }
            // horizontal breakpoint (lower limit)
            @else {
               @include bp($breakpoint) {
                  #{$property}: $bp_value;
               }
            }     
         }
      }
   }
}

And my breakpoint definitions for reference.

{
   "def"      : 0,
   "mini"     : 481,
   "xxsmall"  : 600,
   "xsmall"   : 736,
   "small"    : 768,
   "medium"   : 961,
   "large"    : 1041,
   "mlarge"   : 1281,
   "xlarge"   : 1441,
   "xxlarge"  : 1881,
   "bp4k"     : 2880
}

Add a comment