-1

I have some problem with flexbox gap (not working) in older versions of browsers and was recommended using stylis. https://www.npmjs.com/package/stylis

Im trying to figure out the documentation but I'm struggling. I guess I need to create a customized plugin? I followed some of emotion's documentation and then got stuck. Anyone who can help me?

"Gap" is my supposed to be customPlugin

My background: Using Next.js with Mantine library (which is using emotion)

It feels like I have tried everything. I'm not so experienced so I have certainly missed something obvious.

  • Can you explain a bit more in detail? What do you want to achieve, what are you struggling with and where are you stuck.. – Sbaliyev Oct 26 '22 at 12:05
  • If I have an iphone with an old IOS version e.g and I go to my website, all my elements with "gap: value" are not working anymore. So my main goal here is to have a website working with flexbox gaps in older browsers. I'm stuck with creating the custom plugin (Gap-function) that will help me fix the "gap"-problem. – zziinnk Oct 26 '22 at 12:15
  • I had to fallback to using margin-left/right along with some odd/even rules in CSS but my layout was meant to be 2 columns so this may or may not work for your case. It will not be a perfect match but it's probably not worth overengineering it for such a small userbase (though it depends on what is typical for your site) – apokryfos Oct 26 '22 at 12:49
  • Please make sure to post code and errors as text directly to the question (and [not as images](https://meta.stackoverflow.com/questions/285551)), and [format them appropriately](https://stackoverflow.com/help/formatting). – juliomalves Oct 29 '22 at 12:53

2 Answers2

0

Flex Gap is not supported for Safari < 14.1, and iOS Safari < 14.5 but used in mantine components (@mantine/core v5):

  • Carousel: indicators: {gap: 8}
  • Group: root: { gap: theme.fn.size({ size: spacing, sizes: theme.spacing }) } -- fixed
  • Stack: root: { gap: theme.fn.size({ size: spacing, sizes: theme.spacing }) } -- fixed
  • Tabs (TabList): tabsList: {... if (variant === 'pills') { return { gap: theme.spacing.sm / 2, }; } ... } -- fixed
  • Calendar (CalendarBase): calendarBase: {gap: theme.spacing.md}

Workaround: Group and Stack components is a base for most Mantine components. Flex component not uses global config styles, and used for their demos, so just not use it in your codebase.

To fix Group and Stack components add this code to config in provider:

const themeConfig: MantineThemeOverride = {
  components: {
    Group: {
      styles: (theme: MantineTheme, { spacing }: GroupStylesParams) => {
        return {
          root: {
            gap: 0,
            marginRight: -theme.fn.size({ size: spacing, sizes: theme.spacing }),
            marginBottom: -theme.fn.size({ size: spacing, sizes: theme.spacing }),
            '> *': {
              marginRight: theme.fn.size({ size: spacing, sizes: theme.spacing }),
              marginBottom: theme.fn.size({ size: spacing, sizes: theme.spacing }),
            },
          },
        };
      },
    },
    Stack: {
      styles: (theme: MantineTheme, { spacing }: StackStylesParams) => {
        return {
          root: {
            gap: 0,
            marginBottom: -theme.fn.size({ size: spacing, sizes: theme.spacing }),
            '> *': {
              marginBottom: theme.fn.size({ size: spacing, sizes: theme.spacing }),
            },
          },
        };
      },
    },
    Tabs: {
      styles: (theme, { variant, color }: TabsStylesParams) => {
        const filledScheme = theme.fn.variant({ color, variant: 'filled' });
        let tabStyles = {};
        let tabListStyles = {};

        if (variant === 'pills') {
          const spacing = theme.spacing.sm; // In mantine is hardcoded now (https://github.com/mantinedev/mantine/blob/master/src/mantine-core/src/Tabs/TabsList/TabsList.styles.ts#L46)
          tabListStyles = {
            gap: 0,
            marginRight: -spacing,
            marginBottom: -spacing,
            '> *': {
              marginRight: spacing,
              marginBottom: spacing,
            },
          };
        }

        return {
          tab: tabStyles,
          tabsList: tabListStyles,
        };
      },
    },
  },
}

Known limitations

  • Must use a wrapper div when using margin: auto or background or when you need to make some space between container and next element. Also this may have issues in cases when some code calculates scrollHeight - it will be larger than expected by the size of gap (spacing on the bottom despite the fact that it is absorbed by the parent negative it will be calculated).
  • Percentage gaps aren't reliable if the container is not full width of parent container
  • Width of flex items with percentages vary slightly from spec because of negative margin on container.

Advanced approach: You can use modernizr config to add custom classes to the html element, so you can apply fallback values only for browsers that doesn't support flex gap.

modernizr-config.json

 {
  "classPrefix": "_",
  "enableClasses": true,
  "enableJSClass": true,
  "scriptGlobalName": "window",
  "usePrefixes": true,
  "minify": true,
  "options": [
    "addTest",
    "testProp",
    "setClasses"
  ],
  "feature-detects": [
    "css/flexgap",
  ]
}

package.json

"scripts": {
 "compile-modernizr": "modernizr -c modernizr-config.json -d ./public/static/scripts/modernizr-bundle.min.js"
}

_document.tsx

<body>
  <Main />
  <NextScript />
  <Script src="/static/scripts/modernizr-bundle.min.js" strategy="beforeInteractive" />
</body>

After this, change your theme-config like this

    Group: {
      styles: (theme: MantineTheme, { spacing }: GroupStylesParams) => {
        return {
          root: {
            '._no-flexgap &': {
              gap: 0,
              marginRight: -theme.fn.size({ size: spacing, sizes: theme.spacing }),
              marginBottom: -theme.fn.size({ size: spacing, sizes: theme.spacing }),
            },
            '._no-flexgap & > *': {
              marginRight: theme.fn.size({ size: spacing, sizes: theme.spacing }),
              marginBottom: theme.fn.size({ size: spacing, sizes: theme.spacing }),
            },
          },
        };
      },
    },
    Stack: {
      styles: (theme: MantineTheme, { spacing }: StackStylesParams) => {
        return {
          root: {
            '._no-flexgap &': {
              gap: 0,
              marginBottom: -theme.fn.size({ size: spacing, sizes: theme.spacing }),
            },
            '._no-flexgap & > *': {
              marginBottom: theme.fn.size({ size: spacing, sizes: theme.spacing }),
            },
          },
        };
      },
    },

Similar way in other cases. So, with this optional fallback you always keep use an additional wrapper (a div) around your elements that uses gap for best backward compatibility. I hope this helps you!

-1

The gap property of flexbox won't work in older browsers (as you just stated in your own comment). As @apokryfos suggests in the comments, you can use margins.

Sbaliyev
  • 163
  • 7
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 29 '22 at 19:41