如何垂直对齐Bootstrap v4模式对话框

时间:2016-12-29 10:12:19

标签: modal-dialog flexbox bootstrap-modal vertical-alignment bootstrap-4

Bootstrap 4中的垂直中心模态对话框。

注意:我已添加以下要求以明确我正在寻找一种 正确的 方式来垂直居中Bootstrap模式,覆盖所有可能的设备,在所有浏览器中覆盖所有可能的情况。在我的情况下,我想要一个大型SPA在整个应用程序中重用相同的模式,所以我需要它在每种情况下工作。

它应该:

  • 在所有设备上保持模态内容可访问,即使设备高度高于设备高度
  • 使用市场份额大于1%
  • 的任何设备+浏览器组合
  • 不使用display:table-cell或类似的黑客(任何布局技术不是为布局而设计的)
  • click之外的tap.modal-content关闭(包括上方和下方)。
  • 尽可能限制jQuery / JavaScript的使用
  • (可选)处理默认的Bootstrap示例,无需标记修改

10 个答案:

答案 0 :(得分:54)

自Beta 3起更新,[docs]

  

.modal-dialog-centered添加到.modal-dialog以垂直居中模式。

原始答案:

SCSS

.modal-dialog {
  min-height: calc(100vh - 60px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow: auto;
  @media(max-width: 768px) {
    min-height: calc(100vh - 20px);
  }
}

没有前缀 CSS

.modal-dialog {
    min-height: calc(100vh - 60px);
    display: flex;
    flex-direction: column;
    justify-content: center;
    overflow: auto;
}
@media(max-width: 768px) {
  .modal-dialog {
    min-height: calc(100vh - 20px);
  }
}

注1:请注意完全加前缀 CSS逐渐变得过时,因为某些属性的浏览器支持会发生变化。获取更新的前缀CSS的正确方法是:

  • 将未加前缀的CSS复制/粘贴到Autoprefixer
  • 将底部框中的过滤器设置为所需的设置(最大浏览器支持使用> 0%)。
  • 从右侧的框中获取最新代码。

注2:此答案是在 v4 alpha 3或4 )的早期阶段添加的,现在位于β。您可以通过将以下类添加到.modal-dialog来安全地替换此答案的CSS部分:

h-100 d-flex flex-column justify-content-center my-0

...,正如@Androbaut在下面的评论中指出的那样。你仍然需要JavaScript(见下文)关闭模态窗口下方/上方click tap的模态窗口。

jQuery(需要在点击/点按上方/下方关闭模式):

$('.modal-dialog').on('click tap', function(e){
  if ($(e.target).hasClass('modal-dialog')) {
    $('.modal').modal('hide');
  }
})

就是这样。

使用不同模式大小的工作代码段,完全带前缀的CSS和标记:

$('.modal-dialog').on('click tap', function(e){
  if ($(e.target).hasClass('modal-dialog')) {
  	$('.modal').modal('hide');
  }
})
.modal-dialog {
  min-height: -webkit-calc(100vh - 60px);
  min-height: -moz-calc(100vh - 60px);
  min-height: calc(100vh - 60px);
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -webkit-flex-direction: column;
     -moz-box-orient: vertical;
     -moz-box-direction: normal;
      -ms-flex-direction: column;
          flex-direction: column;
  -webkit-box-pack: center;
  -webkit-justify-content: center;
     -moz-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
  overflow: auto; 
}
@media (max-width: 768px) {
  .modal-dialog {
    min-height: -webkit-calc(100vh - 20px);
    min-height: -moz-calc(100vh - 20px);
    min-height: calc(100vh - 20px);   
  }
}

/* you don't need the CSS below this line. It's mainly cosmetic and for aligning the modal launch buttons */

.modal-content {
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -webkit-flex-direction: column;
     -moz-box-orient: vertical;
     -moz-box-direction: normal;
      -ms-flex-direction: column;
          flex-direction: column; }
