使用CSS交换两个按钮的位置
最近搞组件库的时候发现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。
方案零:使用 ant design 的 footer
这是我首先想到的方式,重新实现一下对话框的按钮,后来仔细考虑了一下,感觉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的方式是温柔的话,那这种方案是温柔到家了~