Giter Club home page Giter Club logo

assembly's Introduction

Assembly

A CSS framework that makes the hard parts of building anything on the web easy. We define the hard parts as: managing class specificity, designing cross-browser form components that work well with each other, creating a harmonious typographic scale, maintaining a baseline grid, and keeping responsive designs simple.

For usage guidelines and documentation, check out https://labs.mapbox.com/assembly/.

Build Status

Browser support

Assembly targets modern versions of Chrome, Firefox, Safari, and Edge on desktop; Safari on iOS; and Chrome on Android.

Usage

See https://labs.mapbox.com/assembly/ for usage guidelines.

Migration

See our Migration guides to understand what changes you might need to make when upgrading Assembly in your project.

Custom Builds

Assembly exposes a JS module for creating custom builds. Why might you want to create a custom build?

  • You want to customize variables (like colors and font stacks) or media queries.
  • You want to append extra stylesheets that also use Assembly's variables and media queries.
  • You want to reduce file-size by picking and choosing the color variants you need.

buildUserAssets(outdir[, options])

Returns a Promise that resolves when all assets have been written to outdir.

const Assembly = require('assembly');
Assembly.buildUserAssets('path/to/my/outdir', myOptions)
  .then(() => /* something */)
  .catch((err) => /* handle error */);

Options, all of which are optional:

  • files: An array of file paths to stylesheets you would like to append to assembly.css. These will be processed through Assembly's PostCSS pipeline.

  • variables: An object whose properties will override and add to src/variables.json. Use this option to change or add variables. These variables are accessible in any stylesheets you append via the CSS custom properties syntax, e.g. var(--property-name).

  • mediaQueries: An object whose properties will override and add to src/mediaQueries.json. Use this option to change or add media queries. These media queries are accessible in any stylesheets you append via the CSS custom media query syntax, e.g. @media --media-query-name.

  • colorVariants: An object or array specifying the color variants you would like added to assembly.css. This is documented in detail below.

  • icons: An array of icons names to include in Assembly. Names correspond to file names in src/svgs/. Use this option to decrease the size of assembly.js by only including the icons you need.

  • browsersList: A Browserslist array to be used by Autoprefixer. Default:

    [
      'last 4 Chrome versions',
      'last 4 Firefox versions',
      'last 4 Safari versions',
      'last 2 Edge versions',
      'last 2 iOS versions',
      'last 2 Android versions',
      'not IE 11',
      'not dead'
    ]
    
  • quiet: Suppress logs.

colorVariants option

If the colorVariants value is an array, it must be an array of color names corresponding to variables. All components will have color variants generated for all colors in the array.

The following configuration specifies an array of default colors. All components will have these (and only these) color variants.

["red", "green-light"]

If the colorVariants value is an object, each property value must be an array of color names corresponding to variables. The property names designate which component each color array applies to:

  • default: These colors apply to all components that are not otherwise specified.
  • buttonFill: *-dark colors will not be used.
  • buttonStroke: *-dark colors will not be used.
  • inputTextarea: *-dark colors will not be used.
  • selectFill: *-dark colors will not be used.
  • selectStroke: *-dark colors will not be used.
  • checkbox: *-dark colors will not be used.
  • radio: *-dark colors will not be used.
  • switch: *-dark colors will not be used.
  • toggle: *-dark colors will not be used.
  • range: *-dark colors will not be used.
  • color
  • background
  • link: *-dark colors will not be used.
  • border
  • hoverShadow: Only lighten* and darken* colors will be used.
  • hoverBackground
  • hoverColor
  • hoverBorder

The following configuration specifies colors for individual components. In this configuration, every component not specified will have the default color variants; specified components will have their specified color variants; and switch and range components will have no color variants (only the default will be available).

{
  "default": ["lighten50", "lighten25", "gray"],
  "buttonFill": ["green", "purple"],
  "selectFill": ["green"],
  "background": ["orange", "yellow", "pink"],
  "link": ["orange"],
  "hoverShadow": ["lighten50"],
  "switch": [],
  "range": []
}

Development principles

Writing rules

Assembly strives for flat, single rule declarations and avoids overrides whenever possible. Declarations are marked as !important for classes whose names directly correspond with what they do — e.g. bg-blue, px12. This way they cannot be overridden and so are guaranteed to actually do what they say they do.

