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:
  1. npm i csstype  
Necessary imports:
  1. 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:
  1. var divStyle: CSS.Properties = {  
  2. minHeight:'auto',  
  3. maxHeight:'500px'    
  4. };  
By default, it only supports a string if we need to pass number literals.
  1. var divStyle: CSS.Properties<string | number> = {  
  2.    minHeight:'auto',  
  3.    maxHeight:'500px',  
  4.    padding:10  
  5. };  
We can consume this in our tsx file with the following:
  1. <div  style={divStyle}>  </div>  
Sometimes, we need to pass array of values for CSS that uses PropertiesFallback:
  1. const divStyle: CSS.PropertiesFallback<string | number> = {  
  2.   display: ['-webkit-flex''flex'],  
  3.   color: 'white',  
  4.   padding:10  
  5. };  
Sometimes, there is an need for pseudo selectors, in that case:
  1. const divStyle: { [P in CSS.SimplePseudos]?: CSS.Properties } = {  
  2.   ':hover': {  
  3.     display: 'flex',  
  4.   },  
  5. };  
It also support hyphen case, this will implemented by:
  1. interface Style extends CSS.Properties, CSS.PropertiesHyphen {}  
  2. const mydivstyle: Style = {  
  3.   'flex-grow': 1,  
  4.   'flex-shrink': 0,  
  5.   'font-weight''normal',  
  6.   backgroundColor: 'white',  
  7.   'padding':'10 10 10 10'  
  8. };  
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
  1. npm i typestyle  
Necessary imports:
  1. import { style,stylesheet } from "typestyle";  
Similar to the style attribute, we can assign classCss to className using the style method in typestyle, e.g.
  1. const myclassname = style({paddingLeft: 'red',marginLeft:'10px'});  
We can consume this in our tsx file with:
  1. <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.
  1. const redMaker = {color:'red'};  
  2. const bigFont = {fontSize: '50px'};  
  3. const bigRedClass = style(  
  4.   redMaker,  
  5.   bigFont  
  6. );  
  7.   
  8. <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.
  1. const mycolors = style({    
  2.   transition: 'color .2s',    
  3.   color: 'blue',    
  4.   $nest: {    
  5.     '&:hover': {    
  6.       color: 'red'    
  7.     },    
  8.     '&::before': {    
  9.       content:'Hello '    
  10.     }  , '&>*': {  
  11.       marginBottom: 10,  
  12.     },  
  13.     '&>*:last-child': {  
  14.       marginBottom: '0px',  
  15.     }  
  16.   }    
  17. });    
  18.     
  19. <h1 className={mycolors }world</h1>    
  20.     
  21. //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:
  1. const myButton = {  
  2.   border: 'solid thin red',  
  3.   borderRadius: 2,  
  4.   color: 'white',  
  5.   padding: '4px 10px'  
  6. };  
  7.   
  8. const css = stylesheet({  
  9.   component: {  
  10.       display: 'flex'  
  11.   },  
  12.   primaryButton: {  
  13.       backgroundColor: 'darkblue',  
  14.       ...myButton  
  15.   },  
  16.   secondaryButton: {  
  17.       backgroundColor: 'teal',  
  18.       ...myButton  
  19.   }  
  20. });  
  21.   
  22. <div className={css.component}>  
  23.   <button className={css.primaryButton}>Primary</button>  
  24.   <button className={css.secondaryButton}>Secondary</button>  
  25. </div>  

Conclusion

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