使用CSS交换两个按钮的位置
最近搞组件库的时候发现UED给的图里确认和取消的按钮和 Ant Design 官方的不太一样。Ant Design的确认按钮在右边,而我们设计是在左边。
如图:
图1:Ant Design默认的样式
图2:我们的设计样式
个人感觉这个问题还挺有意思,所以写个文章记录一下,下面是我的个人想到的解决文案。
基础代码
先把 Ant Design 的基础对话框实现。
1import React, { useState } from 'react';
2import { Modal, Button } from 'antd';
3
4const App = () => {
5 const [isModalVisible, setIsModalVisible] = useState(false);
6
7 const showModal = () => {
8 setIsModalVisible(true);
9 };
10
11 const handleOk = () => {
12 setIsModalVisible(false);
13 };
14
15 const handleCancel = () => {
16 setIsModalVisible(false);
17 };
18
19 return (
20 <>
21 <Button type="primary" onClick={showModal}>
22 Open Modal
23 </Button>
24 <Modal title="Basic Modal" visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
25 <p>Some contents...</p>
26 <p>Some contents...</p>
27 <p>Some contents...</p>
28 </Modal>
29 </>
30 );
31};
32
33ReactDOM.render(<App />, mountNode);
运行效果如图1。
方案零:使用 ant design 的 footer
这是我首先想到的方式,重新实现一下对话框的按钮,后来仔细考虑了一下,感觉Effort有点大,这种方法的灵活度最高,但实现代价也最大,而这典型的只是一个样式问题,不必这么兴师动众。所以这种方法暂时放弃。
方案一:使用绝对定位
这也是比较容易想到的方法,把下面几个按钮的定位方式改成绝对定位。实现如下:
1.ant-modal-footer {
2 position: relative;
3 padding-bottom: 40px;
4}
5
6.ant-modal-footer .ant-btn-default {
7 position: absolute;
8 right: 10px;
9}
10
11.ant-modal-footer .ant-btn-primary {
12 position: absolute;
13 right: 100px;
14}
效果如下:
不过Ant的确认和取消按钮支持自定义,如果我自定义的text很长,这种方案就不能很好的自适应了。
方案二:使用Flex
我不太喜欢方案一这种霸道,所以想到了温柔一点的flex,flex的子项里可以设置一个order,实现位置的排序。代码如下:
1.ant-modal-footer {
2 display: flex;
3 justify-content: flex-end;
4}
5
6.ant-modal-footer .ant-btn-default {
7 order: 2;
8}
9
10.ant-modal-footer .ant-btn-primary {
11 order: 1;
12 margin-right: 20px;
13}
效果如图:
方案三:使用transform
当我决定使用 Flex
时候,我又去网上找了一下,结果在Stackoverflow中又发现了更厉害的解决方案。
使用的是 transform: scale
属性。代码如下:
1.ant-modal-footer {
2 transform: scaleX(-1);
3 text-align: left;
4}
5
6.ant-modal-footer .ant-btn {
7 transform: scaleX(-1);
8}
效果如下:
这个方案就更有趣了,先使用 scaleX(-1)
把父级元素翻面,然后再使用 scaleX(-1)
把每个子元素都翻过来。
图3:先翻面父级元素
图4:再翻面子元素并改变 text-align
是不很神奇,如果Flex的方式是温柔的话,那这种方案是温柔到家了~