Getting started

FICTOAN runs on SCSS, meaning it needs to be transpiled into CSS before it can be read by the browser. Install it from here.

Once installed, you’ll write SCSS, where you can use variables and mixins, greatly adding functionality to plain ol’ CSS.

Using FICTOAN

Straight out of the box

Just head to the dist folder, and take fictoan.min.css file and drop it into your project. Include the path in your HTML file, and that’s it, you’re done.

<link rel="stylesheet" href="path-to/fictoan.min.css" type="text/css">
Or, getting your hands dirty

Want to build on top of FICTOAN? Then, open the scss directory, and in it, you'll find three more folders and the main.scss source file and the transpiled fictoan.min.css output file. The fictoan.scss imports all the other SCSS files in a particular order and transpiles them into one single CSS file.

Customised builds

You can comment out the files you don’t want— your project doesn’t need a sidebar? Comment it out. Or you need FICTOAN for just the layouts? Comment out all the folders but base. This way you can reduce the outputted CSS file size and thus performance.

/vendor

This folder contains all third-party plugins, right now it has only one file— normalize.scss.

/fictoan

This is the meat of FICTOAN, and has all the layouts, grids, styling rules, elements and components all neatly organised. They all have a ff prefix, so that you don’t confuse them with your our files in your projects.

/this-project

Now, we come to the custom part. This folder has two files inside, one for defining variables, and another for all your styling rules. Rename them to reflect the name of your current project, and edit only these files. This way, it becomes easy to track changes, and updating FICTOAN is also a breeze. Be sure to rename the filenames in main.scss too.

Class names

Class names in FICTOAN are designed to be intuitively recalled, so that you don’t have to remember complex nomenclature and contextual modifiers. All class names are in plain, conversational English, rather than devspeak.

For example, .vertically-centre-this, .no-padding-left and .show-only-on-mobile, to name a few. We’ll elaborate this in the individual sections.

Element sizing

Variable themes

If you are planning to use FICTOAN right out of the box, it comes with a well laid out theme to set the look and feel of your web project.

You can easily change the look and feel completely just by changing a few values of variables, in the theme/_ff-variables.scss file.


$fontSans  : "Work Sans", sans-serif;
$fontSerif : "Crimson Text", serif;
$fontMono  : "Space Mono", monospace;

//  Paragraph-specific variables
$baseFontSize : 1em;
$scaleFactor  : 1.2;

$paraSerifFontSize   : 1.1em;
$paraSerifLineHeight : 1.4;

//  Body basics  ==========================================
$bodyBgColor : $colorWhite;

$paraFontSize   : 1em;
$bodyLineHeight : 1.6;

//  Selection highlight
$textHighlightBg    : $colorHue;
$textHighlightColor : $colorWhite;

//  Variables for text
$bodyFontColor : $colorShade;
$linkColor     : $colorHue;

//  Button  ===============================================
$buttonGradientStartColour : $colorHue;
$buttonGradientEndColour   : $colorAnalogue;

//  Progress bar  =========================================
$progressBarBG   : $colorTint;
$progressBarFill : $colorHue;

//  Sidebar  ==============================================
$sideBarBG        : $colorGrey-10;
$sideBarItemBG    : $colorGrey-10;
$sidebarTextColor : $colorShade;

$sideBarItemBGOnHover    : $colorHue;
$sidebarTextColorOnHover : $colorWhite;
                

Layout

FICTOAN uses a 16–column grid system. Content by default is full-width, but you can add a .padded-content class to the body to provide a bit of equal padding to the left and right.

Some of you might think 16 columns a bit much, but there have been quite a few times when the extra columns have come to my rescue, offering a bit more fine control over the content.

A single row

All content is organised into .row elements having .portion children elements of varying widths. The .portion divs are accompanied by a width class, ranging from one-sixteenth which would be 6.25% of parent .row’s width, to .whole, which is 100%.

The idea is to have the widths of the .portion elements add up to a 100%. So, for example, in a .row, you could have three instances of .portion.one-third to create a three-column layout. You can also have unequal widths, as long as the widths add up to a 100%. If exceeded, it’ll wrap to the next line.


// Example 1
<div class="row">
    <div class="portion one-fourth"></div>
    <div class="portion one-fourth"></div>
    <div class="portion one-fourth"></div>
    <div class="portion one-fourth"></div>
</div>
            

// Example 2
<div class="row">
    <div class="portion one-ninth"></div>
    <div class="portion three-fourteenths"></div>
    <div class="portion two-tenths"></div>
    <div class="portion two-twelfths"></div>
    <div class="portion four-thirteeths"></div>
</div>
            
Example 1

.row

.one-fourth

.one-fourth

.one-fourth

.one-fourth

Example 2

.row

.one-ninth

.three-fourteenths

.two-tenths

.two-twelfths

.four-thirteenths

Multiple rows

If you want to group portions whose collective widths exceed a 100% into a single container, just use a .box class instead of a .row.

The portions inside can be all of equal widths, or varying widths too.


<div class="box">
    <div class="portion one-fourth"></div>
    <div class="portion one-fourth"></div>
    <div class="portion one-fourth"></div>
    <div class="portion one-fourth"></div>
    <div class="portion one-fourth"></div>
    <div class="portion one-fourth"></div>
    <div class="portion one-fourth"></div>
</div>
            

.box

.one-fourth

.one-fourth

.one-fourth

.one-fourth

.one-fourth

.one-fourth

.one-fourth

Responsive helpers

Use special classes to change the way a particular .portion behaves in each of these devices. Simply specify what width you want it to have in each of these breakpoints. Use any width class suffixed with the appropriate device.

Then, if you want to turn off the responsive behaviour, and have the divs maintain their layout across all or even specific devices, there are classes for that, too. Just add retain-layout along with the device and orientation.

