css: плавное "выдвигание" созданного блока

Рейтинг: 0Ответов: 1Опубликовано: 28.03.2023

подскажите, можно ли как-то реализовать плавное "выдвигание" <div /> блока (т.е. появление с 0 высоты до исходной высоты под каким-то другим блоком), если блок не присутствует изначально в DOM, а в какой-то момент создаётся динамически?

я реализовал это через "костыль" -

  • блок уже изначально создан, но его высота 0px (скрыт)
  • при наведении на карточку блоку выставляется нужный размер

недостатки такого подхода - приходится вручную устанавливать высоту блока (а этой информации у меня изначально нет), приходится отрисовывать блок всегда, а не когда он нужен

.main {
  width:              200px;
  
  border:             1px solid black;
}

.title {
  height:             100px;
  line-height:        100px;
  text-align:         center;
}

.main .animated {
  border-top:         1px solid black;

  background:         #ffff80;

  text-align:         center;

  height:             0px;
  line-height:        0px;
  overflow:           hidden;

  transition:         all 0.75s;
}

.main:hover .animated {
  height:             45px;
  line-height:        45px;
}
<div class='main'>
  <div class='title'>Наведи на меня</div>
  <div class='animated'>Выдвигаемый блок</div>
</div>

это нужно для элемента Card от Ant Design, в котором при наведении должна плавно появиться (отъехать) плашка actions

когда наводится мышка на карточку, то появляется блок 'actions' - .ant-card-actions и вот ее отъезд и хотелось бы реализовать

Вот код этой карточки и эффекта:

https://codesandbox.io/s/support-more-content-configuration-antd-5-3-2-forked-ycqsp9?file=/demo.tsx

Код (а то песочница тяжелая):

import React, { useState } from "react";
import "./index.css";
import {
  EditOutlined,
  EllipsisOutlined,
  SettingOutlined
} from "@ant-design/icons";
import { Avatar, Card } from "antd";

const { Meta } = Card;

const App: React.FC = () => {
  // показывать или скрывать блок с кнопками
  // ПРОБЛЕМА: НУЖНО ЗАСТАВИТЬ БЛОК НЕ ПРОСТО ПОЯВЛЯТЬСЯ МГНОВЕННО (ОН СОЗДАЕТСЯ ДИНАМИЧЕСКИ), 
  // А ПЛАВНО ВЫЕЗЖАТЬ СВЕРХНУ ВНИЗ
  const [isToolbarEnabled, setToolbar] = useState<boolean>(false);

  return (
    <Card
      onMouseEnter={() => setToolbar(true)}
      onMouseLeave={() => setToolbar(false)}
      style={{ width: 300 }}
      cover={
        <img
          alt="example"
          src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"
        />
      }
      actions={/* указывается блок, который будет отрисован снизу элемента */
        isToolbarEnabled
          ? [
              <SettingOutlined key="setting" />,
              <EditOutlined key="edit" />,
              <EllipsisOutlined key="ellipsis" />
            ]
          : undefined
      }
    >
      <Meta
        avatar={<Avatar src="https://joesch.moe/api/v1/random" />}
        title="Card title"
        description="This is the description"
      />
    </Card>
  );
};

export default App;

Ответы

▲ 2

Вы это имели ввиду? Что высота разная для .animation?

.main {
  width:              200px;
  
  border:             1px solid black;
}

.title {
  height:             100px;
  line-height:        100px;
  text-align:         center;
}

.main .animated {
  border-top:         1px solid black;

  background:         #ffff80;

  text-align:         center;

  height:             0px;
  line-height:        0px;
  overflow:           hidden;

  transition:         all 0.75s;
}

.main:hover .animated {
  height:             100%;
  line-height:        45px;
}
<div class='main'>
  <div class='title'>Наведи на меня</div>
  <div class='animated'>Выдвигаемый блок</div>
</div>

<div class='main'>
  <div class='title'>Наведи на меня</div>
  <div class='animated'>Выдвигаемый блок Выдвигаемый блок</div>
</div>

<div class='main'>
  <div class='title'>Наведи на меня</div>
  <div class='animated'>Выдвигаемый блок Выдвигаемый блок Выдвигаемый блок</div>
</div>