闻心阁

一蓑烟雨看苍生,半壶浊酒笑红尘

使用CSS交换两个按钮的位置

2022-02-27 约 1 分钟读完 搬砖秘籍

最近搞组件库的时候发现UED给的图里确认和取消的按钮和 Ant Design 官方的不太一样。Ant Design的确认按钮在右边,而我们设计是在左边。

如图:

图1:Ant Design默认的样式

图2:我们的设计样式

个人感觉这个问题还挺有意思,所以写个文章记录一下,下面是我的个人想到的解决文案。

基础代码

先把 Ant Design 的基础对话框实现。

import React, { useState } from 'react';
import { Modal, Button } from 'antd';

const App = () => {
  const [isModalVisible, setIsModalVisible] = useState(false);

  const showModal = () => {
    setIsModalVisible(true);
  };

  const handleOk = () => {
    setIsModalVisible(false);
  };

  const handleCancel = () => {
    setIsModalVisible(false);
  };

  return (
    <>
      <Button type="primary" onClick={showModal}>
        Open Modal
      </Button>
      <Modal title="Basic Modal" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
      </Modal>
    </>
  );
};

ReactDOM.render(<App />, mountNode);

运行效果如图1。

这是我首先想到的方式,重新实现一下对话框的按钮,后来仔细考虑了一下,感觉Effort有点大,这种方法的灵活度最高,但实现代价也最大,而这典型的只是一个样式问题,不必这么兴师动众。所以这种方法暂时放弃。

方案一:使用绝对定位

这也是比较容易想到的方法,把下面几个按钮的定位方式改成绝对定位。实现如下:

.ant-modal-footer {
  position: relative;
  padding-bottom: 40px;
}

.ant-modal-footer .ant-btn-default {
  position: absolute;
  right: 10px;
}

.ant-modal-footer .ant-btn-primary {
  position: absolute;
  right: 100px;
}

效果如下:

不过Ant的确认和取消按钮支持自定义,如果我自定义的text很长,这种方案就不能很好的自适应了。

方案二:使用Flex

我不太喜欢方案一这种霸道,所以想到了温柔一点的flex,flex的子项里可以设置一个order,实现位置的排序。代码如下:

.ant-modal-footer {
  display: flex;
  justify-content: flex-end;
}

.ant-modal-footer .ant-btn-default {
  order: 2;
}

.ant-modal-footer .ant-btn-primary {
  order: 1;
  margin-right: 20px;
}

效果如图:

方案三:使用transform

当我决定使用 Flex 时候,我又去网上找了一下,结果在Stackoverflow中又发现了更厉害的解决方案。

使用的是 transform: scale 属性。代码如下:

.ant-modal-footer {
  transform: scaleX(-1);
  text-align: left;
}

.ant-modal-footer .ant-btn {
  transform: scaleX(-1);
}

效果如下:

这个方案就更有趣了,先使用 scaleX(-1) 把父级元素翻面,然后再使用 scaleX(-1) 把每个子元素都翻过来。

图3:先翻面父级元素

图4:再翻面子元素并改变 text-align

是不很神奇,如果Flex的方式是温柔的话,那这种方案是温柔到家了~

Demo

  1. use-absolute - CodeSandbox
  2. use-flex - CodeSandbox
  3. use-transform - CodeSandbox