Mobile

Below 600px

Tablet – portrait

From 601px to 900px

Tablet – landscape

From 901px to 1200px

Desktop

Above 1200px

//  Specific layout
<div class="row">
<div class="portion  one-sixth  one-fourth-on-tab-ls  one-third-on-tab-pt  half-on-mobile"></div>
</div>
//  Turn off responsive behaviour
<div class="row">
<div class="portion  retain-layout-on-tab-ls  retain-layout-on-tab-pt  retain-layout-on-mobile"></div>
</div>

Responsive visibility

There are also special classes to handle visibility across various device resolutions.

Simply add the .show-only-on- or .hide-on- prefix and the device suffix to the element.

//  Visible on tablets and desktops
<div class="hide-on-mobile"></div>
//  Visible on mobiles and desktops
<div class="hide-on-tab-pt hide-on-tab-ls"></div>
//  Visible on tablets and mobiles
<div class="hide-on-desktop"></div>
//  Visible on mobiles and desktops
<div class="hide-on-tab-pt hide-on-tab-ls"></div>

Gutter sizing

The .portion divs come with a bit of padding on their left and right, which essentially act as the gutters in the grid layout. You can increase or decrease this padding to change the gutter accordingly.

.row.large-gutters

.row

.row.small-gutters

.row.no-gutters

Typography

Typography is an important part of FICTOAN, and there are myriad classes focused just on typography. To keep things free, the framework uses fonts from Google Fonts, handpicked beauties that you can quickly use in your projects.

There are three typefaces, each for one category commonly used on web pages— one sans for body, one serif for fancy occasions, and one geometric monospace for displaying code.

Type scaling

h1

I’m just your type.

h2

I’m just your type.

h3

I’m just your type.

h4

I’m just your type.

h5
I’m just your type.
h6
I’m just your type.

Apart from this, there are also generic font-size classes you can use anywhere. They range from tiny, small, normal, large, and huge. The class names are pretty simple— just use .text-tiny, .text-large and so on.

Type helpers

As you can see, classes are pretty straight-forward and intuitive. Just slap these onto any text-element and they’ll work.

Syntax highlighting

There’s a custom code colour theme available in FICTOAN. Right now it supports HTML, CSS, SCSS, JS, JSON and PHP.

While the colour theme itself is custom-made, it uses PrismJS, a kickass plugin for language identification and highlighter.

There are two themes— one light and one dark. Hit the button to switch between them. For the dark theme, just add .bg-dark class to the pre element.

JSON

"glossary": {
    "title": "example glossary",
    "GlossDiv": {
        "title": "S",
        "GlossList": {
            "GlossEntry": {
                "ID": "SGML",
                "SortAs": "SGML",
                "GlossTerm": "Standard Generalized Markup Language",
                "Acronym": "SGML",
                "Abbrev": "ISO 8879:1986",
                "GlossDef": {
                    "para": "A meta-markup language, used to create.",
                    "GlossSeeAlso": ["GML", "XML"]
                },
                "GlossSee": "markup"
            }
        }
    }
}
                        

JS

'use strict';

    // In production, the bundled pdf.js shall be used instead of SystemJS.
    Promise.all([System.import('pdfjs/display/api'),
    System.import('pdfjs/display/global'),
    System.resolve('pdfjs/worker_loader')])
    .then(function (modules) {

        var api = modules[0], global = modules[1];

        global.PDFJS.workerSrc = modules[2];

        api.getDocument('helloworld.pdf').then(function (pdf) {

            pdf.getPage(1).then(function (page) {
                var scale = 1.5;
                var viewport = page.getViewport(scale);

                var canvas = document.getElementById('the-canvas');
                var context = canvas.getContext('2d');
                canvas.height = viewport.height;
                canvas.width = viewport.width;

                var renderContext = {
                    canvasContext: context,
                    viewport: viewport
                };

                page.render(renderContext);
            });
        });
    });
                        

PHP

<?
    class Address {
        protected $city;

        public function setCity($city) {
            $this->city = $city;
        }

        public function getCity() {
            return $this->city;
        }
    }

    class Person {
        protected $name;
        protected $address;

        public function __construct() {
            $this->address = new Address;
        }

        public function setName($name) {
            $this->name = $name;
        }

        public function getName() {
            return $this->name;
        }

        public function __call($method, $arguments) {
            if (method_exists($this->address, $method)) {
                return call_user_func_array(
                    array($this->address, $method), $arguments);
            }
        }
    }
?>
                        

HTML

<!doctype html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!--And a clean, simple sans typeface-->
    <link href="https://fonts.googleapis.com/css?family=Work+Sans:400,700" rel="stylesheet">

    <link rel="stylesheet" href="css/main.css">

    <title>FICTOAN Forms</title>
</head>

<body>
    <div class="row margin-top-medium">
        <h6 class="margin-bottom-small">Login</h6>

            <form class="ff-form">
                <div class="ff-input-unit">
                    <input class="ff-input needs-validation input-success" type="text" id="first_name" name="first_name" placeholder=" " required/>
                    <label for="first_name">First Name</label>
                </div>

                <div class="ff-input-unit">
                    <input class="ff-input needs-validation" type="password" id="password" name="password" required placeholder=" " pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}" />
                    <label for="password">Password</label>
                    <p class="input-rules">Your password must be at least 6 characters as well as contain at least one uppercase, one lowercase, and one number.</p>
                </div>

                <input class="ff-button shape-rounded bg-indigo shadow-hard full-width" type="submit" value="Sign Up" />
            </form>
        </div>
    </div>
</body>
</html>
                
                    

SCSS

body {
    font-family      : $fontSans;
    color            : $bodyFontColor;
    line-height      : 1.6;
    word-wrap        : normal;
    text-rendering   : optimizeLegibility;
}

