Search code examples
cssreactjsstyled-componentsreactstrap

How to add media query to non component variable in styled components?


I am working on a React JS project where I am using styled-components for styling the web pages.

I am using reactstrap components in the project. I am styling the Button component of reactstrap and trying to add the media query.

ButtonX Component

import styled, {css} from 'styled-components';
import { Button } from 'reactstrap';
import media from '../media';


const orange = `
    background-color: #E4572E;
    border: 1px solid #E4572E;
    color: #fff;

    &:hover,
    &:focus {
        background-color: #e97857;
        border: 1px solid #e97857;
        color: #fff;
    }
`;

const inline = `
    position: absolute;
    top: 1rem;
    right: 1rem;
`;

const ButtonX = styled(Button)`
    padding: 0.5rem 1.5rem;
    font-weight: 500;
    font-size: 0.8rem;
    transition: all 0.4s linear;
    border-radius: 0.2rem;

    ${props => props.orange ? css`${orange}` : ''};
    ${props => props.inline ? css`${inline}`: ''}

    ${props => props.inline ? 
        (media.smalldevice`
            top: 4rem;
            right: 5rem;
        `)
        : ''}
`;

export {
    ButtonX
}

I am Writing the ButtonX component like this

<ButtonX orange="true" inline="true">Sign Up</ButtonX>

As, In the ButtonX component I am checking if inline is set then add the css code as well as media query for the css.

${props => props.inline ? css`${inline}`: ''}

        ${props => props.inline ? 
            (media.smalldevice`
                top: 4rem;
                right: 5rem;
            `)
            : ''}

I am checking the condition 2 times if inline is true then add css and media query.

1) The above is working, but I want to add both the queries in a single condition which is not working.

2) Else, I would like to know how can I write this media query in the inline variable above like this.

const inline = `
    position: absolute;
    top: 1rem;
    right: 1rem;

    ${
        media.smalldevice`
            top: 4rem;
            right: 5rem;
        `
    }

`;

I tried the second one but that is not working as I am sure if we can write media query in the variable.


Solution

  • When adding something like a media query inside a template string, you are interpolating a function. These cannot work inside normal template literals as you have provided inline with.

    styled-components provides a helper called css that can be used to interpolate functions. In your case it can be used:

    import { css } from "styled-components";
    
    const inline = css`
        position: absolute;
        top: 1rem;
        right: 1rem;
    
        ${media.smalldevice`
            top: 4rem;
            right: 5rem;
        `}
    `;