Why does centring my div stop it taking it taking up the max amount of width available?

Viewed 224

I am having an issue centring a div with elements using justify-content: space-between;. The child element fills the max-width of the container(900px) prior to either putting a margin auto or justify-content: center; on the parent object. once these styles are added to centre the container the elements inside are crushed to the min-width possible. What's the solution to this because I still would like to have the content inside the container shrink to the screen width?

The parent div using styled-components to have the following styles:

import styled from 'styled-components'
import { ACCOUNT_MAX_WIDTH, UNIT_8 } from '../../../components/_core/grid'

export const AccountMaxWidth = styled.div`
  max-width: ${ACCOUNT_MAX_WIDTH};
  align-self: stretch;
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: ${UNIT_8};
  padding-top: 0;

//toggling this on centres the div but crushes the div.

  margin: auto;
`

Styles of the child div:

import styled from 'styled-components'
import { COLOUR } from '../../../components/_core/colours'
import { UNIT_1, UNIT_3, UNIT_4 } from '../../../components/_core/grid'

export const PreferencesWrapper = styled.div`
  display: flex;
  flex-direction: column;
  > h2 {
    padding: ${UNIT_4} 0;
    color: ${COLOUR.primary.blue_slate};
  }
`

export const SwitchHeadContainer = styled.div`
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  padding: ${UNIT_1} 0;
  > svg {
    margin: auto 0;
    margin-right: ${UNIT_4};
  }
  > h4 {
    margin: auto 0;
  }
`

export const SwitchContainer = styled.div`
  display: flex;
  flex-direction: column;
  > label {
    flex-wrap: wrap;
    margin: ${UNIT_3} 0;
    padding: 0 ${UNIT_1};
    justify-content: space-between;
  }

Here is the tsx file(this is imported and nested within the AccountMaxWidth styled div):

import { Divider } from '@material-ui/core'
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import { Switch } from '../../../components/_atoms/Switch'
import { COLOUR } from '../../../components/_core/colours'
import { MailIcon } from '../../../components/_core/icons/Mail'
import { Medium, Small2X } from '../../../components/_core/Typography'
import {
  PreferencesWrapper,
  SwitchContainer,
  SwitchHeadContainer,
} from './index.styles'

export const Preferences = () => {
  const { t } = useTranslation()
  return (
    <PreferencesWrapper>
      <Medium>{t('account.preferences.heading')}</Medium>
      <SwitchContainer>
        <SwitchHeadContainer>
          <Small2X>{t('account.preferences.notifications.subheading')}</Small2X>
          <MailIcon fill={COLOUR.primary.blue_slate} variant="line" />
        </SwitchHeadContainer>
      </SwitchContainer>
      <SwitchContainer>
        <Divider variant="fullWidth" />
        <Switch
          label={t('account.preferences.notifications.protectionStatus')}
          isChecked={true}
          onToggle={() => null}
        />
      </SwitchContainer>
      <SwitchContainer>
        <Divider variant="fullWidth" />
        <Switch
          label={t('account.preferences.notifications.highThreat')}
          isChecked={true}
          onToggle={() => null}
        />
      </SwitchContainer>
      <SwitchContainer>
        <Divider variant="fullWidth" />
        <Switch
          label={t('account.preferences.notifications.mediumThreat')}
          isChecked={true}
          onToggle={() => null}
        />
      </SwitchContainer>
      <SwitchContainer>
        <Divider variant="fullWidth" />
        <Switch
          label={t('account.preferences.notifications.lowThreat')}
          isChecked={true}
          onToggle={() => null}
        />
      </SwitchContainer>
      <SwitchContainer>
        <Divider variant="fullWidth" />
        <Switch
          label={t('account.preferences.notifications.news')}
          isChecked={true}
          onToggle={() => null}
        />
      </SwitchContainer>
      <SwitchContainer>
        <Divider variant="fullWidth" />
        <Switch
          label={t('account.preferences.notifications.account.heading')}
          isChecked={true}
          onToggle={() => null}
        />
      </SwitchContainer>
    </PreferencesWrapper>
  )
}

[Image One][1]

Here is an image where the div is centred using margin auto or align-self centre as you can see the div is crushed.

[Image Two][2]

Here is an image of how the div looks before centre aligning and how I'd like it to look after centre alignment.

The only difference between the two images is a margin auto [1]: http://imgur.com/hgJUU0a [2]: http://imgur.com/W2gyAzs

3 Answers

I may need more clarification on your question, but justify-content: space-between; should still keep you element center, especially if it's the only element in its parent, without any sibling elements. To center its own children, I would add the centering properties to that div, like in this code:

Also, make sure that the parent element of the parent is also display: flex or that align-self will not do anything. And for a horizontal stretch, you may actually want to use justify-content: stretch.

.parentElement {
    display: flex;
    justify-content: space-between;
}
.parentElement > .childElement {
    display: flex;
    justify-content: center;
    flex: 1;
}

I'd like to assist further, but I'm still having a difficult time fully understanding your question. Would you mind adding a working snippet to your ticket that demonstrates the issue that needs to be fixed so I can adjust a copy of your code directly? Thanks!

Try giving the PreferencesWrapper a min-width or width: 100%.

Hope you are doing well, you have not shared any codesandbox to test out the changes on your code and provide you the solution, but what seems to be the problem on the surface is max-width. Please change the styles accordingly.

export const AccountMaxWidth = styled.div`
  min-width: ${ACCOUNT_MAX_WIDTH};
  align-self: stretch;
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: ${UNIT_8};
  padding-top: 0;
Related