h1, h2, h3, h4, h5, h6 {
    font-weight : inherit;
    line-height : 1.2;
    margin      : 0;
}

h1 { font-size : $baseFontSize*pow($scaleFactor, 8); }
h2 { font-size : $baseFontSize*pow($scaleFactor, 6); }
h3 { font-size : $baseFontSize*pow($scaleFactor, 4); }
h4 { font-size : $baseFontSize*pow($scaleFactor, 3); }
h5 { font-size : $baseFontSize*pow($scaleFactor, 2); }
h6 { font-size : $baseFontSize*pow($scaleFactor, 1); }

@import "compass/reset";

// variables
$colorGreen     : #008000;
$colorGreenDark : darken($colorGreen, 10);

@mixin container {
    max-width: 980px;
}

// mixins with parameters
@mixin button($color:green) {
    @if ($color == green) {
        background-color: #008000;
    }
    @else if ($color == red) {
        background-color: #B22222;
    }
}

div,
.navbar,
#header,
input[type="input"] {
    display     : block;
    width       : auto;
    margin      : 0 auto;
    font-family : "Helvetica Neue", Arial, sans-serif;
}

.row-12 > [class*="spans"] {
    border-left: 1px solid #B5C583;
}

@for $i from 1 through 5 {
    .span#{$i} {
        width: 20px*$i;
    }
}

@mixin mobile {
  @media screen and (max-width : 600px) {
    @content;
  }
}
                    

CSS

@import "fictoan/base/reset-fictoan";

code[class*="language-"],
pre[class*="language-"] {
    color                  : #51514F;
    background             : hsla( 200, 100%,  50%);
    text-align             : left;
    white-space            : pre;
    word-spacing           : normal;
    word-break             : normal;
    word-wrap              : normal;
    line-height            : 1.5;
    -moz-tab-size          : 4;
         tab-size          : 4;
    -webkit-hyphens        : none;
       -moz-hyphens        : none;
        -ms-hyphens        : none;
            hyphens        : none;
    font-variant-ligatures : none;
}

/* Code blocks */
pre[class*="language-"] {
    padding  : 1em;
    margin   : .5em 0;
    overflow : auto;
}

