Back to home

ChallengesNaming conventionsTypesOrderingExample layout
Principles main image

Principles

Challenges

Current challenges

  1. Standardising style configuration:
    • themes
    • colours
    • animation
    • elevation
    • typography
    • grid
    • breakpoints
    • iconography
    • naming conventions
    • style order
    • rules for classing
    • relation to design
  2. Standardising file system layout:
    • themes
    • flexibility
    • subdirectory structure (images, fonts, utils)
  3. Code quality
    • documentaiton
    • testing
    • reusability
    • callback ability when updating repos
    • accessibility
    • dependency abuse
  4. Resources
    • references and direction
    • onboarding

Naming challenges

A list of challeneges when thinking of naming conventions:

  1. How can styling conventions apply between frameworks?
  2. What conventions do we need to sacrifice between different frameworks?
  3. How is this consumable for both the dev and designer ecosystem?
  4. What file structures do we incorporate between partials to make them easily reusable.
  5. How can we define class names that work for all the different types of code we write?
  6. How can we efficiently document and test our code?
  7. How can we maintain consistency in the way we write our styling?
  8. How can we enforce accessible, high standards for our HTML?
  9. How can we decouple and standardise things such as grids, animation speeds, iconography etc.?

Naming conventions

Links

  • Modular Sass
  • RSCSS
  • A11y Style Guide

Types

Predetermined types by level:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 body: header:# @classname header # @children # Top level for each section section: # @classname section-name # @children container: # @classname container-name # Base selection of rules block: # @children grid: grid-item: # @children table: # @children table-header: # @children table-data: # @chidlren list: # react native only list-item: # @children # ... more, maybe article etc nav: nav-item: # @children component: # @classname component-name # Specific component based styling # @children # Base selection of rules block: # @children grid: grid-item: # @children table: # @children table-header: # @children table-data: # @chidlren list: # react native only list-item: # @children # ... more, maybe article etc nav: nav-item: # @children footer:# @classname footer - but maybe should be more specific # @children

Ordering

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 .selector { /* Mixins + Extends */ @extend .selector-to-extend-from; @include mixin; /* Positioning */ position: absolute; z-index: 10; top: 0; right: 0; /* Display & Box Model */ display: inline-block; overflow: hidden; box-sizing: border-box; padding: 10px; border: 10px solid #333; margin: 10px; /* Sizing */ max-width: 100px; width: 100%; height: 100px; /* Background */ background-color: #000; /* Text */ font-family: sans-serif; font-size: 16px; line-height: 1.4; text-align: right; color: #fff /* Transitions */ transition: all $speed ease-out; /* Other */ cursor: pointer; /* Modifiers */ &:last-of-type { // Repeat Ordering Rules } &:hover, &:focus { // Repeat Ordering Rules } /* Media Breaks */ @include grid-media($mobile-grid) { // Repeat Ordering Rules } /* Second-tier elements */ .selector-child { // Repeat Ordering Rules } }

Example layout

Example layout

Example layout

The aim is that regardless of whether or not we are using a template engine, JSX, html or whatever that uses/doesn't use partials or components of some form that we are able to maintain consistency.

In the above image, let's look at how we would implement in a template engine like twig and then in React:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <!-- Section partial ~/partials/page-offers/section-offers.twig (TODO: decide naming strutures?) --> <section class="section-offers"> <div class="container-content"> <div class="block-content"></div> <div class="block-header"></div> <div class="grid-offers"> {% for offer in offers %} <div class="grid-offer"> {% include 'partials/component-offer/offer.twig' with {offer: offer} %} </div> {% endfor %} </div> </div> </section> <!-- Section partial ~/partials/page-offers/component-offer.twig (TODO: decide naming strutures?) --> <div class="component-offer"> <div class="block-image"> <img src="{{ offer.imgSource }}" alt="{{ offer.alt }}" class="offer-image" /> </div> <div class="block-title"> <h3 class="offer-title">{{ offer.title }}</h3> </div> </div>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 // components/SectionOffers/index.js import React, { Component } from 'react'; import Images from 'img/Image'; import Offer from 'components/Offer'; class SectionOffers extends Component { constructor(props) { super(props); this.state = { offers = [...] }; } /** * Render the <Home /> component * @return {Home} Home page component */ render() { const { membershipCardId, profile } = this.props; console.log(this.state.renderCode); return ( <section className="section-offers"> <div className="container-content"> <div className="block-content"></div> <div className="block-header"></div> <div className="grid-offers"> {offers.map(d, i) => ( <div className="grid-offer"> <Offer offer={d} /> </div> )} </div> </div> </section> ); } } export default SectionOffers; // components/Offer/index.js // ENSURE THAT ANY COMPONENT WE BUILD FOR // IS STATELESS import React, { Component } from 'react'; import { Link } from 'react-router'; import Images from 'img/Image'; export default Offer = (props) => ( <div className="component-offer"> <div className="block-image"> <img src={props.imgSource} alt={props.imgAlt} className="offer-image"> </div> <div className="block-title"> <h3 className="offer-title">{props.offerTitle</h3> </div> </div> );
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 // in other base files // base/_container.scss .container { // keep vars elsewhere max-width: $max-width; // center margin: 0 auto; // set base padding rules // containers should only have padding padding: 80px 20px; // set base overrides @include grid-media($mobile) { padding: 10px; } } // base/_block.scss .block { // if blocks get basic rules } // base/_grid.scss .grid { // our base grid rules // given we are enforcing STANDARD rules // ensure you use the direct child selector > .grid-item { // item rules } } // Component or partial: SectionOffers // sections/_section-offers.scss // every file should only go three levels deep // level one: parent // level two: any child of parent (parent should prevent bleed through) // level three: modifiers, sibling classes, media breaks .section-offers { // should handle: // padding // background color padding: 80px 20px; @include grid-media($mobile) { padding: 40px 20px; } .container-content { // should handle central gutter @extend .container; // ^ brings in things like margin: 0 auto; } .block-content { // blocks should only have margin-bottom margin-bottom: 20px; @include grid-media($mobile) { } } .block-header { } // another pre-determined type .grid-offers { @extend .grid; } // note that this is still level two // and doesn't fall in component scss .grid-offer { @extend .grid-item; } } // components or react level styling // components/_offers.scss .component-offer { // begin rules again position: relative; // ... .block-image { // ... } .offer-image { // ... } .block-title { // ... } .offer-title { // ... } }

In the case of a React Native app, set the styles object to be equivalent but without nesting:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 // Component or partial: SectionOffers // sections/_section-offers.scss // every file should only go three levels deep // level one: parent // level two: any child of parent (parent should prevent bleed through) // level three: modifiers, sibling classes, media breaks const sectionOffers = { containerContent { @extend .container; } blockContent { // blocks should only have margin-bottom margin-bottom: 20px; @include grid-media($mobile) { } } blockHeader { } // another pre-determined type gridOffers { @extend .grid; } // note that this is still level two // and doesn't fall in component scss gridOffer { @extend .grid-item; } } // Offer component const styles = { // components or react level styling // components/_offers.scss offer: { // begin rules again position: "relative"; // ... } offerimage: { // ... } offerTitle { // ... } }

Dennis O'Keeffe

@dennisokeeffe92
  • Melbourne, Australia

Hi, I am a professional Software Engineer. Formerly of Culture Amp, UsabilityHub, Present Company and NightGuru.
I am currently working on workingoutloud.dev, Den Dribbles and LandPad .

Related articles


1,200+ PEOPLE ALREADY JOINED ❤️️

Get fresh posts + news direct to your inbox.

No spam. We only send you relevant content.