Naming classes

  • Keep names as short as reasonable.
  • Use real number values in utility class names to describe the value the utility class applies in cases where the number of utility classes describing a particular property could be unlimited. For example, .pt6 for padding-top: 6px instead an abstract scale like .pt-small or .pt-1.
  • If the number of utility classes describing a property is limited and the variants are about size, Assembly classes use the suffixes xl, l, m, s, sm.
  • Assembly provides a reset that will affect the entire page, but other than that reset none of its rules should affect the styling of elements that don't bear Assembly classes.

Media query class variants

Media query class variants (e.g. block-mm as a variant of block) are automatically generated and added to the CSS build with scripts/build-media-variants.js. If you want to generate media variants for a new class, or change which classes get media variants, you'll need to modify the lists in that file.

Development

Tools

Install and start

npm ci # Installs your `node_modules`

npm start # Builds everything, starts a dev server, rebuilds & reloads on changes

npm run build:js # Build SVGs and other JS

For other scripts, look in package.json.

Releasing

Development is done in the publisher-staging branch, but releases are made from the publisher-production branch. Here's how you cut a release:

  • From publisher-staging:
    • Document changes in the CHANGELOG.
    • Increment the version key in package.json and package-lock.json.
    • Make sure all this is committed, typically with a commit message like Prepare 0.8.0.
    • Merge these changes into the publisher-production branch. Conduct the following steps from publisher-production.
  • From publisher-production:
    • Create a tag. No message is necessary, since the changelog includes explanations of changes. For example: git tag -a 0.8.0 -m "".
    • Push the tag: git push --tags.
    • Publish the new version on npm: mbx npm publish
    • Deploy the changes. Talk to @mapbox/frontend-platform if you need help.

assembly's People

Contributors

adnanh avatar adrianababakanian avatar andrewharvey avatar andrewsepic avatar castledoor avatar chriswhong avatar danswick avatar davidtheclark avatar elifitch avatar emilymdubois avatar jfurrow avatar jingsam avatar katydecorah avatar kepta avatar manaswinidas avatar mayagao avatar samanpwbb avatar sarahkleins avatar tristen avatar vluisa avatar yuletide avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

assembly's Issues

Move in icon SVGs

The only SVGs we have right now are dummy icons I downloaded to get the icon system going. We'll need to real ones.

Icon system

Do we want to continue using an icon font, or has that worn on people?

I only know of one alternative that provides the same sizing/coloring flexibility (more, actually): I've had great success in the past with the icon system described here — create a file of <defs> and use icons with <use>. However, I know of two problems for our purposes:

In order to use the icon, you have to do something like this in HTML:

<svg><use xlink:href="#shape-codepen"></use></svg>

A little ugly. With React it's totally fine because you can create an Icon component. But we're not building this for React. Might be tolerable, though, if we all just keep a stiff upper lip. Looks like Material Design does this.

Another problem is that the SVG sprite file doesn't load itself, so base users would have to include a JS file or copy-paste some JS — OR if we are comfortable making base only work with JS enabled, we could deliver base.js instead of base.css and make that script load the CSS and the SVGs.

Target use-cases

As we rebuild base, lets build a set of 'ideal use cases' and make sure they work great. use-cases include:

  • Brochure page (like mapbox.com)
  • App with left-aligned toolbar and condensed form (like studio)
  • Data dashboard
  • Full-width signup form with lots of options
  • Blog feed with images that bleed out from left and right
  • Documentation site with scrolling left sidebar

pos- prefix on positioning rules or no?

Right now I have positioning rules that look like this:

/**
 * Positioning utility classes
 * @namespace Positioning
 * @memberof Utilities
*/
.fix { position: fixed; }
.abs { position: absolute; }

/*
Zero out positioning
*/
.top    { top: 0; }
.right  { right: 0; }
.left   { left: 0; }
.bottom { bottom: 0; }

so instead of pin-topright, you'd write abs top right. I think this is nice, but it sorta breaks the rules. abs pos-top pos-right would be more aligned with convention.

Aligning curly braces

By "aligning curly braces" I mean this:

