Preventing CSS from affecting child views - html

In the context of .NET MVC (but that could also apply to other similar technologies), let :
A tree of views, e.g the page view 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>
Some CSS rules which I would like to apply only to the view's own elements instead of globally :
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 everytime 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.
Thank you.

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.

Related

Reference Nested DIV for CSS Styling

Using Elementor I have a current HTML structure as per the below;
<div class="carousel-post">
<div class="elementor-element-overlay">
<div class="elementor-widget-container">
<div class="elementor-posts-container">
</div>
</div>
</div>
</div>
I need to reference the class "elementor-posts-container" therefore, I have added class "carousel-post".
In my CSS I want to display "elementor-posts-container" as FLEX however, only this DIV which is under "carousel-post".
CSS
.carousel-post, .elementor-posts-container
The above works but targets all .elementor-posts-container
***** Just an Explanation *****
Adding this as an answer since I am not able to add formatting.
It should be .carousel-post .elementor-posts-container. Remove the comma.
When the code is .carousel-post, .elementor-posts-container, with the comma (,) it means match either of the two.
When you remove the comma (,), it means match the child within the parent. -->>> This will match your usecase
To get a direct match of the direct parent-child relationship (when you need it in the future), do .carousel-post > .elementor-posts-container. This matches all the ".elementor-posts-container" divs directly within ".carousel-post".
***** EDIT *****
Doesn't this work:
.carousel-post .elementor-posts-container{
display: flex;
}
The above code means, all ".elementor-posts-container" inside ".carousel-post" should be "display flex".

Difference between two types of CSS class declaration

So, I have been using my own CSS class named myclass and Bootstrap built-in class container. My question is while declaring a with both classes.
Should I use
<div class="myclass container">some code</div>
this format, or:
<div class="myclass">
<div class="container">
some code
</div>
</div>
Does both work in the same way? Or these two are different?
They are different, first one you have 2 classes for the same element, and you can select the element by using the following rules:
.container {}
.myclass{}
.myclass.container{} or .container.myclass{}
The second example you have a parent and a child elemtns
which you can use the following rule:
.myclass .container {}
Both are totally different.
<!-- Here you're declaring ONE div element with two values on class atribute -->
<div class="myclass container">some code</div> this format
<!-- Here you're declaring TWO elements with a different class each one -->
<div class="myclass">
<div class="container">
</div>
</div>
Why this is so different?
HTML tags/eelements have default properties with default values, plus the properties and values that you put in addition.
For example:
if you set globally:
div{padding:5px;}
On the first example, the content inside the div will be padded 5px.
On the second example, the content inside container will be padded 10px.
That can happen with default properties rendered by the browser or globally applied by frameworks as bootstrap.

CSS class naming different?

I am working with the TN3 gallery (jquery slide show) and tried to change a class name to one that I found easier to understand. Thing is the class name that is within the div is different than the class name that controls it in the .css file? I am confused as I have never seen this before? I have only ever named a div class the same name as the class in my css code? Example is here:
<div class="tn3 description">
and in the .css file the class that controls this div is:
.tn3-image-description{Code here}
So my question is how can a differently named class work???
For me I understand the following:
<div class="description">
.description{Code here}
Interesting and I am keen to understand how this works as I have not seen things done this way before!
This div is using multiple (2) separate classes: tn3 and description.
Also check if any of the other CSS files are imported in the original css. This is usually done with #import url("another.css"); syntax, so you can search for #import statements.
Classes Are Only Conditions
<div class="a b"></div>
<style>
.a {color:blue;} /*The style only need to match a element with class "a"*/
.a.b {color:red;} /*The style need to match a element with class "a" AND "b"*/
</style>
Turns out that .a.b has overwritten .a and the div's text is in red.
e.g. no.2
<div>
<div class="c x"></div>
<div class="c"></div>
<div class="x"></div>
</div>
using .c.x {} will only style "c x"

Can I define (override) a class using a style attribute?

I'm working in a content management system that allows me limited (no) access to the stylesheets, but does allow me to insert CSS into certain templates. So I have this:
<div class="inside_widget">
<div class="input"><span class="form_label">Form stuff</span></div>
<div class="input"><span class="form_label">Form stuff</span></div>
<div class="input"><span class="form_label">Form stuff</span></div>
etc...
</div>
Where inside_widget, input, and form_label are all defined in a sheet I can't touch. I want to put some custom CSS on "form_label" without having to touch every single span.
I tried using the style attribute in the containing div, but that did not work.
<div class="inside_widget" style=".form_label {color:#FFFFFF;}" >
Note: I want to retain everything else in the inside_widget styling, and not have to define a whole new class.
I think what the OP is trying to achieve is not having to repeat the style="" attribute for every single <span> in his form.
This can be done by simply adding your own class name to the enclosing div's classes:
<div class="inside_widget myclass" ...>
<!-- ... -->
</div>
Then make your own secondary stylesheet and define myclass:
.myclass span
{
color: #ffffff;
}
You can put this secondary CSS either in a <style> tag in the HTML itself, or in its own CSS file linked in.
You could do it this below.
<span class="form_label" style="color:#FFFFFF;">Form Stuff</span>
Inline styles like this will overwrite any css rules in a stylesheet, unless in the stylesheet they have a rule with !important
you do not know css right? will look like
<div class="inside_widget" style="color:#FFFFFF;" >
but I suggest you create a new css file and add whatever you want in the same

Logical AND for CSS3

I have a quite interesting problem here.
I want to target elements that match two conditions at the same time, but I can not find the way
<div class='redLink'>
<!-- ... ... ... -->
<a href='#'>Link</a>
<!-- ... ... ... -->
</div>
<div>
<!-- ... ... ... -->
<a href='#' class='redLink'>Link</a>
<!-- ... ... ... -->
</div>
My ideal CSS would be
[*:not(.redLink) a] AND [* a:not(.redLink)] {
color:green;
/* i.e., color NOT red */
}
However, the operand , is just an OR (and, when it doesn't match one condition, it matches the other...!).
And the only AND I can find is the logical concatenation div#myDivId.someClass, though what I would like is something like [div#myDiv a].[div.someClass a]
My goal is to target ONLY those anchors <a/> that don't have the class .redLink and have no parents with the .redLink class eiher.
And, very important, the only thing I want to target is the final anchor, not the whole div or the whole element.redLink...
Thank you!
Unfortunately, you can't achieve this using a CSS selector with a single rule. Currently you can only target a elements without the class using a:not(.redLink).
It is not possible to target a elements that do not have any .redLink ancestors, because the :not() pseudo-class doesn't accept combinators (otherwise you would do a:not(.redLink a)). A selector like :not(.redLink) a wouldn't work either, because that targets a elements with at least one ancestor without the class, which is not the same as a elements that have no ancestors with the class.
For example if your structure looked like this:
<div class='redLink'>
<p>
<a href='#'>Link</a>
</p>
</div>
That p doesn't have the class, so :not(.redLink) a would match.
If you happen to have the option of using jQuery, though, $('a:not(.redLink, .redLink a)') will work, because :not() is much more permissive in jQuery than in CSS.
If you need to do this using CSS only, the easiest solution is to make all a elements green, then override it:
a {
color: green;
}
a.redLink, .redLink a {
color: red;
}
Maybe you can reverse the logic like this. Make every link green (if that is possible in your site) and make the specific links red again.
a {
color: green;
}
a.redlink,
.redlink a {
color: red;
}
Of course it depends on the structure and complexity of your site and the existance of other styling that might collide with this, but I would prefer a CSS-only solution like this over JQuery if it is reasonably possible.