How to format "::before" psuedo-class in Microsoft's mergeStyles() utility?
Asked Answered
F

1

5

I'm trying to move my SCSS code into React components using microsoft's mergeStyles utility, which is a part of its FluentUI framework. I'm stuck figuring out how to specify "::before" as a selectors property. For some reason, mergeStyles() recognized ":hover::before" but not "::before" on its own. Please see comments in code below for example. Any help appreciated. Thank you.

export const getClassNames = (): ISidebarClassNames => {
    return mergeStyleSets({
        sideNavItem: {
            position: "relative",
            selectors: {
                ":not(:last-child)": {
                    marginBottom: ".5rem",
                },
               // This works and "hover::before" does indeed triggers "scaleY(1)".  
               // Why then does "::before" not work on its own (see below)?
                ":hover::before": {
                    transform: "scaleY(1)",
                },
                // TODO: This does not work in mergeStyles() but does work if coded in SCSS. 
                "::before": {
                    content: "",
                    position: "absolute",
                    top: 0,
                    left: 0,
                    bottom: 0,
                    width: "3px",
                    backgroundColor: "red",
                    transform: "scaleY(0)",
                }
            }
        }
Forefront answered 28/7, 2020 at 17:18 Comment(0)
F
17

I think i figured it out. The culprit was the "content" property. Because CSS expects a quoted string (and because mergeStyleSets passes the property itself as a string), the value needs to be double quoted, like example below:

--> content: "''"
--> instead of content:""

Also, it doesn't appear to matter if you have one colon (:before) or two (::before). It works the same way on my system, at least!

 // this array notation allows us to specify generated class name statically
    sidebar_nav_ul_li: ['sidebar_nav_ul_li', {
        // make the element you're trying to "before" position absolute and the ::before relative
        position: "relative",
        color: currentTheme.palette.white,
        selectors: {
            ":not(:last-child)": {
                marginBottom: ".5rem",
            },
            ":active::before": {
                backgroundColor: currentTheme.palette.themeDarkAlt,
            },
            "::before": {
                content: "''",
                position: "absolute",
                top: 0,
                left: 0,
                height: "100%",
                width: "4px",
                backgroundColor: currentTheme.palette.themeSecondary,
                transformOrigin: "center",
                transform: "scaleY(0)",
                // the transform property (which scales Y from 0 to 1) takes place over .2s,
                // then the transition of width occurs from 3px to 100% over .4s after .2s delay
                // in parallel, the backgroundcolor changes fast in .1s.  this happens upon hover
                // and also upon click which activates :active state.
                transition: "transform 0.3s, width 0.4s cubic-bezier(1, 0, 0, 1) 0.3s, background-color 0.1s",
            },
            ":hover::before": {
                transform: "scaleY(1)",
                width: "100%", // grows from 3px to 100% upon hover.
                border: "1px solid var(--neutralPrimary)",
            }
        }
    }],
Forefront answered 30/7, 2020 at 22:30 Comment(4)
Super helpful man, was stuck for 2 days on this nonsenseKindergarten
This should be the accepted answer +1Duct
This should be in big capitals somewhere on the documentation pages! Thanks!Trigg
Aaah.. wasted so much time to add space. Fixed after adding quote "::after": { content: "'\\00a0'" }Tocharian

© 2022 - 2024 — McMap. All rights reserved.