pre[class*="language-"],
:not(pre) > code[class*="language-"] { background : #eceef7; }

/* Inline code */
:not(pre) > code[class*="language-"] {
    padding       : .1em;
    border-radius : .3em;
    white-space   : normal;
}

pre:hover { transition: all 0.2s #ff8899; }

pre::after { content: "&"; }

/*  For screens FROM 900px width and UPWARD  */
@media all and (min-width : 900px) {
    .all-content { padding : 0 8vw; }
}
                        

Colour

FICTOAN uses the HSL colour format, and you should too. You can read more about why, here. FICTOAN comes with a multiple colour schemes to use right out of the box.

FICTOAN colour scheme

Tint of primary hue

$colorTint hsl( 42, 16%, 96%);

PRIMARY HUE

$colorHue hsl( 42, 100%, 64%);

Analogue of primary hue

$colorAnalogue hsl( 32, 100%, 64%);

Shade of primary hue

$colorShade hsl( 0, 0%, 16%);

Accent

$colorAccent hsl( 164, 72%, 36%);

Colour list

Here’s a list of colours that you can use. Each of these can be used as a background, text or fill class suffix. Use bg-, text- or fill- as a prefix in your class name, followed by any of the colours listed below.

You can use these prefixes with the main colour scheme too. Just add the appropriate colour term as a suffix.

<div class="bg-indigo-90"></div>
<p class="text-pistachio-40"></p>
<svg class="fill-teal"></svg>

<h3 class="text-shade"></h3>
<div class="bg-analogue"></div>

red

red-90

red-80

red-70

red-60

red-50

red-40

red-30

red-20

red-10

orange

orange-90

orange-80

orange-70

orange-60

orange-50

orange-40

orange-30

orange-20

orange-10

amber

amber-90

amber-80

amber-70

amber-60

amber-50

amber-40

amber-30

amber-20

amber-10

yellow

yellow-90

yellow-80

yellow-70

yellow-60

yellow-50

yellow-40

yellow-30

yellow-20

yellow-10

pistachio

pistachio-90

pistachio-80

pistachio-70

pistachio-60

pistachio-50

pistachio-40

pistachio-30

pistachio-20

pistachio-10

green

green-90

green-80

green-70

green-60

green-50

green-40

green-30

green-20

green-10

teal

teal-90

teal-80

teal-70

teal-60

teal-50

teal-40

teal-30

teal-20

teal-10

cyan

cyan-90

cyan-80

cyan-70

cyan-60

cyan-50

cyan-40

cyan-30

cyan-20

cyan-10

sky

sky-90

sky-80

sky-70

sky-60

sky-50

sky-40

sky-30

sky-20

sky-10

blue

blue-90

blue-80

blue-70

blue-60

blue-50

blue-40

blue-30

blue-20

blue-10

indigo

indigo-90

indigo-80

indigo-70

indigo-60

indigo-50

indigo-40

indigo-30

indigo-20

indigo-10

violet

violet-90

violet-80

violet-70

violet-60

violet-50

violet-40

violet-30

violet-20

violet-10

purple

purple-90

purple-80

purple-70

purple-60

purple-50

purple-40

purple-30

purple-20

purple-10

pink

pink-90

pink-80

pink-70

pink-60

pink-50

pink-40

pink-30

pink-20

pink-10

crimson

crimson-90

crimson-80

crimson-70

crimson-60

crimson-50

crimson-40

crimson-30

crimson-20

crimson-10

brown

brown-90

brown-80

brown-70

brown-60

brown-50

brown-40

brown-30

brown-20

brown-10

slate

slate-90

slate-80

slate-70

slate-60

slate-50

slate-40

slate-30

slate-20

slate-10

grey

grey-90

grey-80

grey-70

grey-60

grey-50

grey-40

grey-30

grey-20

grey-10

black

white

transparent

Inputs

A sample form

Please enter a valid email address

At least 6 characters long

I prefer

I like

I’m from

A form takes the full width of its parent, so a form inside a portion.one-third div will be 33% of the page width.

Form elements are wrapped within a .ff-form class parent. You can use .row and .portion within this form to control the layout of the elements. Form elements are wrapped individually by a .ff-form-unit div to ensure consistent spacing and margins.

<form class="ff-form">
    // Some element
    <div class="ff-form-unit"></div>

    // Two form elements side-by-side
    <div class="row ff-form-multi-unit">
        <div class="portion half">
            <div class="ff-form-unit"></div>
        </div>

        <div class="portion half">
            <div class="ff-form-unit"></div>
        </div>
    </div>

</form>

Text input

Text inputs come with simple styling and floating labels for placeholders. Text inputs need a class of .ff-input for their styling and behaviour. Make sure you add the placeholder attribute with a single space as its value, this is what makes the floating labels work. Also include the required tag to add the asterisk.

Each .ff-input is followed immediately by a label element, with a for attribute that matches the id of the text input.

<div class="ff-form-unit">
    <input class="ff-input" id="first-name" placeholder=" " pattern="{1,}$" required/>
    <label for="first-name">First name</label>
</div>
Input validity

You can also check for input validity using regular expressions within the pattern attribute. Add the .needs-validation class to the .ff-input, and also the appropriate regex.

You can also add a p element with a .input-help class to appear as a prompt beneath the input field. Invalid fields get a red border, and the prompt is again displayed on focus. Complete the field to see for yourself.

At least 6 characters long

// Atleast 6 characters long
<div class="ff-form-unit">
    <input class="ff-input needs-validation" pattern="^.{6,}$" type="password" id="password" placeholder=" " required/>
    <label for="password">Password</label>
    <p class="input-help">At least 6 characters long</p>
</div>

Checkboxes

Each checkbox is individually wrapped in a .ff-checkbox div, and has a input checkbox, followed by a label. Just make sure to add an id for the checkbox and the for attribute for the label.

I like

<div class="ff-form-unit">
    <div class="row">
        <div class="portion one-fifth">
            <p class="no-margin">I like</p>
        </div>

        <div class="portion four-fifths">
            <div class="ff-checkbox">
                <input type="checkbox" id="checkbox-2">
                <label for="checkbox-2">books</label>
            </div>

            <div class="ff-checkbox">
                <input type="checkbox" id="checkbox-1">
                <label for="checkbox-1">movies</label>
            </div>

            <div class="ff-checkbox">
                <input type="checkbox" id="checkbox-3">
                <label for="checkbox-3">comics</label>
            </div>
        </div>
    </div>
</div>

Switches

Switches are just restyled checkboxes, just to look different. The markup is pretty similar to the checkbox, except that the parent now has a class of .ff-switch.

<div class="ff-switch">
    <input type="checkbox" id="remember-toggle"/>
    <label for="remember-toggle">Remember me</label>
</div>

Radio buttons

Radio buttons are also similar to the checkbox, just change the parent div to a .ff-radio class, and add a name attribute to group a set of radio buttons.

I prefer

<div class="ff-form-unit">
    <div class="row">
        <div class="portion one-fifth">
            <p class="no-margin">I prefer</p>
        </div>

        <div class="portion four-fifths">
            <div class="ff-radio">
                <input type="radio" id="radio-1" name="radioset-1" />
                <label for="radio-1">cats</label>
            </div>

            <div class="ff-radio">
                <input type="radio" id="radio-2" name="radioset-1" />
                <label for="radio-2">dogs</label>
            </div>

            <div class="ff-radio">
                <input type="radio" id="radio-3" name="radioset-1" />
                <label for="radio-3">birds</label>
            </div>
        </div>
    </div>
</div>

Select options

Select dropdowns come with a .ff-select class, again with a .ff-form-unit parent.

I’m from

<div class="ff-form-unit">
    <div class="row">
        <div class="portion one-fifth">
            <p class="no-margin">I’m from</p>
        </div>

        <div class="portion four-fifths">
            <select class="ff-select show-inline" title="example-select" required>
                <option value="" hidden>Select one</option>
                <option value="1">Asia</option>
                <option value="3">Australia</option>
                <option value="2">Europe</option>
                <option value="4">North America</option>
                <option value="5">South America</option>
            </select>
        </div>
    </div>
</div>

Buttons

Buttons come with a .ff-button class, and myriad other options to mix and match. You can add them as an input element as well as an anchor tag.

Like most elements in FICTOAN, buttons too are modularly styled, which means you can change their look and feel just by adding classes.

Simple button

Plain button, just text colour. Default is text-hue. Use any class from the list of colours.

<a class="ff-button"></a>

<a class="ff-button text-indigo-80"></a>
Background

Button with background and text colour, again choose any colour from the list.

In the ff-variables file, you can edit $buttonGradientStartColour and $buttonGradientEndColour to create a button with a gradient background. Default is $colourHue and $colourAnalogue

<a class="ff-button bg-pistachio-60 text-green-90">Click me</a>

<a class="ff-button border-green-80 text-green-90">Click me</a>

<a class="ff-button border-green-80 bg-pistachio-60 text-green-90">Click me</a>

<a class="ff-button bg-gradient text-white">Click me</a>
Sizes

Button sizes, from size-tiny to size-large. For a normal size, don’t add a size class.

<a class="ff-button size-tiny bg-blue-80 text-white">Click me</a>

<a class="ff-button size-small bg-blue-80 text-white">Click me</a>

// Normal size
<a class="ff-button bg-blue-80 text-white">Click me</a>

<a class="ff-button size-large bg-blue-80 text-white">Click me</a>

<a class="ff-button size-huge bg-blue-80 text-white">Click me</a>
Shape

Button with background, text colour and shaped edges.

The circular button is a standard 64×64, but you can change the size of the icon inside.

// Rounded edges
<a class="ff-button shape-rounded bg-teal-70 text-white"></a>

// Curved edges
<a class="ff-button shape-curved bg-teal-70 text-white"></a>

// Circular button
<a class="ff-button shape-circular bg-teal-70">
<img class="icon-medium" src="icons/icon-cloud.svg">
</a>
Shadow

Button with shadows. There are three varieties.

// Mild shadow
<a class="ff-button shape-rounded bg-teal-70 text-white shadow-mild">Click me</a>

// Hard shadow
<a class="ff-button shape-rounded bg-teal-70 text-white shadow-hard">Click me</a>

// Soft shadow
<a class="ff-button shape-rounded bg-teal-70 text-white shadow-soft">Click me</a>
Tags

You can also create tag pills. Include a with-delete class to add a × on the right.

<a class="ff-pill size-large shape-curved bg-orange-80 text-white text-regular">kiwi</a>
<a class="ff-pill with-delete size-large shape-curved bg-orange-80 text-white text-regular">kiwi</a>

So, basically, you can combine all of the above to create this monstrosity.

<a class="ff-button size-large shape-curved bg-gradient border-cyan-80 text-indigo-40 shadow-soft">This is fine</a>
States

And finally, you can create a disabled button with a simple disabled attribute in HTML. This will render the button unclickable, over-ride shadow classes, and reduce the opacity.

<a class="ff-button" disabled>Can’t click me, bro</a>

Add a .loading class to display a simple CSS spinner within the button. This will also render the button unclickable and remove shadows.

<a class="ff-button with-loader shape-curved bg-pink-90 text-white shadow-hard">Can’t click me</a>

Progress bar

Progress bars use the HTML5 progress element, rather than a purely CSS styled div. You can also change the title of the progress bar in HTML, and the value to dynamically change by getting the value attribute via JS.

You can change the $progressBarBG and $progressBarFill colour values in the ff-variables file. Defaults are $colorTint and $colorHue respectively.

Download

40%

<p class="progress-bar-title">Download</p>
<p class="progress-bar-value">via JS</p>
<progress class="ff-progress-bar" value="40" max="100"></progress>

Components

Header

The header is a simple horizontal bar on the top of the page, which displays a logo on the left, and a list of links on the right.

Reduce the window width here to check how it behaves on smaller screens.

Structure

• The .ff-header is 56px tall.

• The first bit is the #header-logo, which sits on the left and takes up the entire height of the header. The image inside is defined in HTML.

• Next is the checkbox to show/hide the menu in the mobile view. The actual checkbox element is hidden, and the label is an hamburger icon, with an .icon-small class. This is hidden up till 600px viewport width.

• Then comes the nav.ff-nav. It is immediately succeeded by an ul element. Add li elements with an a tag inside, and you’re good to go. You can add buttons in here, too.

<header class="ff-header bg-grey-10 shadow-hard">
    <div id="header-logo">
        <img src="images/fictoan-logo.svg">
    </div>

    <label for="menu-toggle" class="links-toggle">
        <img class="icon-small" src="icons/icon-menu.svg">
    </label>
    <input type="checkbox" id="menu-toggle"/>

    <nav class="header-links">
        <ul>
            <li class="nav-item">
                <a>Link 1</a>
            </li>
            <li class="nav-item">
                <a class="ff-button shape-rounded shadow-hard bg-green text-white">Button 1</a>
            </li>
            <li class="nav-item">
                <a>Link 2</a>
            </li>
            <li class="nav-item">
                <a>Link 3</a>
            </li>
            <li class="nav-item">
                <a>Link 4</a>
            </li>
        </ul>
    </nav>
</header>
Position

THe default behaviour of the header is to scroll along with the page. To make the header stick to the top of the page when scrolling, add a .fixed-on-top class to the header.

Want it to stick to the bottom instead? Add a .fixed-on-bottom class. Take care to add a bit of margin to the bottom-most body element to avoid overlapping.

Styling

Basic styling is done by adding classes to the .ff-header element in HTML. You can add background classes and shadow classes. Default is bg-grey-10 and shadow-hard.

There are a few variables you can tweak to change the look and feel of the header.

$headerLinkBG

Changes the background colour of the links on the right. More evident in the mobile view. Default is $colorGrey-10.

$headerLinkColor

Changes the text colour of the links. Default is $colorShade.

$headerLinkHoverColor

Changes the text colour of the links on hover. Default is $colorHue.

$navItemBorderColor

Draws a 1px line between the links in mobile view. Default is $colorGrey-20.

Responsiveness

On screens less than 600px wide, the .ff-nav element is hidden, and is replaced by the hamburger icon. Tapping this icon slides open the list of links, stacked vertically.

The logo remains on the left, unaffected by this rearrangement of elements.

Tabs

Tabs in FICTOAN are CSS-only, and uses the input-radio hack to show and hide content within the tabs.

Tab 01 content

Tab 02 content

Tab 03 content

Tab 05 content

Structure

The entire tabs section goes into a .ff-tabs-wrapper parent div. Each tab component is made up by three elements— The radio button which works as a toggle, a label to display the name of the tab, and finally, the content of the tab.

The radio buttons have an unique ID of #ff-tab-<number> and a ff-tabs name attribute. Its sibling label has an ID of #ff-tab-label-<number> and a for attribute that matches the radio input.

Then comes along a .ff-tabs-content, which nicely wraps all the content of the tab together. In this way, you can add as many tabs as you need. You can even nest them within each other, as long as you keep the name attribute unique to each group.

Add the checked value to the tab you wanted activated by default.

<div class="ff-tabs-wrapper">
    <input id="ff-tab-1" type="radio" name="ff-tabset-1" checked />
    <label class="ff-tab-label" for="ff-tab-1">Tab One</label>
    <div class="ff-tab-content">
        <p>Tab 01 content</p>
    </div>
    
    <input id="ff-tab-2" type="radio" name="ff-tabset-1" />
    <label class="ff-tab-label" for="ff-tab-2">Tab Two</label>
    <div class="ff-tab-content">
        <p>Tab 02 content</p>
    </div>
    
    <input id="ff-tab-3" type="radio" name="ff-tabset-1" />
    <label class="ff-tab-label" for="ff-tab-3">Tab Three</label>
    <div class="ff-tab-content">
        <p>Tab 03 content</p>
    </div>

    <input id="ff-tab-4" type="radio" name="ff-tabset-1" />
    <label class="ff-tab-label" for="ff-tab-4">Tab Four</label>
    <div class="ff-tab-content">
        <p>Tab 04 content</p>
    </div>

    <input id="ff-tab-5" type="radio" name="ff-tabset-1" />
    <label class="ff-tab-label" for="ff-tab-5">Tab Five</label>
    <div class="ff-tab-content">
        <p>Tab 05 content</p>
    </div>
</div>
Variables
Variable Default value
$activeTabLabelBG $colorWhite
$activeTabLabelTextColor $colorShade
$inactiveTabLabelBG $colorGrey-20
$inactiveTabLabelHoverBG $colorGrey-10
$inactiveTabLabelTextColor $colorGrey-70
$tabsBorderColor $colorGrey-30

Sidebar

The sidebar is a slightly more complex component, like the one you’re on the left. It is a fixed-width div with collapsible, nested folders and sub-links.

Below is the markup for the sidebar setup. The sidebar is 240px when expanded, and 48px when collapsed.

body.page-with-sidebar

div.ff-sidebar-container

div.ff-content-container

div.clear-both

The layout pretty simple—
• Add a .page-with-sidebar class to the body.
• Within this add a .ff-sidebar-container and a .ff-content-container as siblings.
• Then, add a nav.ff-sidebar within .ff-sidebar-container.

There’s a div.clear-both div just before the close of body. That’s it.

<body class="page-with-sidebar">
    <div class="ff-sidebar-container">
        <nav class="ff-sidebar">
            //  Links and folders
        </nav>
    </div>

    <div class="ff-content-container">
        //  All your content
    </div>

    <div class="clear-both"></div>
</div>

Use simple anchor tags to list them as links on the sidebar. For folders, FICTOAN uses the HTML5 details and summary elements, as they offer the open and collapse functionality by default instead of the usual CSS checkbox hack or extra javascript.

A details tag with a summary immediate child creates a simple folder that opens and closes on click.

For a nested folder, just add another details tag within the previous details tag, as a sibling to the summary element. You can keep doing this infinitely, but take care not to get in too deep, you might get stuck in limbo forever.

<div class="ff-sidebar-container">
    <a id="sidebar-logo" class="sidebar-toggle">
        <img id="logo-big" src="images/fictoan-logo.svg" />
        <img id="logo-small" src="icons/favicon.png" />
    </a>

    <div class="sidebar-links">
        <!--  Single links  -->
        <a class="sidebar-link" href="#">
            <span>
                <svg></svg>
            </span>
            <label>Label text</label>
        </a>

        <!--  Folder  -->
        <details>
            <summary>
                <a class="sidebar-link" href="#"></a>
            </summary>
            <a class="sidebar-link" href="#"></a>
            <a class="sidebar-link" href="#"></a>
        </details>

        <!--  Folder with nested sub-folder  -->
        <details>
            <summary>
                <a class="sidebar-link" href="#"></a>
            </summary>
            <a class="sidebar-link" href="#"></a>
            <a class="sidebar-link" href="#"></a>
            <details>
                <summary>
                    <a class="sidebar-link" href="#"></a>
                </summary>
                <a class="sidebar-link" href="#"></a>
                <a class="sidebar-link" href="#"></a>
            </details>
        </details>
    </div>
</div>

The sidebar opens and closes when you click the #sidebar-logo div.

The sidebar is 240px wide when open, and 48px when collapsed. When collapsed, you can still click on the icons to navigate to the corresponding div.

//  Toggle sidebar  ===================================================
var wrapper = document.querySelector(".page-with-sidebar");
var toggler = document.querySelectorAll(".sidebar-toggle");

for (var i = 0; i < toggler.length; i++) {
    toggler[i].addEventListener('click', function() {
        wrapper.classList.toggle("collapsed");
    });
}

//  Display labels when sidebar is collapsed  =========================
var sidebarLinkIcons = document.querySelectorAll(".ff-sidebar-container .sidebar-link > span");
    sidebarLinkIcons.forEach((elem) => {
        elem.onmouseover = function(e){
            var top          = this.getBoundingClientRect().top, 
                siblingLabel = elem.nextElementSibling;
            
            top = top + 12;
            siblingLabel.style.top = top + "px";
        };
    });
};

Add an a tag with an sidebar-logo id. Within this add two iamges, one with #logo-big and logo-small. The former is displayed when the sidebar is expanded, and the latter when it is collapsed. Ideal sizes for the bigger image is 240×80, and smaller, any square size will do.

<div class="ff-sidebar-container">
    <nav class="ff-sidebar">
        <a id="sidebar-logo">
            <img id="logo-big" src="path/to/image" />
            <img id="logo-small" src="path/to/image" />
        </a>
        ...
        //  Folders and links
    </nav>
</div>

Card

A card is a simple UI element that is best used to display disparate chunks of information. Their styling is done by simply adding classes.

Cards always take the full-width of the parent, and height matches the width.

Some element

<div class="ff-card">
    <p>Some element</p>
</div>
Background
<div class="ff-card"></div>
<div class="ff-card bg-teal-70"></div>
<div class="ff-card bg-slate-40"></div>
Shape
<div class="ff-card shape-rounded bg-amber-70"></div>
<div class="ff-card shape-curved bg-violet-70"></div>
<div class="ff-card shape-circular bg-pink-70"></div>
Circular cards

Circular cards are a bit different. They take the full-width of the parent containter, and they resize automatically to remain a circle.

Add a .circular-card-content to ensure your content remains centered inside the circle. But don’t to cram too much into it, though, it will overflow.

Text

An icon and text

//  Just text
<div class="portion one-sixth">
    <div class="ff-card shape-circular bg-grey-20">
        <div class="circular-card-content">
            <p>Text</p>
        </div>
    </div>
</div>

//  Icon or image
<div class="portion one-third">
    <div class="ff-card shape-circular bg-grey-20">
        <div class="circular-card-content">
            <img class="icon-medium" src="icons/icon-droplet.svg">
        </div>
    </div>
</div>

//  Icon and text
<div class="portion half">
    <div class="ff-card shape-circular bg-grey-20">
        <div class="circular-card-content">
            <img class="icon-medium" src="icons/icon-layers.svg">
            <p>An icon and text</p>
        </div>
    </div>
</div>
Shadow
<div class="portion one-third">
    <div class="ff-card shape-rounded bg-white shadow-mild"></div>
</div>

<div class="portion one-third">
    <div class="ff-card shape-curved bg-white shadow-hard"></div>
</div>

<div class="portion one-third">
    <div class="ff-card shape-circular bg-white shadow-soft"></div>
</div><
Padding
//  Huge padding
<div class="ff-card padding-huge shape-rounded bg-white shadow-hard">
    <p>Some random text to demonstrate padding within a card element.</p>
</div>
//  Large padding
<div class="ff-card padding-large shape-rounded bg-white shadow-hard">
    <p>Some random text to demonstrate padding within a card element.</p>
</div>
//  Medium padding
<div class="ff-card padding-medium shape-rounded bg-white shadow-hard">
    <p>Some random text to demonstrate padding within a card element.</p>
</div>
//  Small padding
<div class="ff-card padding-small shape-rounded bg-white shadow-hard">
    <p>Some random text to demonstrate padding within a card element.</p>
</div>
//  Tiny padding
<div class="ff-card padding-tiny shape-rounded bg-white shadow-hard">
    <p>Some random text to demonstrate padding within a card element.</p>
</div>
Examples
Checkout
<div class="ff-card shape-rounded shadow-soft">
    <img class="horizontally-center-this margin-bottom-tiny" src="images/round-profile.png">
    <h5 class="text-center no-margin-bottom">Caterina Murino</h5>
    <p class="text-center no-margin-top">Actress</p>

    <p class="text-center no-margin-bottom">Caterina Murino (born 15 September 1977) is an Italian actress from Sardinia. Murino was born in Cagliari, Sardinia, and initially wanted to be a doctor. She finished fourth in the 1996 Miss Italy contest.</p>

    <p class="text-center text-small text-grey-40">— From Wikipedia</p>

    <div class="row">
        <div class="portion half">
            <a><img src="icons/icon-edit.svg" class="icon-small show-inline margin-right-fixed"></a>
            <a><img src="icons/icon-activity.svg" class="icon-small show-inline"></a>
        </div>

        <div class="portion half">
            <a class="ff-button size-small shape-rounded bg-accent text-white shadow-hard pull-right">SAVE</a>
        </div>
    </div>
</div>

Table

FICTOAN also lets you style the ever-useful table tag with simple classes that you add to the appropriate element.

Default table

Here’s a typical default table. Start by adding .ff-table class to the main element.

Column 01 Column 02
Row-item 1 Row-item 2
Row-item 3 Row-item 4
Row-item 5 Row-item 6
Row-item 7 Row-item 8
Row-item 9 Row-item 10
<table class="ff-table">
    <thead>
        <tr>
            <th>Column 01</th>
            <th>Column 02</th>
        </tr>
    </thead>

    <tbody>
        <tr>
            <td>Row-item 1</td>
            <td>Row-item 2</td>
        </tr>
        <tr>
            <td>Row-item 3</td>
            <td>Row-item 4</td>
        </tr>
        <tr>
            <td>Row-item 5</td>
            <td>Row-item 6</td>
        </tr>
        <tr>
            <td>Row-item 7</td>
            <td>Row-item 8</td>
        </tr>
        <tr>
            <td>Row-item 9</td>
            <td>Row-item 10</td>
        </tr>
    </tbody>
</table>
Padding

Still too congested. Add a .padding-tiny class to the table. There are five padding sizes you can add— -tiny, -small, -medium, -large and -huge.

Column 01 Column 02
Row-item 1 Row-item 2
Row-item 3 Row-item 4
Row-item 5 Row-item 6
Row-item 7 Row-item 8
Row-item 9 Row-item 10
<table class="ff-table bordered padding-tiny">
</table>
Borders

Add a .bordered-rows or a .bordered-columns class to the table. Want both? Use .bordered-all.

You can change the colour of the border via the $tableBorderColor variable.

Column 01 Column 02
Row-item 1 Row-item 2
Row-item 3 Row-item 4
Row-item 5 Row-item 6
Row-item 7 Row-item 8
Row-item 9 Row-item 10
Column 01 Column 02
Row-item 1 Row-item 2
Row-item 3 Row-item 4
Row-item 5 Row-item 6
Row-item 7 Row-item 8
Row-item 9 Row-item 10
<table class="ff-table bordered-rows">
</table>

<table class="ff-table bordered-columns">
</table>
Column 01 Column 02
Row-item 1 Row-item 2
Row-item 3 Row-item 4
Row-item 5 Row-item 6
Row-item 7 Row-item 8
Row-item 9 Row-item 10
<table class="ff-table bordered-all">
</table>
Colours

Now for some stripes. Add a .striped class to the table.

Column 01 Column 02
Row-item 1 Row-item 2
Row-item 3 Row-item 4
Row-item 5 Row-item 6
Row-item 7 Row-item 8
Row-item 9 Row-item 10
<table class="ff-table bordered striped padding-tiny">
</table>

Alternatively, you can set individual row and text colours by adding classes. Hideous, but works. Go nuts!

Make sure you remove the .striped class if you wanna colour individually.

Column 01 Column 02
Row-item 1 Row-item 2
Row-item 3 Row-item 4
Row-item 5 Row-item 6
Row-item 7 Row-item 8
Row-item 9 Row-item 10
<table class="ff-table bordered padding-tiny">
    <thead class="bg-accent text-white">
        <tr>
            <th>Column 01</th>
            <th>Column 02</th>
        </tr>
    </thead>

    <tbody>
        <tr class="bg-blue-60 text-crimson-80">
            <td>Row-item 1</td>
            <td>Row-item 2</td>
        </tr>
        <tr class="bg-pistachio-90 text-brown">
            <td>Row-item 3</td>
            <td class="text-accent">Row-item 4</td>
        </tr>
        <tr>
            <td class="bg-crimson text-black">Row-item 5</td>
            <td class="bg-sky-70 text-indigo">Row-item 6</td>
        </tr>
        <tr>
            <td class="bg-grey-70 text-cyan"><strong>Row-item 7</strong></td>
            <td class="bg-slate text-hue"><strong>Row-item 8</strong></td>
        </tr>
        <tr>
            <td class="bg-brown-80 text-teal-40">Row-item 9</td>
            <td class="bg-pink text-amber-90">Row-item 10</td>
        </tr>
    </tbody>
</table>
Hovering

You can also change the background colour and text colour of a row on hover, by adding a .hoverable class. You can also change the $tableHoverableBG and $tableHoverableTextColor variables.

Column 01 Column 02
Row-item 1 Row-item 2
Row-item 3 Row-item 4
Row-item 5 Row-item 6
Row-item 7 Row-item 8
Row-item 9 Row-item 10
<table class="ff-table striped hoverable padding-tiny">
</table>
$tableHoverableBG        : $colorGreen-20;
$tableHoverableTextColor : $colorShade;
Table width

By default, tables take up as little space as possible. But add the .full-width class, and bam, it stretches to the width of the parent.

Column 01 Column 02
Row-item 1 Row-item 2
Row-item 3 Row-item 4
Row-item 5 Row-item 6
Row-item 7 Row-item 8
Row-item 9 Row-item 10
<table class="ff-table striped hoverable full-width padding-tiny">
</table>
Text sizing

Text size is inherited from the body, but you can change it with the text sizing classes. You can use the usual five sizing suffixes.

Column 01 Column 02
Row-item 1 Row-item 2
Row-item 3 Row-item 4
Row-item 5 Row-item 6
Row-item 7 Row-item 8
Row-item 9 Row-item 10
<table class="ff-table striped hoverable text-tiny padding-tiny">
</table>

<table class="ff-table striped hoverable text-large padding-tiny">
</table>
Variables
Variable Default value
$tableBG $colorWhite
$tableTextColor $colorShade
$tableBorderColor $colorGrey-40
$tableStripedHeaderBG $colorHue
$tableStripedCellBG $colorSlate-20
$tableHoverableBG $colorAmber-20
$tableHoverableTextColor $colorShade

Modal

The modal is a simple pop-up box that you can display with a JS function. It’s included in this modal as an example, but please modify it in your projects.

Show me the modal!
The modal is made of three divs—
• A parent .ff-modal-wrapper that contains the modal element. This is what you need to add an .ff-active class to display the modal.

• A .ff-modal-overlay, which forms the background of the modal window. You can change its colour and opacity via variables.

• And finally, a .ff-modal-content div, that contains the actual content in the pop-up. In the example, it holds a simple .ff-card element with a few items inside. There’s also a .close-modal div, with a cross icon that closes the modal on click.
<a data-modal="modal-01" class="js-open-modal">Show me the modal!</a>

<div id="modal-01" class="ff-modal-wrapper">
    <div class="ff-modal-overlay">
        <div class="ff-modal-content">
            <a class="close-modal js-close-modal"></a>
            // Modal content
        </div>
    </div>
</div>

This is handled by JS, included as a sample script here. I highly recommend you use your own methods for production.

The link or button used for triggering the modal needs a data-modal attribute with a value that matches the unique id of the modal you wish to display. Make sure it also has a .js-open-modal class as well. Clicking it will add an active class to the .modal-wrapper, making it visible.

To close a modal, there’s a a tag with two necessary .close-modal and .js-close-modal classes. Clicking on it removes the active class from the wrapper div, making it invisible again.

<a data-modal="modal-01" class="js-open-modal ff-button size-small shape-rounded bg-hue text-white shadow-hard">Show me the modal!</a>

<div id="modal-01" class="ff-modal-wrapper">
    // The rest of the modal
</div>
Variable Default value
$modalOverlayBG rgba($colorHue, 0.64)