Сделать дочерний элемент сетки пользовательского интерфейса Material растянутым, чтобы соответствовать оставшейся высоте родительского контейнера

#javascript #css #reactjs #material-ui

#javascript #css #reactjs #материал-пользовательский интерфейс

Вопрос:

1. Текущий внешний вид

У меня есть контейнер сетки пользовательского интерфейса Material с 4 элементами сетки. Внутри каждого элемента сетки находится компонент типографики, содержащий заголовок и карточку с некоторым содержимым, как показано ниже:

введите описание изображения здесь

2. Желаемый внешний вид

Я бы хотел, чтобы карточки заполняли оставшуюся высоту элементов сетки и не превышали ее. Это мой желаемый результат:

введите описание изображения здесь

3. Нежелательный внешний вид (высота карты = 100%)

Я попытался увеличить высоту карточек на 100%, но это означает, что каждая карточка принимает высоту своего родителя (элемента сетки) и высоту родительского элемента = Типография карточка (а не оставшееся пространство минус типография), в результате чего карта превышает высоту родительского элемента.высота родительского элемента сетки, как показано ниже:

введите описание изображения здесь

Каков наилучший способ преодолеть эту проблему? Я использую сетку пользовательского интерфейса Material, чтобы упростить контрольные точки и согласовать их с остальной частью моего проекта, поэтому в идеале решение должно использовать этот подход.

Вот код:

 import React from 'react';

const useStyles = makeStyles(theme => ({
   // stretch: { height: '100%' }, // Un-commenting this results in undesirable appearance 3 (see image 3 above)
    outline: { border: '1px solid red' },
}));

const Sections= () => {
  const classes = useStyles();

  return (
    <Grid container spacing={3} justify="space-between" alignItems="stretch" className={classes.outline}>
      <Grid item xl={2} lg={2} md={6} xs={12} className={classes.outline}>
          <Typography className={classes.outline}>Big title 1</Typography>
          <Card className={classes.stretch}><CardContent>Lots and lots and lots and lots and lots and lots of content</CardContent></Card>
      </Grid>
   <Grid item xl={4} lg={4} md={6} xs={12} className={classes.outline}>
          <Typography className={classes.outline}>Big title 2</Typography>
          <Card className={classes.stretch}><CardContent>Not much content</CardContent></Card>
   </Grid>
   <Grid item xl={3} lg={3} md={6} xs={12} className={classes.outline}>
          <Typography className={classes.outline}>Big title 3</Typography>
          <Card className={classes.stretch}><CardContent>Not much content</CardContent></Card>
   </Grid>
   <Grid item xl={3} lg={3} md={6} xs={12} className={classes.outline}>
          <Typography className={classes.outline}>Big title 4</Typography>
          <Card className={classes.stretch}><CardContent>Not much content</CardContent></Card>
   </Grid>
</Grid>
  );
};


export default Sections;
 

Большое спасибо,

Кэти

Комментарии:

1. Я думаю, вам не хватает некоторых частей кода. Например, дополнительные «Большие заголовки» над каждой из карточек. Сможете ли вы обновить фрагмент кода, чтобы включить его? Спасибо

2. Я создал живой пример stackblitz, который, как я полагаю, имеет желаемый результат. Интересно, что я раскомментировал стили, которые у вас были, и, похоже, это работает. Были некоторые проблемы, когда ваши <Grid /> теги были не в правильном порядке, поэтому, возможно, именно поэтому ваш стиль раньше не работал.

3. Спасибо, Чарльз — я внес изменения в код и надеюсь, что теперь он выглядит правильно? Я также понимаю, как вы предполагаете, что закрывающий тег </Grid> находится не в том месте. Кроме этого, я вижу, что ваш код работает, но я не понимаю разницы? Мне пришлось значительно упростить код, показанный здесь, по сравнению с моим собственным кодом, поэтому я пытаюсь устранить разницу! Не могли бы вы объяснить? Большое спасибо!

4. На самом деле — я вижу, что боюсь, что это решение не работает. Если вы примените границу к сеткам, вы увидите, что она похожа на изображение 3 выше. Карты выходят за пределы высоты родительской сетки. Большое спасибо за вашу помощь!

5. Кэти, я понял проблему в своем первом решении и обновил его. Надеюсь, это поможет! Спасибо за фотографии, показывающие, какие результаты были желаемыми.