.modal-content > * {
  -webkit-box-flex: 0;
  -webkit-flex: 0 0 auto;
     -moz-box-flex: 0;
      -ms-flex: 0 0 auto;
          flex: 0 0 auto; 
}
.modal-content > *.modal-body {
  -webkit-box-flex: 1;
  -webkit-flex-grow: 1;
     -moz-box-flex: 1;
      -ms-flex-positive: 1;
          flex-grow: 1; 
}

#Modal_2 .modal-content {
  min-height: 50vh; 
}

#Modal_3 .modal-content {
  min-height: 85vh; 
}

#Modal_4 .modal-content {
  min-height: 200vh; 
}

.full-page-center {
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
  -webkit-justify-content: center;
     -moz-box-pack: center;
      -ms-flex-pack: center;
          justify-content: center;
  -webkit-box-align: center;
  -webkit-align-items: center;
     -moz-box-align: center;
      -ms-flex-align: center;
          align-items: center;
  min-height: 100vh; 
}
.full-page-center button {
  margin: 15px; 
}
@media (max-width: 768px) {
  .full-page-center {
    -webkit-flex-wrap: wrap;
        -ms-flex-wrap: wrap;
            flex-wrap: wrap;   
  }
  .full-page-center button {
    display: block;
    min-width: 100%;
    margin: 10px 15px;
  }
  .full-page-center::after {
    display: none;
    -webkit-box-flex: 0;
    -webkit-flex-grow: 0;
       -moz-box-flex: 0;
        -ms-flex-positive: 0;
            flex-grow: 0;
  }
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://npmcdn.com/tether@1.2.4/dist/js/tether.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/js/bootstrap.min.js"></script>


<div class="container full-page-center">
  <button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#Modal_1">
    Tiny modal
  </button>
  <button type="button" class="btn btn-default btn-lg" data-toggle="modal" data-target="#Modal_2">
    Normal modal
  </button>
  <button type="button" class="btn btn-success btn-lg" data-toggle="modal" data-target="#Modal_3">
    Large modal
  </button>
  <button type="button" class="btn btn-warning btn-lg" data-toggle="modal" data-target="#Modal_4">
    Very large modal
  </button>
</div>
<div class="modal fade" id="Modal_1" tabindex="-1" role="dialog" aria-labelledby="modalLabel_1" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
        <h4 class="modal-title" id="modalLabel_1">Tiny modal</h4>
      </div>
      <div class="modal-body">
        I am cute...
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>
<div class="modal fade" id="Modal_2" tabindex="-1" role="dialog" aria-labelledby="modalLabel_2" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
        <h4 class="modal-title" id="modalLabel_2">Dull modal</h4>
      </div>
      <div class="modal-body">
        I am normal...
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Some action</button>
      </div>
    </div>
  </div>
</div>
<div class="modal fade" id="Modal_3" tabindex="-1" role="dialog" aria-labelledby="modalLabel_3" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
        <h4 class="modal-title" id="modalLabel_3">Don't call me fat</h4>
      </div>
      <div class="modal-body">
        Call me "oversized".
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-success">Some action</button>
      </div>
    </div>
  </div>
</div>
<div class="modal fade" id="Modal_4" tabindex="-1" role="dialog" aria-labelledby="modalLabel_4" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
        <h4 class="modal-title" id="modalLabel_4">Huge modal</h4>
      </div>
      <div class="modal-body">
        Comments, anyone?
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-warning">Some action</button>
      </div>
    </div>
  </div>
</div>

如果您发现任何错误或缺点,请告诉我们。我会花时间改进答案并保持有用。欢迎帮助完成这项任务。

答案 1 :(得分:7)

Here's a simple Flexbox Approach.

SCSS

.modal-open .modal {
    display: flex!important;
    align-items: center!important;
    .modal-dialog {
        flex-grow: 1;
    }
}

Working Demo

答案 2 :(得分:2)

将.modal-dialog-centered添加到.modal-dialog以使模态垂直居中。

<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModalCenter">
  Launch demo modal
</button>

<!-- Modal -->
<div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLongTitle">Modal title</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        ...
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>

答案 3 :(得分:1)

有一种更简单的方法来实现这一点,而无需编写一堆CSS覆盖或其他自定义CSS,基本上只使用股票引导类并添加一个额外的HTML元素来控制高度。

CSS(不需要见下文)

.modal > .row{
    flex: 1;
}

HTML(更新见下文)

<div id="dialogBox" class="modal fade d-flex">
    <div class="row justify-content-center"> <!-- Vertically Align Modal -->
        <div class="modal-dialog align-self-center" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Modal title</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <p>Modal body text goes here.</p>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-primary">Save changes</button>
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>
</div>

然后使用:

JS

$("#dialogBox").modal('show');

或HTML

<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#dialogBox">
  Launch demo modal
</button>

有可能只使用引导程序.row.colflex-XXX类来实现所需结果,但我无法使其工作。

最后一点,您可能需要添加:<body class="d-flex">以使所有内容生效,具体取决于您的其他CSS。

更新

有一种方法可以仅使用引导类h-100w-100实现此目的:

<div id="dialogBox" class="modal fade d-flex">
    <div class="row justify-content-center w-100"> <!-- Vertically Align Modal -->
        <div class="modal-dialog align-self-center" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Modal title</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <p>Modal body text goes here.</p>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-primary">Save changes</button>
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>
</div>

答案 4 :(得分:1)

此解决方案适用于需要滚动的小型和长型模式。

添加以下自定义css规则:

.modal-header {
  flex-shrink: 0;
}

.modal-body {
  overflow-y: auto;
}

并添加这些类:

  • modal-dialogh-100 my-0 mx-auto d-flex flex-column justify-content-center
  • modal-contentm-2

像这样:

<div class="modal-dialog h-100 my-0 mx-auto d-flex flex-column justify-content-center" role="document">
  <div class="modal-content m-2">
     ...
  </div>
</div>

答案 5 :(得分:1)

只需使用此类“以模态对话框为中心” 用于在屏幕中央垂直显示模态。

例如:

<div class="modal-dialog modal-dialog-centered" role="document">

谢谢

答案 6 :(得分:0)

使模态垂直对齐的另一种简单方法是将top: 50%;transform: translateY(-50%);margin: 0 auto调整为模态对话框类。

修改 缺点是您还必须将max-height: 100vh;设置为.modal-content。否则当模态比视口更高时,模态的顶部不再可访问。

<强>演示:

&#13;
&#13;
.modal.vertically-modal .modal-dialog {
  transform: translateY(-25%);
  top: 50%;
  margin: 0 auto;
}

.modal.vertically-modal.show .modal-dialog {
  transform: translateY(-50%);
}

.modal-content {
  max-height: 100vh;
  overflow-y: auto;
  padding: 40px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js "></script>

<button class="btn btn-primary" data-toggle="modal" data-target=".vertically-modal">Show modal</button>

<div class="modal fade vertically-modal" tabindex="-1" role="dialog" aria-hidden="true">
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      Vertically modal
    </div>
  </div>
</div>
&#13;
&#13;
&#13;

答案 7 :(得分:0)

通过将以下CSS添加到“ .modal-dialog ”类中,对我来说效果很好。您也可以使用自定义CSS类覆盖。

.modal-dialog {
      height: 100vh;
      display: flex;
      align-items: center;
}

答案 8 :(得分:0)

只需添加以模态对话框为中心的类以及如下所示的模型对话框

<head>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
 <button class="btn btn-success" data-toggle="modal" data-target="#MyModal">Launch Modal</button>     
<div class="modal align-middle" id="MyModal">
    <div class="modal-dialog modal-dialog-centered">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Modal Title</h5>
                <button class="close" data-dismiss="modal">&times;</button>
            </div>
            <div class="modal-body">Lorem Ipsum is simply dummy text of the                        printing and typesetting industry</div> 
            <div class="modal-footer">
                <button class="btn btn-info" data-dismiss="modal">Close</button>
            </div>                
        </div>
    </div>
</div>

答案 9 :(得分:0)

尝试一下,

::ng-deep{
    .modal-body{
        padding: 0.25rem;
        width: 600px !important;
    }
    .modal-content {
        position: relative;
        display: flex;
        flex-direction: row;
        margin-top: auto;
        margin-bottom: auto;
        width: 600px !important;
      }
}