.bg-blue   { background-color: #0077cc; }
.bg-purple { background-color: #5500cc; }

instead of this:

.bg-blue { background-color: #0077cc; }
.bg-purple { background-color: #5500cc; }

Here are some disadvantages, I think:

  • You have to do it.
  • It's easy to mess up but hard to automatically enforce.
  • Diffs are less useful when you add a new, longer-named class but end up changing several unrelated lines by one space because of the new positioning (if you remember).
  • You have to ask yourself questions about when to align what with what, e.g. after line breaks — instead of not thinking about it at all.

I don't know of any advantages (?).

So, I guess I'm in favor of using an easily-enforceable, no-thought-required convention of putting the curly brace one space after the selector. What do you think?

Concerns about multiple repos

I'm running into some troubles caused by the multiple-repository approach.

  1. The build process in place here in base-core is presumably going to have to be duplicated in base-mapbox. That's a pain, right? (cc @samanpwbb)
  2. I wonder if we should move the documentation generator code into this repository? That way we can
  • Use base v2 for its theme as we build it. It's kind of a weird problem for a CSS documentation generator, actually, that it might require CSS for a theme that breaks the documented CSS, or the other way around.
  • Not worry about genericizing.
  • Not worry about versioning.
    @tmcw

Do we think that open-sourcing parts of base is worth these troubles? Or do you see a way to make these troubles less troublesome?

Let's get serious about a class naming convention

We need to decide if we're serious about following through on #26 and other class naming convention proposals, and then get the linting to start passing. We're still committing code willy-nilly that we will just need to go back and modify later. Most of our CSS rules are simple enough that they're only worth writing the right way, once, rather than revisiting a bunch of times.

Here's our selector-class-pattern right now:

/^[a-z]+$|^[a-z]{3}-((?!md-|sm-|lg-)[a-z-]*)[0-9]*(-sm|-md|-lg)?$/

This says (I think):

  • Allow a single word, all lowercase, with no hyphens.
  • Anything with hyphens must start with a 3 character prefix (#26).
  • Sizes are suffixes, only allowed at the very end.
  • Numbers are also suffixes, only allowed at the end, but before sizes.

My impression is that the only part of this that might be controversial right now is the 3 character prefix (correct me if I'm wrong!).

@samanpwbb thought:

Being strict about 3 character rule will make rules easier to remember.

Agree? Disagree?

Let's hash this out before we produce a lot more code we'll have to revise. (Either way, we'll need to revise ... e.g. I'd change .icn classes to .icon if we drop this rule.)

Create a stylelint configuration

I think that everybody agreed it would be a good idea to use a linter (right?). stylelint is the open-source CSS linter that I created & lead-maintain. There are a lot of rules. I'm pretty sure it's the best around by a longshot (not much competition).

I suggest we start by copy-pasting stylelint-config-standard and then add, remove, and reconfigure rules as we work on the CSS together and find our groove.

(There are some editor plugins. I have experience using Atom's and it works great.)

How about universal position abbreviations l, t, r, b?

Of all the things I'm least excited to type in class names, left, top, right, and bottom top the list.

If we're thinking we might want to take an abbreviated approach to classnames (e.g. with the 3-character prefix), how about abbreviating these words everywhere they occur with single letters?

Even if we don't restrict the prefix or don't abbreviate many other things, maybe this one is work doing, if we're 100% consistent, since those words get repeated quite a lot?

to what extent should we add media query classes

We could potentially duplicate every class across every media query. Where do we draw the line? I'm adding some basic positioning and display classes:

.inline { display: inline; }
.block { display: block; }
.inline-block { display: inline-block; }
.flex { display: flex; }
.hidden { display: none; }

hidden-sm, inline-sm, block-sm, inline-block-sm definitely make sense... flex-sm less so, but maybe. Do we need to tackle this case-by case? Where do we draw the line?

Form elements

@mayagao is working on some design for this, I understand.

Here's a list of form elements I can think of:

  • Label
  • Input
  • Select
  • Text area
  • Radio button
  • Set of radio buttons (fieldset)
  • Checkbox
  • Set of checkboxes (fieldset)

Others?

I think we'll need regular and short styles.

We'll need disabled, hover, and focus states.

I know how we could use :checked to customize checkboxes and radio buttons, but that's going to require some kind of prescribed HTML pattern. Do people like the current pattern that requires the next sibling to be the label (esp. non-Studio folks)?

<!-- Next element must be the <label>  -->
<input id="checker" type='checkbox' class="frm-checkbox">
<label for="checker">Checkbox</label>

Build system

We talked about using Autoprefixer. That means we'll be running the CSS through a PostCSS pipeline — which means we could add other PostCSS plugins, if we want to.

There are a lot of PostCSS plugins, doing everything from approximating features of CSS spec drafts to all the stuff that Sass does. If something really annoys you about CSS and you can think of a way you think it should be done, that can probably happen with an existing or new PostCSS plugin.

Is anybody interested in any PostCSS plugins other than Autoprefixer?

(I want to hold off on offering my own opinions to listen to what others think.)

High level architecture

Base will be composed of at least two separate CSS stylesheets: base-core.css which will be in an open source repo, and base-mapbox.css which will be in a closed source repo at https://github.com/mapbox/base-mapbox.

The base-mapbox project will require base-core.css via NPM, and build base-combined.css. base-mapbox then will provide base-combined.css via NPM and also provide a hosted version of base-combined at mapbox.com/base-mapbox/{versionnumber}/base-combined.css.

This way, Mapbox team can easily take advantage of all of base without needing to reference two stylesheets or do any of the build steps themselves.

Find better fancy type font alternative

I found "Cabin" to be similar to Brandon but turns out it looks like a deflated version of Open Sans Bold. Ticketing as reminder to find something that is a little more visually appealing

Components

Consider anything that isn't a single declaration a component.

Inline components should:

  • be compostable into groups – i should be able to make a group with multiple buttons, a button and a text input, ect.
  • optional left or right aligned icons
  • optional left or right aligned labels
  • 3 sizes: 20px high, 30px high, 40px high
  • in some cases, combinable on a single element: a button checkbox should give me a checkbox that is visually styled like a button.

All form components should:

  • have hover, active, disabled, and focus states
  • be easy to nicely line up in a row, with labels and various form types, without hacky custom css. Look at studio's form UI for example. Will likely require flexbox layout.
  • built-in subtle animations that can be cancelled out with something like a no-animate class.

Definites:

  • Tooltips
  • Modals
  • Tabs
  • Tables
  • Buttons
  • Text input
    • text input with button
    • text input with icon
    • text input with spinner
  • textarea
  • checkboxes (i like checkboxes that can be combined with buttons for checkbox buttons)
  • rounded toggles
  • radio buttons
  • rage slider
  • select buttons
  • Video container for standard video sizes
  • Special layout classes (like right-bleed-image)
  • Navigation patterns
    • breadcrumb
    • underline links (like studio)
  • Lists (esp. with icons to left)
  • Loading spinner (large and small, compostable with form elements)

Maybes:

Define guiding principles

What rules do we all follow when writing styles for base.

  • Specifically define a class naming convention. Something like BEM but that also resembles existing base naming convention.

  • Only class selectors allowed.

  • Minimize classes that dramatically change the children are rendered (I.E. no more .dark).

  • More coming soon...

link styling should use underlines, at least inside prose

There's a problem with base's links, especially when used inside .dark class. They don't have enough contrast. I think defaulting to underlined links, at least in prose, and then providing another non-underlined link style would be best.

Documentation site design

  • Usage: how to get started
  • Principles: general info on how base is designed and how meant to be used.
  • Documentation:
    • Basic elements (divs, a, code, p, ul, img, ect)
    • Typography (text styling, or basic elements when inside .prose class)
    • Grid ( + also vertical tiles) #11
    • Sizing (width, height)
    • Position (absolute and fixed positioning, ect)
    • layout utilities (margin, padding, display, ect )
    • Theming utilities (borders, border radius, box shadows, ect)
    • Icons (base icons, multiple sizes)
    • Colors (all mapbox brand colors as both text and background colors)
    • state utilities (hover, active, .active, ect)
    • Components (forms, tooltips, modals, ect)
  • Examples (see #3)

The 'documentation' sections would be auto-generated from comments in css. Examples would not be.

Documentation generator

re-base should automatically generate documentation from CSS code comments. It should both parse keywords / tags like documentation.js, and also parse html inside comments into real html documentation.

Alternative to `.dark`

Base has a dark class that modifies almost everything else, from font color, to keylines, to default button styling. Instead of dark, do we simply offer many color options for everything, including text, and expect user to consistently use their, say, txt-white class everywhere?

A few border ideas

  • Should bor-all-* be reduced to bor-*? I think that might fit the convention elsewhere: we have pad-10 instead of pad-all-10.
  • How about bor-*-transparent? I find myself wanting to use that sometimes — usually when an element is only going to have a border in a certain state. Do others?
  • Do we want to allow people to put different colored borders on the same element? If not, we could very significantly reduce the number of rules required, I think.
  • Should uncolored classes, like bor-all-2, take currentColor (the equivalent of no specific color, e.g. 2px solid) instead of the dark color?

Problems with attribute selectors :(

Turns out the attribute selectors might be too clever after all ... I feel like I let some important things slip my mind.

I made a div with classes bor2-bottom-red bg-yellow, thinking that I'd get a yellow background and a red border. But instead I got a yellow border. This is because the rule [class^='bor'][class$='-yellow'] { border-color: #ffeb3b; } ends up targeting this element, whose class name starts does start with bor and does end with -yellow!

So that's a problem that might seem specific to the border selectors. But I realized some other problems:

  • We shouldn't use ^=, because that means the class attribute must start with the string we're targeting. It's not that a single class name starts with the string, but the whole attribute value.
  • By using *= we open ourselves to weird problems. Like ,*='col' could end up targeting my class colorize, and the selector *='bor' will end up targeting my class boring.
  • By using attribute selectors we are making the rules more difficult to override. I don't think you can override two selectors with a single class, for example.

Because of all the above, I'm in favor of banishing attribute selectors and just being explicit about our class names.

Thoughts?

state utilities

hovers, actives, focuses, as rules, detached from any specific component.

Master css requirements

The stylesheet we provide in base-core need to include the following features:

  • Standard CSS reset
  • Flexible, mobile-friendly grid system
  • Classes for styling all HTML5 form components
  • Base icon set classes
  • Custom Typographic scale using freely available fonts
  • Basic set of color fill classes
  • Style utility classes for keylines, borders, rounded corners, transparency, shadows, ect.
  • Layout utility classes for padding, margin, centering and alignment
  • Component classes for commonly used components (tooltips, popovers, modals, blockquotes, ect, loading spinner)
  • Syntax highlighting (?)
  • Animation classes (?)

The stylesheet we provide in mapbox-base needs to include the following features:

  • Classes for placing the Mapbox logo at various sizes onto the page
  • Mapbox brand color palette
  • Typography overrides using Mapbox's brand fonts
  • classes for mapbox customer logos. See https://github.com/mapbox/www.mapbox.com/tree/mb-pages/_includes/logos for how we handle logos now. (?)
  • classes for credit card icons (we have this in base now, not sure we need to keep them) (?)

Add theming utilities

  • border radiuses (3px, 6px, round left and right, round top and bottom, fully round)
  • keylines (multiple colors, 1px and 2px sizes)
  • shadows (multiple colors, sizes, intensities)

CSS sourcemaps

Right now we don't have sourcemaps coming out of the CSS processing pipeline. Because something nasty is going on.

Grid system

We're going to build our grid system using Flexbox. Mostly because it happily does what you'd expect: containers of variable heights flow evenly. I'm just going to get started using it for our column rules!

The goal is to create something like this:

screen shot 2016-12-05 at 3 41 14 pm

In a clean and efficient way using base. Establish a grid, be able to break out of the grid and still line up evenly against columns in the container.

Notes

Naming cols, col-2

A parent container cols defines the Flexbox properties how immediate child columns should operate. each column container has col- followed by the number it takes up.

Gutters cols-gut-10

Gutters provide proper spacing between the content within containers. If a gutter is defined it should create the spacing in-between each column and still be flush to the left and right of the parent container. Frameworks typically use negative margins to get around this. I'll look into other possibilities but will probably use a margin right with nth-child(Nn+N) selector to zero out margins on last elements.

Limiters

limiter name should be explicit by pixel width (i.e limiter-1500 where width is 1500px). There should be a handful of limiter widths we can use.

Breakpoints

Breakpoints supported are: mobile, tablet, & wide. Adapting to the number of columns you should see for each of these breakpoints should be explicit and to the choice of the content creator by a class naming convention like col-mobile-4.

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.