CSS in SPFx

Introduction

Styling is the most important part of web development. In this article, we will learn how to efficiently consume CSS in our Typescript file.

CSSType

This is an npm package available in the npm repository handle styled attribute in an HTML element.

Installation:

npm i csstype 

Necessary imports:

import * as CSS from 'csstype'; 

Properties are categorized into different uses and in several technical variations to provide typings that suit as many as possible. The good part is that it supports IntelliSense.

Default Hyphen Fallback HyphenFallback  
All Properties PropertiesHyphen PropertiesFallback PropertiesHyphenFallback
Standard StandardProperties StandardPropertiesHyphen StandardPropertiesFallback StandardPropertiesHyphenFallback
Vendor VendorProperties VendorPropertiesHyphen VendorPropertiesFallback VendorPropertiesHyphenFallback
Obsolete ObsoleteProperties ObsoletePropertiesHyphen ObsoletePropertiesFallback ObsoletePropertiesHyphenFallback
Svg SvgProperties SvgPropertiesHyphen SvgPropertiesFallback SvgPropertiesHyphenFallback

Categories 

  • All - Includes Standard, Vendor, Obsolete and SVG
  • Standard - Current properties and extends subcategories StandardLonghand and StandardShorthand (e.g. StandardShorthandProperties)
  • Vendor - Vendor prefixed properties and extends subcategories VendorLonghand and VendorShorthand (e.g. VendorShorthandProperties)
  • Obsolete - Removed or deprecated properties
  • SVG - SVG-specific properties

Variations

  • Default - JavaScript (camel) cased property names
  • Hyphen - CSS (kebab) cased property names
  • Fallback - Also accepts an array of values e.g. string | string[]

Examples

Using default Properties:

var divStyle: CSS.Properties = {  
minHeight:'auto',  
maxHeight:'500px'    
};

By default, it only supports a string if we need to pass number literals.

var divStyle: CSS.Properties<string | number> = {  
   minHeight:'auto',  
   maxHeight:'500px',  
   padding:10  
}; 

We can consume this in our tsx file with the following:

<div  style={divStyle}>  </div>  

Sometimes, we need to pass array of values for CSS that uses PropertiesFallback:

const divStyle: CSS.PropertiesFallback<string | number> = {  
  display: ['-webkit-flex', 'flex'],  
  color: 'white',  
  padding:10  
}; 

Sometimes, there is an need for pseudo selectors, in that case:

const divStyle: { [P in CSS.SimplePseudos]?: CSS.Properties } = {  
  ':hover': {  
    display: 'flex',  
  },  
};

It also support hyphen case, this will implemented by:

interface Style extends CSS.Properties, CSS.PropertiesHyphen {}  
const mydivstyle: Style = {  
  'flex-grow': 1,  
  'flex-shrink': 0,  
  'font-weight': 'normal',  
  backgroundColor: 'white',  
  'padding':'10 10 10 10'  
}; 

typestyle

This is also an npm package available in the npm repository. By using this package, we can write CSS in a typescript file.

Installation

npm i typestyle

Necessary imports:

import { style,stylesheet } from "typestyle";  

Similar to the style attribute, we can assign classCss to className using the style method in typestyle, e.g.

const myclassname = style({paddingLeft: 'red',marginLeft:'10px'});  

We can consume this in our tsx file with:

<div className={myclassname}> </div> 

Concept - Mixin

A mixin is an object that contains properties for reuse.

The style function can take multiple objects. This makes it easy to reuse simple style objects, e.g.

const redMaker = {color:'red'};  
const bigFont = {fontSize: '50px'};  
const bigRedClass = style(  
  redMaker,  
  bigFont  
);  
  
<div className={bigRedClass}>Hello world</div>  

Concept - Interpolation

You can nest properties for different selectors using the $nest property. Any & in a key for $nest gets replaced with the generated class name when its written to CSS. For example, it allows super simple CSS pseudo class (&:hover, &:active, &:focus, &:disabled) customization. It also allows you to use pseudo-elements ,(e.g. ::after, &::before etc):, child selectors.

const mycolors = style({    
  transition: 'color .2s',    
  color: 'blue',    
  $nest: {    
    '&:hover': {    
      color: 'red'    
    },    
    '&::before': {    
      content:'Hello '    
    }  , '&>*': {  
      marginBottom: 10,  
    },  
    '&>*:last-child': {  
      marginBottom: '0px',  
    }  
  }    
});    
    
<h1 className={mycolors }world</h1>    
    
//output be Helloworld 

Sometimes we need to implement the whole CSS file in the component. That can be achieved with the stylesheet class:

Implementation sample:  

const myButton = {  
  border: 'solid thin red',  
  borderRadius: 2,  
  color: 'white',  
  padding: '4px 10px'  
};  
  
const css = stylesheet({  
  component: {  
      display: 'flex'  
  },  
  primaryButton: {  
      backgroundColor: 'darkblue',  
      ...myButton  
  },  
  secondaryButton: {  
      backgroundColor: 'teal',  
      ...myButton  
  }  
});  
  
<div className={css.component}>  
  <button className={css.primaryButton}>Primary</button>  
  <button className={css.secondaryButton}>Secondary</button>  
</div>

Conclusion

In this article, we learned various types of CSS implementation in SPFx. I hope this helps someone. Happy coding :)