Ответ №1:

Чтобы решить эту проблему, вам нужно установить высоту для каждого отдельного элемента сетки. Затем вы можете отобразить элемент сетки, согнутый в направлении сгиба «столбца». Затем вы можете установить высоту карты на 100%, как и раньше. Механизм отображения по умолчанию в сетке Material-UI не настроен на flex, поэтому карта будет выходить за пределы границы, поскольку они используют такие вещи, как отрицательные поля.

Код приведен ниже:

 // imports omitted

const useStyles = makeStyles(theme => ({
  stretch: { height: "100%" },
  item: { display: "flex", flexDirection: "column" } // KEY CHANGES
}));

export const Sections = () => {
  return (
    <Grid container spacing={2} justify="space-between" alignItems="stretch">
      <Item xl={2} lg={2} md={6} xs={12} title="Big Title 1" content="Lots and lots and lots and lots and lots and lots of content!" />
      <Item xl={4} lg={4} md={6} xs={12} title="Big Title 2" content="Not much content" />
      <Item xl={3} lg={3} md={6} xs={12} title="Big Title 3" content="Not much content" />
      <Item xl={3} lg={3} md={6} xs={12} title="Big Title 4" content="Not much content" />
    </Grid>
  );
}

const Item = ({ title, content, ...rest }) => {
  const classes = useStyles();

  return (
    <Grid className={classes.item} item {...rest}>
      <Typography>{title}</Typography>
      <Card className={classes.stretch}>
        <CardContent>{content}</CardContent>
      </Card>
    </Grid>
  );
};
 

Проверьте stackblitz для живого примера.

Комментарии:

1. Абсолютно идеально! Гениальное решение для чего-то, на что я не смог найти удовлетворительного ответа! Большое вам спасибо. Я мучился над этим пару дней, так что еще раз спасибо, Чарльз — блестящий 🙂

Ответ №2:

чтобы Card всегда оставалась оставшаяся высота, укажите высоту Typography , равную . допустим, высота Typography 20px равна, а затем установите высоту CardItem as 100% - (height of the typography_ , т.е. `height:’calc(100% — 20 пикселей)’. Это займет оставшуюся высоту.

 const useStyles = makeStyles((theme) => ({
    stretch: {
        height: 'calc(100% - 20px)'
    }, // Un-commenting this results in undesirable appearance 3 (see image 3 above)
    outline: { border: "1px solid red" }
}));
 
 <Grid
  container
  spacing={3}
  justify="space-between"
  alignItems="stretch"
  className={classes.outline}>
  <Grid item xl={2} lg={2} md={6} xs={12} className={classes.outline}>
    <Typography style={{height:'20px'}} className={classes.outline}>Big title 1</Typography>
    <Card className={classes.stretch}>
      <CardContent>
        Lots and lots and lots and lots and lots and lots of content
      </CardContent>
    </Card>
  </Grid>
  <Grid item xl={4} lg={4} md={6} xs={12} className={classes.outline}>
    <Typography style={{height:'20px'}} className={classes.outline}>Big title 2</Typography>
    <Card className={classes.stretch}>
      <CardContent>Not much content</CardContent>
    </Card>
  </Grid>
  <Grid item xl={3} lg={3} md={6} xs={12} className={classes.outline}>
    <Typography style={{height:'20px'}} className={classes.outline}>Big title 3</Typography>
    <Card className={classes.stretch}>
      <CardContent>Not much content</CardContent>
    </Card>
  </Grid>
  <Grid item xl={3} lg={3} md={6} xs={12} className={classes.outline}>
    <Typography style={{height:'20px'}} className={classes.outline}>Big title 4</Typography>
    <Card className={classes.stretch}>
      <CardContent>Not much content</CardContent>
    </Card>
  </Grid>
</Grid>
 

Редактировать галантный-фиолетовый-k9tqs

Комментарии:

1. Спасибо тебе, Раджив! Это хороший ответ для тех, кто с удовольствием фиксирует рост первого ребенка. Я проголосовал против по этой причине. Я отметил ответ Чарльза выше как правильный ответ, поскольку считаю, что с этим можно было бы справиться, если бы заголовок состоял из двух строк. Я ценю вашу помощь!