Search code examples
cssreactjsemotion

React and Emotion: Specify font size


I am using emotion to style and display the equation for compound interest in my React app. My render() returns this:

<div css ={equation}>
  <p>
  P (1 +</p>
  <p css={fraction}>
    <span className="num">1</span>
    <span className="symbol">/</span>
    <span className="bottom">2</span>
  </p>
  )
   <sup>(nt)</sup>
</div>

And outside of my component I have:

const fraction = css`
    display: inline-block;
    position: relative;
    vertical-align: middle;
    letter-spacing: 0.0001em;
    text-align: center;

    .num {
      display: block;
      padding: 0;
      height: 12px;
      line-height: 12px;
    }

    .bottom {
      border-top: thin solid black;
    }

    .symbol {
      display: none;
    }
`
const equation = css`
font-size: 100%;
.p{
    font-size:large !important;
  }
`;

The fraction is correctly styled. However, I cannot get the font of the p elements to change. The only way I got it to was by switching the p to h1 elements - but I don't want to do that. I want to be able to specify the font size inside my emotion css styling.


Solution

  • There are a couple of things I noticed as an issue in your code.

    • You are passing .p { ... inside the equation which is not a class selector but should have been an element selector like p { ...
    • Your react div has to use a className in order to make that effect applied

    Here is the sandbox code changes: https://codesandbox.io/s/emotion-xh53z?fontsize=14

    Just copying here for your reference:

    import React from "react";
    import { render } from "react-dom";
    import { css } from "react-emotion";
    
    const fraction = css`
      display: inline-block;
      position: relative;
      vertical-align: middle;
      letter-spacing: 0.0001em;
      text-align: center;
      .num {
        display: block;
        padding: 0;
        height: 30px;
        line-height: 12px;
      }
      .bottom {
        border-top: thin solid black;
      }
      .symbol {
        display: none;
      }
    `;
    
     // Notice the p inside the equation
    const equation = css`
      p { 
        font-size: large !important;
      }
    `;
    
    // Rather than css={}, you should be using className={}
    const App = () => (
      <div className={equation}>
        <p>
          P (1 +
          <p className={fraction}>
            <span className="num">1</span>
            <span className="symbol">/</span>
            <span className="bottom">2</span>
          </p>
          )<sup>(nt)</sup>
        </p>
      </div>
    );
    
    render(<App />, document.getElementById("root"));
    

    I also moved the closing </p> tag at the last to ensure it's getting applied as per inline-block

    Updated 1:

    Here is the latest updated version: https://codesandbox.io/s/emotion-1tjc7

    As per their latest blog you should be using:

    import styled from '@emotion/styled'
    import { css } from 'emotion'
    

    instead of import styled, { css } from 'react-emotion'

    Update 2:

    In case you cannot use vanilla emotion, then you can consider using the following:

    import styled from "@emotion/styled";
    /** @jsx jsx */
    import { css, jsx } from "@emotion/core";
    

    According to their documentation:

    There are 2 ways to get started with the css prop.

    • Babel Preset (Can't use in Create-React-App or CodeSandbox)
    • JSX Pragma (This involves to just add the above to lines of code)

    I have updated the same codesandbox: https://codesandbox.io/s/emotion-0z3vz