npm package: @hackandcraft/css-framework
Description: A starting point to customise Angular Material sytles, for Hack&Craft projects
Latest version: 7.1.1

# CSS Framework

[Hack&Craft](https://hackandcraft.com/insights) uses [Material Design](https://material.io/design/) as a design language on their projects, in conjunction with the [Angular Material](https://material.angular.io/guide/theming) library.

Angular Material library only provides color theming (no theming for font-size, font-weight, line-height, spacing…), so Angular Material theming is not enough.

This is why we created this CSS Framework, a starting point to customise Angular Material sytles for Hack&Craft projects.

Related resources:

- [GitHub repo](https://github.com/HackandCraft/hackandcraft-ng/tree/master/projects/css-framework)
- [npm package](https://www.npmjs.com/package/@hackandcraft/css-framework)
- [Pattern Library](https://hackandcraft-ng.hncdev.co.uk/css-framework)
- [Frontend Style Guide > CSS / Sass Style Guide](https://github.com/HackandCraft/frontend-style-guide/blob/master/css-sass-style-guide.md)

## Requirements

- npm
- Angular
- Angular Material library

## Install

1. Install CSS Framework package from your Angular project:

```
$ npm install @hackandcraft/css-framework
```

2. And then install your theme of choice<sup>(1)</sup>:

```
$ npm install @hackandcraft/theme-dulux
```

## Start the Pattern Library

In order to see the components page with the current themes available ("Pattern Library" from now on)<sup>(2)</sup>, just run this from the "hackandcraft-ng" repo:

```
$ ng serve
```

And then access the Pattern Library in: http://localhost:4200/css-framework

## How to create new themes

By default, agnostic theme settings comes out of the box with the framework. These are just "default" styles, not used in any client project.

To create a new client theme, follow these steps:

1. Create a new theme directory and the corresponding "\_settings.scss" file –with specific Sass variables– in "hackandcraft-ng/projects", overriding default theme settings (i.e. "hackandcraft-ng/projects/theme-name/scss/\_settings.scss").
2. Edit the "\_theme.scss" file in the project root, adding your new theme imports (i.e. "theme-name"):

```scss
@import "~@angular/material/prebuilt-themes/indigo-pink.css";
@import "../projects/css-framework/scss/settings";

#css-framework {
  @import "../projects/css-framework/scss/main.scss";

  &.theme-name {
    @import "../projects/theme-name/scss/settings";
    @import "../projects/css-framework/scss/main.scss";
  }

  &.another-theme-name {
    @import "../projects/another-theme-name/scss/settings";
    @import "../projects/css-framework/scss/main.scss";
  }

  // more themes...
}
```

3. Add some Sass variables in your "hackandcraft-ng/projects/theme-name/scss/\_settings.scss" file, to fit your client styles.
4. Add your new theme in "test-css-framework.component.ts" file, in order to make the theme available from the [Pattern Library](https://hackandcraft-ng.hncdev.co.uk/css-framework):

```ts
themes: Theme[] = [
  { title: "Default theme", class: "theme-default" },
  { title: "Akzo Nobel", class: "theme-akzo-nobel" },
  { title: "Dulux theme", class: "theme-dulux" },
  { title: "Name theme", class: "theme-name" },
  // more themes...
];
```

5. Once you're done, your "@hackandcraft/theme-name" can be published as npm package.

## Publish

CSS Framework and client themes are published as npm packages.

Some examples:

- [CSS Framework](https://www.npmjs.com/package/@hackandcraft/css-framework)
- [Akzo Nobel Theme](https://www.npmjs.com/package/@hackandcraft/theme-akzo-nobel)
- [Dulux Theme](https://www.npmjs.com/package/@hackandcraft/theme-dulux)
- More themes to come...

## Using Sass settings

- Use of `!default` flag in Sass variables is only necessary for the CSS Framework default/agnostic theme settings, so there's no need to use it in your "theme-name/\_settings.scss" file.
- If a variable is declared in your theme and assigned to another variable in the same file (known as "variable mapping"), the very last variable must be defined as well in order to work. Example:

In "../projects/css-framework/scss/settings"...

```scss
$fz-small: 14px !default;
$button-fz: $fz-small !default; // 14px
```

In "theme-name/\_settings.scss"...

This **won't work as expected**:

```scss
$fz-small: 12px;
// $button-fz value is 14px :(
```

This **will work**:

```scss
$fz-small: 12px;
$button-fz: $fz-small; // $button-fz value is 12px :)
```

**Important:** Keep this in mind to avoid unexpected results in your theme.

## Modifier classes

Some Angular Material components has been extended with [BEM](http://getbem.com/)<sup>(3)</sup> modifier classes (i.e. dialog sizes).

To use different dialog sizes, add a `cdk-overlay-pane--small` or `cdk-overlay-pane--large` modifier class to the `cdk-overlay-pane` element, with JS.

Small:

```html
<div id="cdk-overlay-0" class="cdk-overlay-pane cdk-overlay-pane--small">
  ...
</div>
```

Medium (default):

```html
<div id="cdk-overlay-0" class="cdk-overlay-pane">...</div>
```

Large:

```html
<div id="cdk-overlay-0" class="cdk-overlay-pane cdk-overlay-pane--large">
  ...
</div>
```

## Fonts and icons

Fonts used in the [Pattern Library](https://hackandcraft-ng.hncdev.co.uk/css-framework) won't be propagated to themes, so you must import your fonts of choice in your project choosing one of these methods:

### Setup Method 1. Using via Google Web Fonts

The easiest way to set up fonts for use in any web page is through Google Web Fonts. All you need to do is include a single line of HTML:

```html
<link
  href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700,800&display=swap"
  rel="stylesheet"
/>
```

Same thing applies to Material Icons font, if you plan to use icons:

```html
<link
  href="https://fonts.googleapis.com/icon?family=Material+Icons"
  rel="stylesheet"
/>
```

### Setup Method 2. Self hosting

For those looking to self host the web font, some additional setup is necessary. Host the font in a location, for example "your-project/src/assets/fonts", and add the proper CSS rules<sup>(4)</sup>.

The easiest way to go is to create a "fonts.scss" in your "your-project/src/" folder.

Example (in "fonts.scss"):

```scss
@font-face {
  font-family: "colour_sansregular";
  src: url($fonts-path+"colour_sans-regularWEB.eot");
  src: url($fonts-path+"colour_sans-regularWEB.eot?#iefix") format("embedded-opentype"),
    url($fonts-path+"colour_sans-regularWEB.woff") format("woff"),
    url($fonts-path+"colour_sans-regularWEB.ttf") format("truetype"), url($fonts-path+"colour_sans-regularWEB.svg#colour_sansregular")
      format("svg");
  font-weight: normal;
  font-style: normal;
}
```

And then use the font like this:

```css
font-family: "colour_sansregular", Arial, sans-serif;
```

Don't forget to edit your "angular.json" file, referencing your "fonts.scss" file:

```json
"styles": [
  "src/styles.scss",
  "src/fonts.scss"
],
```

## Other resources

- [Material Design](https://material.io/design/)
- [Angular Material](https://material.angular.io/guide/theming)
- [Material theme creation](https://speakerdeck.com/nadalsol/material-theme-creation)

---

> (1) If no theme is installed you'll get default/agnostic theme settings.
>
> (2) In order to see the styles properly, `id="css-framework"` and `class="theme-name"` has been added to the `<html>` tag in the [Pattern Library](https://hackandcraft-ng.hncdev.co.uk/css-framework) page.
>
> (3) Notice how we're using BEM for CSS class names, so please refer to our [Frontend Style Guide > CSS / Sass Style Guide](https://github.com/HackandCraft/frontend-style-guide/blob/master/css-sass-style-guide.md) for more details.
>
> (4) More info in [Material Icons Guide > Icon font for the web](https://google.github.io/material-design-icons/#icon-font-for-the-web).