In the context of .NET MVC (but that could also apply to other similar technologies), let :
FileUploadPage
and its child partial view FileDropZone
that would have a class identifying their view "type" on their root node :FileUploadPage.cshtml :
<div class="view-fileuploadpage">
<h2>File upload page view</h2>
@Html.Partial("FileDropZone")
</div>
FileDropZone.cshtml :
<div class="view-filedropzone">
File drop zone partial view
</div>
Like this :
.view-fileuploadpage h2 {
/* Spécific to the view FileUploadPage */
}
But NOT like this :
h2 {
/* Global, not what I want */
}
I like this way of doing things, because it prevents interferences from other pages in the CSS due to needlessly global selectors.
However there is a problem with that : the view-specific CSS rules apply to the view's own elements, but also to any other view that is being included as a child view. In the example above, the view FileDropZone
inherits the rules that are supposed to be specific to the view FileUploadPage
, which is an undesired consequence.
So my question is : how can I make the CSS rules that are supposed to be specific to my views own elements NOT apply to the child views as well ?
I could use the "direct child" opeartor in my selectors to specify the full "path" to the elements I want to style, like so :
.view-fileuploadpage > h2 {
/* Applies to the h2 of the view FileUploadPage */
/* DOes NOT apply to any h2 that would exist in a child view of FileUploadPage */
}
But this would make the code hard to maintain, because the selectors would have to be updated every time a piece of markup gets moved or modified within a view.
I'm having the exact same problem with JavaScript and query selectors, but I guess finding a solution for CSS would also solve the JavaScript problem.
You can use the :not()
pseudo-class to deselect grandchildren within a particular child.
.view-fileuploadpage h2:not(.file-drop-zone *):not(.more-children *){
color: #f00;
}
This assigns the color to all h2
elements excluding those in the stated classes within the :not()
selector.
The CSS file will need to be updated with the classes of new children if any.
The best solution will be to wrap all the contents of the view-fileuploadpage
or parent div that should not get the styling and use the class of this wrapper as a single selector. This way, the file will not need constant updating all future children and grandchildren are added within the wrapper.
Hence, instead of having:
<div class='view-fileuploadpage-one'>
<h2>Container</h2>
<p>...</p>
<div class='file-drop-zone'>
<h2>file drop zone</h2>
...
</div>
<div class='more-children'>
<h2>More children</h2>
...
</div>
</div>
You can opt for:
<div class='view-fileuploadpage-two'>
<h2>Container</h2>
<p>...</p>
<div class='content-wrapper'>
<!-- this wrapper will contain everything else -->
<div class='file-drop-zone'>
...
</div>
<div class='more-children'>
...
</div>
</div>
</div>
</div>
Which will be more or less:
<div class='view-fileuploadpage-two'>
...
<div class='content-wrapper'>
...
</div>
</div>
Kindly see my idea on this pen.