Custom Properties and Components in CSS

JavaScript frameworks like React, Angular and Vue let developers use JavaScript to create reusable, sharable blocks of HTML, often with CSS that’s defined at the component level.

Here’s an example of a React component, written in JSX , a syntax extension for JavaScript. It resembles XML, and gets compiled into HTML or XML. It’s a common way of building React components:

import React from ‘react’;

/* Importing the associated CSS into this component */ import ‘../css/field-button.css’;

class FieldButtonGroup extends React.Component {

render() {

return (

<div className=”field__ button_ group”>

<label htmlFor={this.props.id}>{this.props.labelText}</label>

<div>

<input type={this.props.type}

name={this.props.name}

id={this.props.id}

onChange={this.props.onChangeHandler} />

<button type=”submit”>{this.props.buttonText}</button>

</div>

</div>

);

}

}

export default FieldButtonGroup;

Our React component imports CSS into a JavaScript file. When compiled, the contents of fieLd-button.css are loaded inline. Here’s one possible way to use this with custom properties:

.field_ button_ group label {

display: block;

}

.field_ button_ group button {

flex: 0 1 10rem;

background-color: var(–button-bg-color, rgb(103, 58, 183)); /* include a default */

color: #fff;

border: none;

}

In this example, we’ve used a custom property –button-bg-coLor —for the button’s background color, along with a default color in case –button-bg-coLor never gets defined. From here, we can set a value of –button-bg-coLor , either in a global stylesheet or locally via the style attribute.

Let’s set the value as a React “prop”. React props (short for properties) mimic element attributes. They’re a way to pass data into a React component. In this case, we’ll add a prop named buttonBgCoLor :

import FieldButtonGroup from ‘../FieldButtonGroup’;

class NewsletterSignup extends React.Component {

render() {

// For brevity, we’ve left out the onChangeHandler prop.

return (

<FieldButtonGroup type=”email” name=”newsletter” id=”newsletter” labelText=”E-mail address” buttonText=”Subscribe” buttonBgColor=”rgb(75, 97, 108)” />

);

}

}

export default NewsletterSignup;

Now we need to update our FieLdButtonGroup to support this change:

class FieldButtonGroup extends React.Component {

render() {

/*

In React, the style attribute value must be set using a JavaScript object in which the obj’ect keys are CSS properties. Properties should either be camelCased (e.g. backgroundColor) or enclosed in quotes.

*/ const buttonStyle = {

‘–button-bg-color’: this.props.buttonBgColor

};

return (

<div className=”field__ button_ group”>

<label htmlFor={this.props.id}>{this.props.labelText}</label>

<div>

<input type={this.props.type}

name={this.props.name} id={this.props.id}

onChange={this.props.onChangeHandler} />

<button type=”submit” style={buttonStyle}>

{this.props.buttonText}

</button>

</div>

</div>

);

}

}

In the code above, we’ve added a buttonStyle object that holds the name of our custom property and sets its value to that of our buttonBgCoLor prop, and a style attribute to our button.

Using the style attribute probably runs counter to everything you’ve been taught about writing CSS. A selling point of CSS is that we can define one set of styles for use across multiple HTML and XML documents. The style attribute, on the other hand, limits the scope of that CSS to the element it’s applied to. We can’t reuse it. And we can’t take advantage of the cascade.

But in a component-based, front-end architecture, one component may be used in multiple contexts, by multiple teams, or may even be shared across client projects. In those cases, you may want to combine the “global scope” of the cascade with the narrow “local scope” provided by the style attribute.

Setting the custom property value with the style attribute limits the effect to this particular instance of the FieLdButtonGroup component. But because we’ve used a custom property instead of a standard CSS property, we still have the option of defining –button-bg-coLor in a linked stylesheet instead of as a component prop.

Source: Brown Tiffany B (2021), CSS , SitePoint; 3rd edition.

Leave a Reply

Your email address will not be published. Required fields are marked *