GithubHelp home page GithubHelp logo

extendcss's Introduction

ExtendCSS

An experimental Utility CSS framework that pushes the limits of SASS to write CSS classes programatically.

Still in development

Inspired by Tailwind CSS, but made purely with SCSS, without Javascript or any other language.

What is a Utility CSS Framework?

It is a CSS Framework for rapid prototyping and layout. It is focused on providing you with utility classes that define specific CSS properties, like .bg-blue or .text-center.

This approach differs from frameworks Bootstrap that give you opinionated component classes that you then have to customize or apply themes to make them your own.

Utility classes give you more freedom to create and customize your UI any way you like while still helping you follow some structure:

<button class="bg-blue text-white p-y-2 p-x-4 rounded hover:bg-blue-darker">
    Click me!
</button>

@Extend mode

ExtendCSS also generates placeholder % classes that you can @extend to create your own components. So if all your buttons have the same classes you should consider them to a new style:

.btn {
    @extend %bg-blue, %text-white, %p-y-2, %p-x-4, %rounded, %hover\:bg-blue-darker;
}
<button class="btn">Click me!</button>

If you prefer this component approach and all you need are the placeholder % classes you can disable the regular . classes by setting the $generateClasses varialble to false on the main scss/_application.scss.

Generating classes programatically

To create classes programaticallty we use the make() mixin. It takes four parameters:

make($base, $properties, $values, $variants);
  1. $base: The base name for the class.

    $base: 'border';
    
    // .#{$base}-2 { … }
    
    .border-2 { border-width: 2px; }
  2. $properties: The css property you're modifying with the class. This can be a string for something straightforward like background-color or a key/value list generated multiple modifiers classes:

    $properties: (
        't': 'border-top-weight', 
        'b': 'border-bottom-weight',
        …
    );
    
    // .border-#{$key}-2 { #{$value}: 2px; }
    
    .border-t-2 { border-top-weight: 2px; }
    .border-b-2 { border-bottom-weight: 2px; }

    The property value can also be a list for multiple properties:

    $properties: (
        'y': ('border-top-width', 'border-bottom-width'),
        …
    );
    
    // .border-#{$propertyKey}-2 { #{$propertyValue}: 2px; }
    
    .border-y-2 { 
        border-top-width: 2px; 
        border-bottom-width: 2px; 
    }

    If the key is 'default' it won't be used in the class name:

    $properties: (
        'default': 'border-width',
        't': 'border-top-weight',
        …
    );
    
    .border-2 { border-width: 2px; }
    .border-t-2 { border-top-width: 2px; }
  3. $values: A key/value list with the class modifier and the property value.

    $value: (
        '2': '2px',
        …
    );
    
    // .border-#{$key} { border-width: #{$value}; }
    
    .border-2 { border-width: 2px; }
  4. $variants: Variants are special prefixes to your classes. There are three types of variants:

    1. Special selector variants: hover, active, first-child
    $variants: ('hover', 'active', …);
    
    // .#{$variant}:bg-blue
    
    .bg-blue { background-color: #00F; }
    .hover\:bg-blue {
        &:hover { background-color: #00F; }
    }
    <button class="bg-blue hover:bg-red active:bg-green">
        I'm red on hover, and green on click
    </button>
    1. Screen size variants: xs, md, lg
    $responsive: (
        'sm': '(min-width: 576px)',
        'md': '(min-width: 768px)',
        …
    );
    $variants: ('hover', $responsive);
    
    // .#{$responsiveKey}:bg-blue
    
    @media (min-width: 768px) {
        .xs\:bg-blue { background-color: #00F; }
    }
    <button class="bg-blue md:bg-red lg:bg-green">
        I'm blue on phones, red on tablets, green on desktop
    </button>
    1. Parent target variants: group-hover

    Sometimes you need to change the style of an element when you hover their parent. This is where group-hover is helpful:

    $variants: ('group:hover .group-hover', …);
    
    // .#{variant}:bg-blue
    
    .group:hover .group-hover\:bg-blue { … }
    <div class="group border p-4 hover:bg-blue">
        <p class="group-hover:text-white">Some text</p>
        <button class="bg-blue text-white group-hover:bg-white group-hover:text-blue">
            Click me
        </button>
    </div>

    You can use this pattern in creative ways to create other parent variants too:

    $variants: ('.dropdown:focus .dropdown-open', …);
    <div class="dropdown outline-none" tabindex="0">
        <button class="p-2">Options ▾</button>
        <div class="p-4 border hidden absolute dropdown-open:block">
            Dropdown menu…
        </div>
    </div>

Bringing it all together

The main SASS file (scss/_application.scss) imports the functions and different config files we're going to need.

Then it defines a list of $classes we want to loop through and run the make() mixin.

// ($base, $properties, $values, $variants),
$classes: (
    ('border', $borderWidthProperties, $borderWidths, $borderWidthVariants),
    ('border', 'border-color', $borderColors, $borderColorVariants),
    ('border', 'border-style', $borderStyles, $borderStyleVariants),
    ('rounded', $borderRadiusProperties, $borderRadius, $borderRadiusVariants),
    …
);

Customization

Take this line as an example:

('border', 'border-color', $borderColors, $borderColorVariants),

The variables $borderColors and $borderColorVariants are defined in the sass/config/borders.scss file, and you can customize them there if needed.

By default $borderColors is equal to the main list of $colors. If you don't need colorful borders in your UI you can change that variable to only the border colors you need, for example changing it to ('faded': 'rgba(0,0,0,0.1)') will generate a single .border-faded class.

Likewise $borderVariants by default will generates lots of variants, if you don't plan on changing border colors on hover, or depending on screen size, then you can edit that variable to remove those variants. If you need no variants at all you can set it equal to an empty list ().

extendcss's People

Contributors

fabiogiolito avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.