ttd-popper

    1.0.0 • Public • Published

    HTML Boilerplate

    HTML5 Boilerplate is a frontend template include HTML, CSS, JS for building fast sites.

    Getting started

    Open your preferred command line tool and run follow some steps below:

    1. git clone https://github.com/ninhva/html-boilerplate.git.
    2. cd html-boilerplate.
    3. npm install automatically to install plugins required for the build script based in package.json file.
    4. npm run dev to preview and development, then run url http://localhost:9000 in your browser.
    5. npm run prod to preview final version, then run url http://localhost:9090 in your browser.
    6. npm run build to build final version.

    Features

    • You can separate the elements (header, footer, banner, aside...) to be reused many times without trouble.
    • Prettify HTML code.
    • Using SASS library.
    • Minify JS and CSS files.
    • Minify images (jpg, png, svg...) seamlessly.

    Project structure

    
    html-boilerplate/
    ├── src/
    │   ├── fonts
    │   ├── images
    │   ├── scripts
    │   ├── styles
    │   └── views/
    │       ├── layouts
    │       ├── pages
    │       └── partials
    └── gulpfile.js
    
    
    

    CSS Methodology

    • Blocks
      • are prefixed with b-
      • good: b-menu, b-sidebar, b-sitemap, b-user
      • bad: menu, sidebar, sitemap, user
    • Elements
      • have no prefix and can only be defined in block scope
      • are not prefixed with their block (choose a longer name if it's not expressive enough)
      • good: item, title, user-avatar (instead of user or avatar)
      • bad: user-user-avatar, menu-item-a
    • Modifier
      • are prefixed with is-, and have to be defined in block or element scope
      • good: is-selected, is-active, is-approved
      • bad: selected, active, approved

    Example

    File _menu.scss in source/sass/blocks directory.

    .b-menu { /* block: 'b-menu' */
      &.is-static { /* modifier: 'is-static' for b-menu  */
        …
      }
    
      .item { /* element: 'item' in b-menu */
        a { /* element: 'item a' in b-menu */
          …
        }
      }
    }
    

    Class-Naming

    Because you want to know if the block is for page layout or for a single component, we separate page layout blocks from component blocks.

    Page Layout Blocks:

    • b-page
    • b-page-header
    • b-page-nav
    • b-page-main
    • b-page-aside
    • b-page-footer

    Component Blocks:

    • b-eventlist
    • b-linklist
    • b-sitemap
    • b-teaser-text
    • b-teaser-video

    Commenting

    Start with a small description of the rule set, then number tiny details that are worth an explanation. The numbers are matching with the numbered comments at the end of the CSS rules, e.g. /* [1] */.

    /**
     * Purpose of the selector or the rule set
     * 1. Hardware acceleration hack
     * 2. position: sticky; on anything but top aligned elements is buggy in Chrome <37 and iOS 7+
     */
     
    .box {
      position: fixed;
      transform: translate3d(0, 0, 0); /* [1] */
      
      .csspositionsticky & {
        position: sticky; /* [2] */
      }
    }
    

    CSS Coding Style

    (This list is not intended to be exhaustive.)

    • Use lowercase for class names.
    • Be consistant with indentation – using 2 spaces.
    • Be consistent in declaration order, cluster related properties (Positioning, Box-Model, Text & Color).
    • Be consistant with quotes – using double quotes "".
    • Quote attribute values in selectors, e.g. input[type="checkbox"].
    • One selector per line, one rule per line.
    • Put spaces after : in property declarations.
    • Put a ; at the end of the last declaration in a declaration block.
    • Include a space after each comma in comma-separated property or function values, e.g. rgba(0, 0, 0, 0).
    • Separate each ruleset by a blank line.

    CSS Coding Guidelines

    Avoid dangerous selectors

    If a selector is too generic, it's dangerous. In 99% of cases you have to overwrite this rule somewhere. Be more specific. Try using a class instead. (Exception: CSS-Resetstyles)

    bad

    header { … }
    h2 { … }
    ul { … }
    

    good

    .header { … }
    .subtitle { … }
    .linklist { … }
    

    Avoid element selectors

    Element selectors are expensive. Like the rule above, be more specific. Try using a class instead. Furthermore elements like <div /> and <span /> should always have a class-attribute in your markup.

    bad

    .foo div { … }
    .foo span { … }
    .foo ul { … }
    

    good

    .foo .section { … }
    .foo .title { … }
    .foo .linklist { … }
    

    Avoid IDs where possible

    IDs should never be used in CSS. Use IDs in HTML for fragment identifiers and maybee JS hooks but never in CSS because of their heightened specificity and because they can never be used more than once in a page.

    Though you should use IDs in forms to connect <input /> and <label /> with the for-attribute.

    bad

    #sidebar
    

    good

    .sidebar
    

    Avoid qualifying class names with element selectors

    It's counterproductive because you unnecessary heighten the specifity.

    bad

    ul.linklist { … }
    div.example { … }
    a.back { … }
    

    good

    .linklist { … }
    .example { … }
    .back { … }
    

    Avoid the descendant selector

    The descendant selector is the most expensive selector in CSS. You should target directly if possible.

    bad

    html body .linklist li a { … }
    

    good

    .linklist-link { … }
    

    Avoid deep nesting

    Following to the rule above you should also try to nest your selectors maximum 3 levels deep.

    bad

    .navlist li a span:before { … }
    

    good

    .navlist .info:before { … }
    

    Avoid using the same selctor for styling and JS

    Separation of concerns

    bad

    .dialog-opener { … }
    
    $('.dialog-opener')…
    

    good

    .dialog-opener { … }
    

    prefixed with js-

    $('.js-dialog-opener')…
    

    or use data-attributes:

    $('[data-dialog-opener]')…
    

    Avoid using native language

    The English language has proven itself among coders as the standard.

    bad

    .share-buttons .chia-se a {
      background: url("../img/icons/facebook-teilen.png") no-repeat 0 0;
    }
    

    good

    .share-buttons .facebook-share a {
      background: url("../img/icons/facebook-share.png") no-repeat 0 0;
    }
    

    Use shorthand properties where possible

    It's shorter and easier to read.

    bad

    .box {
      padding-top: 0;
      padding-right: 10px;
      padding-bottom: 20px;
      padding-left: 10px;
    }
    

    good

    .box {
      padding: 0 10px 20px;
    }
    

    Omit unit specification after “0” values

    bad

    .box {
      margin: 0px;
    }
    

    good

    .box {
      margin: 0;
    }
    

    exception, where you don't omit

    .box {
      transform: rotate(0deg);
    }
    

    Use hexadecimal color codes unless using rgba or hsl

    In most cases the hex code is shorter than the color names, so you could save some bits.

    bad

    .box {
      color: orange;
    }
    

    good

    .box {
      color: #ffa500;
    }
    

    Use 3 character hexadecimal notation where possible

    Like above, it's shorter and saves some bits.

    bad

    .box {
      color: #ff009;
    }
    

    good

    .box {
      color: #f09;
    }
    

    Use number keywords 100–900 for font-weight

    It's the typographic standard to use number keywords. Like above it's also shorter and saves some bits.

    bad

    .box {
      font-weight: normal;
    }
    

    good

    .box {
      font-weight: 400;
    }
    

    Separate words in class names by a hyphen

    bad

    .user_avatar { … }
    .userAvatar { … }
    .useravatar { … }
    

    good

    .user-avatar { … }
    

    Don't use !important

    It may be ok to use it on helper classes though.

    SASS structure

    There is a main SCSS-file main.scss.

    The main.scss imports all partials.

    This is how the sass-folder looks like:

    $ tree
    .
    styles
    ├── base
    │   ├── minxins
    │   |   ├── _box-shadow.scss
    │   |   ├── _rem.scss
    │   |   └── …
    │   ├── _button.scss
    │   ├── _extends.scss
    │   ├── _fonts.scss
    │   ├── _mixins.scss
    │   ├── _reset.scss
    │   ├── _utility.scss
    │   ├── _variables.scss
    │   └── …
    ├── custom
    │   ├── _custom-plugin.scss
    │   └── …
    ├── layouts
    │   ├── _header.scss
    │   ├── _footer.scss
    │   └── …
    ├── pages
    │   ├── _homepage.scss
    │   ├── _aboutpage.scss
    │   └── …
    └── responsive
        ├── _responsive.scss
        └── …
    
    

    Some explanation:

    • button.scss – put your button styles.
    • reset.scss – global browser reset.
    • fonts.scss – use it for @font-face-declarations.
    • mixins/ – put your mixins in here, e.g. rem, breakpoint etc.
    • utility.scss – put your common classes.
    • variables/ – put your variables in here, e.g. color, typography etc.

    SASS Coding Guidelines

    Syntax

    We're using SCSS-syntax because it's valid CSS and more expressive.

    Order of definition

    If you have a consistent order of definition, everybody can scan the code on first sight.

    List media queries first

    .b-foo {
      
      // Media Queries
      @include breakpoint(767) {
        padding: 10px;
      }
      
    }
    

    List global styles beginning with @extend second (separated by a blank line)

    .b-foo {
      
      // Media Queries
      @include breakpoint(767) {
        padding: 10px;
      }
      
      // Global Styles
      @extend %module;
      
    }
    

    List @include third

    .b-foo {
      
      // Media Queries
      @include breakpoint(767) {
        padding: 10px;
      }
      
      // Global Styles
      @extend %module;
      @include transition(all .5s ease);
      
    }
    

    List regular styles next

    .b-foo {
      
      // Media Queries
      @include breakpoint(767) {
        padding: 10px;
      }
      
      // Global Styles
      @extend %module;
      @include transition(all .5s ease);
      color: #000;
      
    }
    

    List pseudo-class/elements nesting with & (separated by a blank line)

    .b-foo {
      
      // Media Queries
      @include breakpoint(767) {
        padding: 10px;
      }
      
      // Global Styles
      @extend %module;
      @include transition(all .5s ease);
      color: #000;
      
      &:hover {
        color: #fff;
      }
      
      &::after {
        content: "";
      }
      
    }
    

    List nested selectors last (separated by a blank line)

    .b-foo {
      
      // Media Queries
      @include breakpoint(767) {
        padding: 10px;
      }
      
      // Global Styles
      @extend %module;
      @include transition(all .5s ease);
      color: #000;
      
      &:hover {
        color: #fff;
      }
      
      &::after {
        content: "";
      }
      
      > .bar {
        background-color: #f90;
      }
      
    }
    

    Nesting

    Maximum Nesting: three levels deep!

    .b-foo {
      .bar {
        .baz {
          // no more!
        }
      }
    }
    

    Blocks in blocks

    Where to define the styles for blocks in blocks? Answer: always in your block which gets the styling. Otherwise you have to maintain more than one file which is error-prone.

    Example: Assumed that you have a different styling for the user-avatar-block, based on whether it's in your page-header-block or in your page-footer-block.

    <div class="b-page-header">
      <div class="b-user-avatar">
        …
      </div>
    </div>
    
    <div class="b-page-footer">
      <div class="b-user-avatar">
        …
      </div>
    </div>
    

    bad

    // _page-header.scss
    .b-page-header {
      .b-user-avatar {
        float: right;
        width: 100px;
        height: 100px;
      }
    }
    
    // _page-footer.scss
    .b-page-footer {
      .b-user-avatar {
        float: left;
        width: 50px;
        height: 50px;
      }
    }
    
    // _user-avatar.scss
    .b-user-avatar {
      border-radius: 50%;
    }
    

    good

    // _user-avatar.scss
    .b-user-avatar {
      border-radius: 50%;
      
      .b-page-header & {
        float: right;
        width: 100px;
        height: 100px;
      }
      
      .b-page-footer & {
        float: left;
        width: 50px;
        height: 50px;
      }
    }
    

    Order of elements

    Selectors mirror the order of the markup.

    <div class="b-foo">
      <ul class="bar">
        <li class="baz">
          <a class="qux" href="#">Link</a>
        </li>
      </ul>
    </div>
    

    bad

    .b-foo {
      .qux {
        …
      }
      
      .bar {
        …
      }
    }
    

    good

    .b-foo {
      .bar {
        …
      }
      
      .qux {
        …
      }
    }
    

    Bundling

    All child selectors are bundled below the parent selector.

    <div class="b-foo">
      <ul class="bar">
        <li class="baz">
          <a class="qux" href="#">Link</a>
        </li>
      </ul>
    </div>
    

    bad

    .b-foo {
      .bar {
        …
      }
    }
    
    .b-foo {
      .qux {
        …
      }
    }
    

    good

    .b-foo {
      .bar {
        …
      }
      
      .qux {
        …
      }
    }
    

    Child selectors

    Each child selector will be indented and set on a new line. Important: you don't have to mirror the complete DOM!
    Rule of thumb: The selector is as short as possible. Indention only if the selector is needed.

    <div class="b-foo">
      <ul class="bar">
        <li class="baz">
          <a class="qux" href="#">Link</a>
        </li>
      </ul>
    </div>
    

    bad

    .b-foo {
      .baz .qux {
        …
      }
    }
    

    bad too

    .b-foo {
      .baz {
        .qux {
          …
        }
      }
    }
    

    good

    .b-foo {
      .qux {
        …
      }
    }
    

    Placeholder extends vs. class extends

    You have two options to extend code blocks that are reused several times: standard classes and placeholders. The advantage of placeholder extends over classes: they won't be added to the CSS output and remain silent. Very usefull for helper classes e.g. like the clearfix which was put directly on the markup in the past.

    Class extend

    // Usage
    .foo {
      padding: 10px;
    }
    
    .bar {
      @extend .foo;
      color: #fff;
    }
    
    // Output
    .foo,
    .bar {
      padding: 10px;
    }
    
    .bar {
      color: #fff;
    }
    

    Placeholder extend

    // Usage
    %foo {
      padding: 10px;
    }
    
    .bar {
      @extend %foo;
      color: #fff;
    }
    
    // Output
    .bar {
      padding: 10px;
      color: #fff;
    }
    

    Placeholder extends > Mixins

    To reuse SASS snippets repeatedly, you should choose placeholder extends and not mixins. Thus, the CSS output is smaller because selectors are summarized.

    bad

    // Mixin
    @mixin ellipsis() {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    
    // Usage
    .foo {
      @include ellipsis();
    }
    
    .bar {
      @include ellipsis();
    }
    
    // Output
    .foo {
      overflow: hidden;
      text-overflow: ellipsis:
      white-space: nowrap;
    }
    
    .bar {
      overflow: hidden;
      text-overflow: ellipsis:
      white-space: nowrap;
    }
    

    good

    // Placeholder extend
    %ellipsis {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    
    // Usage
    .foo {
      @extend %ellipsis;
    }
    
    .bar {
      @extend %ellipsis;
    }
    
    // Output
    .foo,
    .bar {
      overflow: hidden;
      text-overflow: ellipsis:
      white-space: nowrap;
    }
    

    Keep it simple – Part 1

    Just because you can solve problems with functions, mixins etc. in SASS, you must not necessarily do it. :)
    Always remember that others should easily read and understand your code too.

    elaborate

    // Mixin
    @mixin context($old-context, $new-context) {
      @at-root #{selector-replace(&, $old-context, $new-context)} {
        @content;
      }
    }
    
    // Usage
    li {
      float: left;
      
      ul {
        display: none;
        
        @include context('li', 'li:hover') {
          display: block;
        }
      }
    }
    

    simple

    li {
      float: left;
      
      ul {
        display: none;
      }
      
      &:hover ul {
        display: block;
      }
    }
    

    Keep it simple – Part 2

    For better readability, you should write the properties as in CSS.

    elaborate

    .foo {
      font: {
        family: arial, sans-serif;
        size: 5em;
        weight: 700;
      }
    }
    

    simple

    .box {
      font-family: arial, sans-serif;
      font-size: 5em;
      font-weight: 700;
    }
    

    Browser support

    • Chrome (latest)
    • Safari (latest)
    • Firefox (latest)
    • Edge (latest)
    • Opera (latest)
    • Internet Explorer 10+

    License

    nikita.css MIT License

    Install

    npm i ttd-popper

    DownloadsWeekly Downloads

    2

    Version

    1.0.0

    License

    MIT

    Last publish

    Collaborators

    • thanhhc