Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modal Dialog is obscured by opaque background

Tags:

element-ui

I am using Element's Notification component but when it is activated the dialog appears but seems to be "behind" the grey background that is also introduced. Clicking anywhere removes the grey background and allows the interaction with the dialog box but without the greyed out background that should be filtering out the noise of the normal screen. Here is a short video that shows the various states:

video

The code to put the component in as follows:

  <div class="add-address" @click="showAddDialog = true">
    +
  </div>
</div>
<el-dialog
  title="Add New Address"
  :visible.sync="showAddDialog"
  width="30%"
  :before-close="newAddressDialogClosed">
  <span>Postal Address</span>
  <el-input v-model="newAddress" type="text"></el-input>
  <span slot="footer" class="dialog-footer">
    <el-button @click="dialogVisible = false">Cancel</el-button>
    <el-button type="primary" @click="dialogVisible = false">Confirm</el-button>
  </span>
</el-dialog>

I have used the inspector to poke around at the CSS but I haven't yet understood what's causing this from a CSS perspective nor a Vue/Element perspective. Any help would be appreciated.


I have further analyzed the HTML/CSS and the component appears to introduce two separate blocks in the DOM:

enter image description here

The lower block is the grey background which you'd expect to "blur" the page and focus attention on the modal. It, however, is in front of the dialog. Also of interest is that clicking anywhere seems to target the grey background and dismiss it but in so doing it also has a subtle effect on the placement on the dialog box as can be seen here:

enter image description here

Note that the z-index of the dialog box is greater than the background which intuitively makes sense to me but I'd have thought this would have put the dialog box on top. Guess that's not all there is to this.


I have hacked a work-around for now by changing the background to display: none and then adding the following HTML directly before the modal dialog in the DOM:

<div class="modal-background" v-if="showAddDialog"></div>

These seems to validate my underlying suspicion that placement within the DOM tree is important and the component's attempt to place the modal background at the very end of the DOM is somehow problematic.

like image 789
ken Avatar asked Dec 19 '17 13:12

ken


1 Answers

I had the same issue and also found changing the z-index of the dialog had no effect. This was occurring when I had nested Element.Eleme.io elements, which appears to be the case for you also.

The z-index is not quite as simple as "higher always means on top". Elements are grouped into different stacking contexts; it is not possible for an element in a lower stacking context to appear above an element in a higher stacking context. Therefore depending on where the different elements were rendered in the DOM, they can land themselves in different stacking contexts, and are destined to remain at the same relation to one another, no matter how much the z-index has changed. (See https://philipwalton.com/articles/what-no-one-told-you-about-z-index/ for a more detailed explanation on the z-index).

Examining with Chrome dev tools, I found that the obscuring modal is not rendered in the same place as the dialog; in fact it is appended to the body, i.e. on the outer reaches of the application, which appears to be the reason they are not within the same stacking context. There is a quick fix; the dialog element has a property "modalAppendToBody". If true, the modal is rendered to the body, and if false it is rendered to the parent element of the dialog. By specifying this as false I managed to solve the issue:

<el-dialog
  title="Add New Address"
  :visible.sync="showAddDialog"
  width="30%"
  :before-close="newAddressDialogClosed
  :modalAppendToBody="false">
</el-dialog>
like image 192
hannahcodes Avatar answered Sep 28 '22 19:09

hannahcodes