[Web前端]CSS高阶提问...

因为与Emacs 无关, 所以不敢期望有解答(因为我Google都找不到答案啊…), 试水一下…

就是我要在点击标签页多个按钮的其中一个的关闭的时候让它动画逐渐缩小(宽度变为0, 包括padding, margin)
我养长了好习惯动画尽量用CSS(transition/animation) 而不用JavaScript
这个实现我现在只能用 JavaScript, 因为CSS的逻辑是把width/padding 这些都 animation 为0, 问题是动画前的 width 我无法在CSS得到(JS里用 element.getBoundingClientRect)
max-content 没有动画
请问该怎么办? (没办法就用JS搭配了)
https://school.celwk.com/


[PS:我现在点击打开每个标签页时如果不是完整展示出这个标签标题都会动画移动过去 因为这不是针对具体项目 所以搭建积累了自己的高性能框架代码哦(不到10KB)…吹牛吹上瘾了 ]

哥们你好像问错地方了吧?

Emacs-China社区已经变成万能的编程社区了 :rofl:

1 个赞

用scaleX把它缩到0呢 然后监听动画结束关闭它 不过它好像是从两头往中间缩

侧栏的宽度难道不是你自己设的么?为啥会不知道?

另外侧栏一般不都是滑走么,改宽度会改变排版的吧。

我觉得楼主就算用css解决了这个问题,以后也还会遇到css解决不了的问题,还是用js吧。

我好久以前想做这么一个效果,根据页面对角线的长度来动态调整元素的大小,而不是由页面长和宽来调整元素的大小。css完全想像不出来怎么做(现在也不知道怎么做,但不想折腾了),只好用js,取到页面长宽,然后 用a^2*b^2=c^2 这个公式来算出对角线长度。

主要是emacs-china社区高手多 :smiley:,在这问一般会解决,如果去javascript社区问可能没这么快。

我看其它也有问啊 JavaScript 什么的… 编程有关的不都可以吗…

不行呢, 修改scale 的时候旁边的标题栏不会动啊 (另外通过transform-origin: left可以让它向左, 默认是center)

我说的宽度是指标题栏, 例如下面有4个标题栏:


我在关闭其中任何一个的时候想要动画压减至0(就像Chrome浏览器关闭标签的时候)

这个感觉不是什么好兆头。。。 :joy:

不久之前有人把这当qq空间来写小说和博客来着,所以大家的敏感度稍微提高了些. :rofl:

正常情况应该没啥,但这是emacs社区,这类问题"短时间"内出现太多,还是会觉得不太合适的.

没必要关啊, 你这种又不是来写小说又不是来写博客,只是认真问个问题.

Emacs 这程序本身是就以万能著称的啊(比起 vi 的优势)

好的, 那我少问 Lisp 无关的代码…
[请问这帖子怎么关闭咯?]

我觉得只要提问的人还在用emacs或者写lisp那就没问题(抱团取暖),毕竟emacs、lisp已经那么小众了,找同类困难,我身边找不到任何一个用emacs的人(大都不知道emacs是啥)。如果不用emacs,不用lisp的又来这里水的,才应该删掉

2 个赞

嗯, 所有做前端的都要用CSS吧? 但是像我(全栈)这样后端用Lisp的屈指可数…
我这要做的网站后端也是要用Common Lisp:

Hunchentoot + Hunchensocket + (自己积累的框架: celwk + smart-sever + management-system 一层层逐层积累, 逐渐用 WebSocket 来代替 HTTP/AJAX/Fetch )

你这个 tab 肯定要借用 css + js 实现的。因为你的操作分为两个步骤:

  1. 执行缩小动画
  2. 删除这个元素

一般如果使用框架的话都会有别的库实现,但是我主要说下原生方法吧

首先点击关闭的时候使用 js 给这个元素加上一个动画类名,例如 ‘will-closing’

.will-closing {
  width: 0;
  padding: 0;
  animation: all .3s ease;
}

加上这个类名之后再启动一个定时器,在动画结束时删除这个元素

setTimeout(() => {
   // remove dom
}, 300);

不需要获取元素大小,动画也是使用css实现,只是用js动态增加类名和最终移除操作。

你不需要用 setTimeout 而应该用 onanimationend

你是指 transition 吗?(不然需要动画名啊)
这两个都不可行, 因为 width 的初始值不知道的(max-content)
目前我只想到了一个通过 min-width 来触发 animation (from 100px to 0px )

不好意思,css打错了,确实是 transition。

使用transition 无需知道 width 值呀?直接 width -> 0 就出现动画了。

不行,width需要是一个具体的值才可以,如果width没设置是根据内容自动撑开的话,是没有过渡动画效果的。

可以再外面加一层元素,然后内层元素设置max-width: 100%;,然后隐藏元素添加一个class比如hide, 然后hide的内容是重新设置max-width: 0px;然后再加上transition过渡就可以了

点击事件开始的时候将width设置上去,然后马上将width设为0,动画还是用transition过渡动画。

我用react撸了一个例子:

import { FC } from 'react';
import styles from './test.module.scss';

const testList = [
  '咨询列表',
  '员工管理',
  '课程管理',
  '学员统计',
  '账单统计',
  '管理员账号',
];

const Test: FC = () => {
  return (
    <div>
      <ul className={styles.list}>
        {testList.map((text) => (
          <li
            className={styles.item}
            key={text}
            onClick={(e) => {
              const w = e.currentTarget.clientWidth;
              e.currentTarget.style.width = `${w}px`;

              /* 触发浏览器重新渲染,使上面的设置生效,使过度动画顺滑 */
              e.currentTarget.clientWidth;

              e.currentTarget.style.width = '0px';
              e.currentTarget.classList.add(styles.hide);
            }}
            onTransitionEnd={(e) => e.currentTarget.remove()}
          >
            {text}
          </li>
        ))}
      </ul>
    </div>
  );
};

export default Test;

scss

.list {
  display: flex;
  margin: 0px;
  padding: 0px;

  li {
    display: flex;
    justify-content: center;

    flex-shrink: 0;
    list-style: none;

    margin-right: 20px;
    white-space: nowrap;
    overflow: hidden;

    transition: all 0.2s linear;
  }

  .hide {
    margin-right: 0px;
  }
}

transform属性不起作用是因为transform仅仅是改变显示效果而已,元素所在的位置和大小再文档里面是不会有任何改变的,之前该在哪里还是在哪里,该占多大的宽高还是占多大的宽高。

说白了transform就只是个障眼法而已