Bootstrap's modal-dialog behaviour has changed significantly since Version 2.0.x.
What interests me here is the behaviour I had previously been testing in Jasmine specs to detect whether the dialog was being shown or not. In earlier versions, Bootstrap would add the CSS class modal-open
to the HTML body
to indicate that there was a modal open somewhere on the page. You can make any of several arguments why that's a poor mechanism, including the fact that you can't look at the currently active DOM and easily tell which of several possible dialogs on a page is active.
Now, the markup for the outermost containing div
of the dialog has changed significantly. I used this jsFiddle to explore how Bootstrap modifies that div
in the DOM as of Bootstrap version 2.3.0.
Attachment 01-as-written.html
shows the markup of a sample dialog, as copied from their example of a "live demo" dialog. Note the outermost div
markup:
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
Attachment 02-as-shown.html
shows the markup active in the DOM while the dialog is being shown. Again, note the outermost div
markup:
<div id="myModal" class="modal hide fade in" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="false" style="display: block;">
What's changed?
- The CSS class
in
has been added to thediv
. (No change was made to any containing block's markup). - The value of the attribute
aria-hidden
has changed fromtrue
tofalse
. - A new
style
attribute was added, with the valuedisplay: block
, so that the entirediv
is shown as one contiguous block in the rendered page.
Finally, attachment 03-after-close.html
shows the markup active in the DOM after the dialog has been "closed" (hidden). The outermost div
now reads:
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="display: none;">
- The CSS class
in
has been removed. - The
aria-hidden
attribute has been restored totrue
. - The CSS
style
attribute has been changed todisplay: none
, rather than being removed to match the initial markup.
- Markup is now significantly more complex, with more fully-fledged ARIA role information being specified.
- Markup changes as dialog state changes are now localised to the dialog markup, rather than polluting the page
body
. - Whereas earlier Bootstrap versions could tell if a dialog was being shown, now we can inspect the DOM to see which dialog is being shown.
- Inspecting the DOM now indicates if a dialog has not yet been shown, is currently being shown, or has been hidden after being shown one or more times.
All this explains why my dialog specs broke after upgrading to the latest version of the bootstrap-sass
Gem, which includes Bootstrap 2.3.0 (the now-current version). I've written this up as a warning and an explanation to myself and others using Bootstrap modals as to why we're suddenly chasing our tails on things that "should Just Work". The accompanying jsFiddle is an easy way to explore changes in future Bootstrap versions; copy the amended sample modal-dialog code over and have a look.