aem-react icon indicating copy to clipboard operation
aem-react copied to clipboard

CSS Styling options

Open l3wi opened this issue 8 years ago • 5 comments

What is the current solution to styling the react components such that they work both Server & Client side?

I've tried using a number of inline styling libraries (styled-jsx, Radium, etc) however they all fail to work. The closest we've gotten is styled-component on the client side.

Any suggestions?

l3wi avatar Apr 12 '17 01:04 l3wi

I use good old css files. I have never tried the component-oriented inline style approach.

stemey avatar Apr 12 '17 04:04 stemey

After a little bit of fumbling I've managed to sort out scoped CSS with AEM-react. I'd highly recommend using this approach as it makes your code much more manageable.

The issue I've been facing with styling components was the server rendering of react didn't include a copy of the CSS from styled-components. This causes the page to load unstyled and then when React loads it injects the styles dynamically into the Head. Not too pretty.

So I've figured out how to inject the whole bundled stylesheet into the html for server rendering. See below.

Install styled-components

npm install --save styled-components

Create a CSS component

This is a simple vanilla component that bundles the CSS. It uses a function within styled-components to expose all the css and bundle it into a style tag.

import * as React from "react";
import * as styleSheet from 'styled-components/lib/models/StyleSheet'

export class Document extends React.Component<any, any> {
    render() {
        return <style dangerouslySetInnerHTML={{ __html: styleSheet.rules().map(rule => rule.cssText).join('\n') }} />
    }
}

Register Component

Register the component in the registry as per the offical instructions and create the required .content.xml in the components folder.

Add component to the page template

Open up jcr_root/apps/react-demo/pages/page/page.html and add this line into the head tag. I've named my component 'Document', so if you name yours differently change the code.

<!-- Underneath shall be the CSS -->
<sly data-sly-resource="${ @path='document', resourceType='react-demo/components/document'}"></sly>

Style a component

Style a component using the styled-components library.

import * as React from "react";
import styled from 'styled-components';

export class Panel extends React.Component<any, any> {
    render() {
        let label = this.props.label || "please select a label 3";
        return (
            <div>
              <Title>{label}</Title>
              {this.props.children}
            </div>
        );
    }
}

const Title = styled.h1`
  font-size: 1.5em;
  text-align: center;
  color: palevioletred;
`;

Issue with approach

I haven't figured out how to inject the style tag within the CSS Component without the default wrapping DIV of AEM. This means when styled-components loads in React it injects a second set of HTML into the head. This leaves the page with a duplicate set of css.

<!-- Underneath shall be the CSS -->
<div data-react-server="true" data-react="app" data-reactid="/content/reactdemo/overview/jcr:content/document_component">
   <style data-reactid="2">
      .kZQsGZ { 
         font-size: 1.5em;
         text-align: center;
         color: palevioletred;
      }
  </style>
</div>

I haven't seen any issues arising from this yet, however I'm sure they exist. Any suggestions for removing the wrapping elements that AEM adds?

l3wi avatar Apr 17 '17 23:04 l3wi

You can remove the wrapper div but you won't be able to edit the associated content.

http://www.codermag.net/2016/02/remove-component-wrapper-divs-in-cqaem.html

stemey avatar Apr 22 '17 06:04 stemey

Ow cool, I will implement that.

@stemey would you be open to a PR adding this method of styling to the docs?

l3wi avatar Apr 22 '17 07:04 l3wi

A documentation for it is a great idea, but I feel that I cannot provide any support for it. If you have a blog that would be a great place to put the docs and I will link to it. Or you create a chapter in the aem-react docs with a special note about the author.

stemey avatar Apr 22 '17 07:04 stemey