接触React
+ Ant Design
开发也有一段时间了,也已经慢慢习惯了React
+ Ant Design
。最近开发的需求功能里,需要一个全屏弹窗的功能,类似于ElementUI
里的Dialog
组件fullscreen
属性设置为true
的效果。然而发现Ant Design
的Modal
组件并不支持全屏效果。
去Github上翻了一下其他开发者提的issue,发现2018年的时候有其他开发者已经提了:https://github.com/ant-design/ant-design/issues/12359
而Antd
开发者afc163对于此需求则回复:
建议自行封装吧,暂时不会增加这样的功能。
如果内容比较多,也可以尝试 Drawer。
看来只能自己动手丰衣足食了。
Modal
组件提供了比较丰富的参数,其中有两个参数,分别是bodyStyle
、style
以及width
。其中bodyStyle
参数控制Modal
组件的body
部分样式,style
参数则用于设置浮层的样式,调整浮层位置等,width
参数控制宽度。
所谓全屏,说简单一点,就是弹窗的宽度和高度分别等于浏览器可视区域的宽度和高度。
对于宽度,我们尝试通过设置参数width="100vw"
来控制弹窗的宽度:
<Modal
title="Basic Modal"
width="100vw"
visible={isModalVisible}
onOk={handleOk}
onCancel={handleCancel}
>
...
</Modal>
然后发现通过上述方式改变宽度之后,弹窗的左右及上下区域,分别出现了空白:
对于左右两边区域的空白,我们通过F12查看网页源代码,可以发现是Modal
组件div
的max-width
样式导致:max-width: calc(100vw - 32px);
:
针对于这个问题,我们只要通过Modal
组件的style
参数来修改max-width
样式,将其设置为100vw
即可:
<Modal
style={{
maxWidth: "100vw"
}}
title="Basic Modal"
width="100vw"
visible={isModalVisible}
onOk={handleOk}
onCancel={handleCancel}
>
...
</Modal>
而对于弹窗的高度,我们通过设置参数style={{maxWidth: "100vw", height: "100vh"}}
,将高度设置为100vh
,发现并没有什么用,看来我们只能另辟蹊径了。
对于弹窗上边区域的空白,我们可以通过设置top: 0
的方式来消除:style={{maxWidth: "100vw", top: 0}}
,其中top: 0
表示Modal
组件div
元素,距离顶部设置为0。
另外,弹窗的高度,我们可以设置Modal
组件body
区域的高度,将其设置为100vh - 弹窗header部分高度 - 弹窗footer部分高度
即可,其中header部分和footer部分的高度分别为55和52:
代码:
<Modal
style={{
maxWidth: "100vw",
top: 0
}}
bodyStyle={{
height: "calc(100vh - 55px - 53px)"
}}
title="Basic Modal"
width="100vw"
visible={isModalVisible}
onOk={handleOk}
onCancel={handleCancel}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Modal>
然而问题又来了,弹窗底部出现了空白:
对此,我们需要额外的将padding-bottom
设置为0:
<Modal
style={{
maxWidth: "100vw",
top: 0,
paddingBottom: 0
}}
bodyStyle={{
height: "calc(100vh - 55px - 53px)"
}}
title="Basic Modal"
width="100vw"
visible={isModalVisible}
onOk={handleOk}
onCancel={handleCancel}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Modal>
对于上述方案,有一点点的瑕疵,就是弹窗body
部分内容过多,会出现body
部分内容超出弹窗窗口进行显示,进而使整个弹窗出现纵向滚动条。对此我们只需要简单的设置一下body
部分样式overflowY: "auto"
即可,最终代码如下:
<Modal
style={{
maxWidth: "100vw",
top: 0,
paddingBottom: 0
}}
bodyStyle={{
height: "calc(100vh - 55px - 53px)",
overflowY: "auto"
}}
title="Basic Modal"
width="100vw"
visible={isModalVisible}
onOk={handleOk}
onCancel={handleCancel}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Modal>
完整代码codesandbox地址:https://codesandbox.io/s/antd-modal-fullscreen-z9yz87?file=/demo.js
demo地址:https://z9yz87.csb.app/
具体实现思路和方案1类似,只不过该方案是通过修改css样式来实现的。代码如下:
.ant-modal {
width: 100vw !important;
max-width: 100vw !important;
top: 0;
padding-bottom: 0;
}
.ant-modal-body {
height: calc(100vh - 55px - 53px);
overflow-y: auto;
}
完整代码codesandbox地址:https://codesandbox.io/s/antd-modal-fullscreen-css-36ku09?file=/index.css
demo地址:https://36ku09.csb.app/
至此,Modal
组件的两种全屏实现方案都已经实现完成,希望有兴趣的朋友点个赞吧。当然,有想法的朋友也欢迎在评论区交流。