1

I have created a modal component in Angular. In a unit test, the modal is appearing in the DOM as shown: enter image description here

However, I start out with a style on app-modal2 that includes display:none, so what actually renders is just the fixed text above the modal -- the content of the modal is correctly omitted: enter image description here

When the user takes an action that adjusts the style to include display:block then the content of the modal correctly appears. Which is to say, the code is working exactly as I expect.

What I am confounded about is a unit test.

So: why my title ("Consternation on testing non-inherited-yet-inherited CSS display property") ?

Well, according to the docs, the display property is NOT inherited: enter image description here

Using browser dev tools, I have confirmed that is true: descendant elements have values other than none for the display property. So even though descendant elements are affected by an ancestor having display: none it is because the subtree rooted at the ancestor is removed -- and this is not considered inheritance. Well, OK, potayto, potahto... Not technically inherited, but acts like it.

The visibility of my modal is controlled by the display property. It is set either to display: none or display:block depending on user actions. But that is strictly dealing with visibility, not existence. That is, #myContent is present with either display value. Since I therefore cannot test for existence of #myContent I must test strictly for visibility.

So how do I check an element for visibility controlled by some ancestor's display value, since display is not inherited? Is there a way to check for any ancestor having display:none? Or is there some other way to do this?

Michael Sorens
  • 35,361
  • 26
  • 116
  • 172
  • Wouldn't checking display properties etc fall under the category of testing implementation details? Could you instead test by searching/querying for the existence in of the text `any content here...`? Or something like https://stackoverflow.com/a/51291842/5385381 – ksav Aug 01 '21 at 03:38
  • @ksav Good question, but no. In the edits I just made, I explain that that content will always be present. – Michael Sorens Aug 03 '21 at 02:57
  • I was chagrined to see my question closed prematurely, as I thought I was asking a clear question. Ah, language. Nevertheless, I have reworded it to, I hope, improve the clarity. :-) – Michael Sorens Aug 03 '21 at 02:59

2 Answers2

0

You can try using the jQuery parent() method, and put the style as the first argument.

Shafiq Jetha
  • 1,337
  • 16
  • 30
0

I found out pretty disturbing your question. I think is one of the most hard questions to answer because goes right to the core of cascading and inheritance.

As far as I could find, display property is the only property that can't be specified (but computed) on how should be display by UA. HTML tags are pre-defined styles, those styles are display on UA without any CSS file, e.g. p elements are display as inline.

I tested it too with devtools; forgetting JS at all for very front-end purposes. (Maybe I'll check with with JS later as -second part-). This answer is intended for all audiences, newbies and experienced devs.

Before declare what is going to be styled, we may note that we have dependencies from the browser (User Agent) that parses the stylesheet.

We do not define all universe of properties to be styled, so when is not defined, a property needs to be set and the user agent roles to set a property (doesn't have to be its initial value), there's no official specification on how UA must render websites, it's expected them to be display as the stylesheet specifies, which often, does not act likely according browsing experience.

Cascading

One of the fundamental design principles of CSS is cascading.

What does an User Agent (UA) cascades? Elements? Properties? Objects?

Well, UA treat HTML tags as elements, and those elements are called as box tree, as the same, text included inside an element are called as text node.

Since CSS syntax and its parsing is a perfect cascade, that is the only word that remains if we need to figure out about how (UA) must display HTML documents. The UA also applies its own style sheet. This means that rendering also depends on the way (units) we use to specify values, if we specify a lot of different values e.g. pixels, cm, percentages, relative units (em, rem), etc, the more information UA needs to parse to be displayed, that's why front-end developers should be encouraged to perform clean css styles with homogeneous units to squeeze every milisecond out of browsing perfomance (such important in mobile experiences).

Inheritance

When no declarations try to set a the value for an element/property combination. In this case, a value is be found by way of inheritance or by looking at the property’s initial value.

What is called for inheritance, it's just the css properties that can be inherited (those are already established).

So, if a css property seems to be inherited, it's not really inheritance behavior, it's cascading behavior, and it's inheritance becomes by the nature of the syntax for the specified css property.

Answer

The display property is not inherited, but when none property is set, all the descendants elements will no generate any box-model subtree nor text node, (JS could be forcing the element to be display for testing purposes).

In the case of display:none; when the box tree and text node descendants are hidden by the parent element, the style applied of none is by cascading, not by inheritance.

Screenshot

In the example below, the span that is descendant of the fourth div element has set the background property as inherit, but the background can't be inherited, that's why the span element does not display any color background. Otherwise, the span that is descendant of the third div element inherits the color property. The fourth div element has display set: inline; once again, display can't be inherited, that's why the span element does not inherit that property and is displayed as block by the UA.

*{
  border: 1px solid black;

}

.one {
  display:block;
}

.two {
  
}

.three{

  background:cornsilk;
}

.childthree{
  color:red;
}

span{
  background: inherit;
  position: relative;
  top:80px;
  border: 5px solid black;
  padding: 5px;
  margin:5px;
}

.four{
  display:inline;
}

canvas{
  background:#99e6ff;
}

html {
  padding:1em;
}
<div class="wrapper">
  <div class="one">one</div>
  <div class="two">two</div>
  <div class="three">three
    <div class="childthree">I'm a subtree inside the third div<br><span>I'm span tag</span></div>
    </div>
  <div class="four">four<p>i'm a p tag with thext content<span>I'm a span element inside a p element</span></p</p>
  <canvas></canvas>
</div>
citizen1
  • 61
  • 6