Blazor ignoring scoped CSS in Components - css

I have a similar problem as mentioned here.
The component MyComponent.razor has the scoped CSS MyComponent.razor.css.
Anyways, the style of the CSS file SOMETIMES is ignored. If I change the CSS it might work on the first start, or it might happen that I have to build the project 10 times before it works. If I move the Component (including the scoped CSS) from one folder to another and move it back, it is more likely to work as well.
It is also not a caching issue. When I hard refresh the browser and clear the cache, the CSS is still not loaded. In the dev tools, I am also not able to find the specific changes in the bundled CSS. E.g., if in the CSS I simply change the background-color of a class from blue to red, the background-color is still blue in the bundled CSS.
Within my _Host.cshtml the bundled style is added.
<head>
...
<link href="<applicationName>.Client.styles.css" rel="stylesheet" />
</head>
Project.Client.csproj does not contain a
<RazorLangVersion>3.0</RazorLangVersion>

The issue was relatively hard to find, but I found the solution. The problems I faced were caused by the components themselves. Basically, my Pages/Components look something like this:
<MyComponentA></MyComponentA>
<div>
<MyComponentB></MyComponentB>
<MyComponentC class="customCssClass">
<MyComponentD></MyComponentD>
</MyComponentC>
</div>
To make styling work, I need to pass down the style with the ::deep CSS-Keyword. Otherwise, the style is not passed down to the component. This means, my CSS looks something like this:
::deep .customCssClass {
}
Keep in mind, that ::deep needs to be added to every CSS class, otherwise, it doesn't work (at least it didn't for me).
Another issue is that I found that under certain circumstances it still didn't work for some components. I honestly have no idea which part of my code breaks it, but the fix was to wrap the entire Page/Component into a div. My code from above would look something like this then:
<div>
<MyComponentA></MyComponentA>
<div>
<MyComponentB></MyComponentB>
<MyComponentC class="customCssClass">
<MyComponentD></MyComponentD>
</MyComponentC>
</div>
</div>
TLDR: Add ::deep to every CSS element and wrap the page/component into a div.

Related

Scoped Style Sheets without HTML5

I am needing an approach where I can scope CSS files to a certain portion of the page. In theory, this example should do what I need:
<html>
<head>
</head>
<body>
<div>
<style scope>
#import url("style1.css");
</style>
<div class="testText">Test with Style 1</div>
</div>
<div>
<style scope>
#import url("style2.css");
</style>
<div class="testText">Test with Style 2</div>
</div>
</body>
</html>
However, I found out that the scope element is only available in some browsers right now (Firefox 21+ mainly). So, I'm looking for a lazy way out or a problem. I need to integrate some content with different styles into a site. We tried loading both css filesets, but there are some style names that appear in both stylesheets, so it will be a lot of work to rename the style names in one fileset and in the corresponding html content, specially because you cannot just refactor with Eclipse... :)
Is there any other solution that can render such a result that is widely compatible?
Regards
Scoped styles aren't well-supported at this point and are going to cause you problems if you're expecting any sort of cross-browser coverage.
The only way you can really achieve what you're after is to use a unique classname (or ID) for each 'section' and then use inheritance to sort-of namespace your CSS. So if you want to target one specific section of the page, give it's parents a classname (eg: class="testone") and then make sure that any styles you want to apply to that section are appended with that classname:
.testone .title{...}
.testone h1{...}
.testone a{...
etc.
Failing that, there is also a jQuery-based scope polyfill which should give you a more browser-independent way of working with scoped CSS. It isn't something I've worked with so don't have any experience to offer, but it looks very promising from the few moments I've spent with it!
Do remember that as with any JavaScript-based solution like this one, anyone who loads your page without JavaScript enabled isn't going to get those little extra niceties so it's important to ensure that the page still behaves in an acceptable manner even when JS is disabled.
The attribute name in HTML5 drafts is scoped, not scope.
Support to it is slowly being implemented, but there is little reason to use the attribute, or scoped style sheets. Most browsers will take <style scoped> simply as <style> and apply it to the entire document.
Thus, it is best to analyze the problem you are trying to solve and find a different approach to it. In many cases, it is trivial, using suitable contextual selectors. Assign an id attribute to an element and use an id selector as the first component of selectors.

Selecting objects within a class

So, this is a question that's been nagging at me for a long time. I've been digging much more into CSS these days. I'm trying to stay away from jQuery for this project as it's in Drupal and I'm trying to stay away from custom code.
So, we have a class the system applies to BODY called "not-logged-in" when the user isn't logged in. Now this should work well for us (as I understand CSS), as we're only allowing admins to "log in". We are having collisions when we have someone editing a node -- all our custom classes are loaded in both cases and some of the editing controls are looking funky because of it.
So the BODY style is something like this:
<body class="html not-front not-logged-in no-sidebars page-node page-node- page-node-1 node-type-page footer-columns" >
... [much body content here--other divs, other classes, elements with IDs] ...
<div class='mycustomclass'>Should be bigger if logged in</div>
</body>
So, when I try to add a CSS selector and style, like this:
.not-logged-in .mycustomclass {
font-size: 20px;
}
It seems to ignore .mycustomclass. I've run into this before and chalked it up to my poor CSS-fu. And there was always jQuery, so I really didn't have to care. I'd really appreciate it if someone could clear this long-time mystery up for me.
Your syntax is fine, no problems there.
I imagine one of two problems:
The class is not actually being loaded, either on the body, or on your mycustomclass element. Check both in the rendered source (i.e. in the browser), not just your own code. As it's Drupal, it could be caching so your changes are not being loaded. Clear the Drupal cache.
Specificity. Perhaps there is another class on the element, or perhaps there's a global rule. Either way, something could be overriding your CSS on that element.
To solve both, use Firebug and the Web Developer Toolbar in Firefox. Both are essential for doing CSS.
Be sure that Drupal is adding the css script tags in the <head> of your HTML. You should have them follow after your stylesheet references. That's it, the drupal css (the one that is adding the not-logged-in class to the <body>) must execute before your css.

how can i customize default values of twitter bootstrap CSS? e.g class=container

in my <head> tags, ive placed the location of bootstrap.css
if i place <div class="container"> it creates a fixed width.
what i wanted to happen is manipulate the default values of the container width by importing another set of stylesheet.
another scenario is, if i placed a span8 how do i put background colors on it without actually editing the bootstrap.css rather, customize it using a new stylesheet.
does putting 2 stylesheet possible? then inherit / manipulate all values in the bootstrap.css in a new stylesheet?
i apologize if my explanation aren't that clear. its kinda hard to express verbally what i wanted to happen. :)
When you add a second stylesheet, you can override rules of the first one. Just make sure you add them to your html page in the right order.
If you want to make sure a rule won't be overridden you can add !important to it. Example:
.example {
color: red !important;
}
Yes it is possible. That is what the "Cascading" part of CSS is. Short answer is to add your own style sheet after the bootstrap.css and before the responsive.css and your styles will be used because they are the latest definition, i.e. the rules "cascade" down.
Long answer is take a look at the docs. There's a lot to learn there if you have the time.
Also have a look at the bootstrap customization page

Chrome Extension - Prevent CSS From Being Over Written

I am writing a Chrome Extension where a small panel appears on top of the existing website. When I go to certain websites, I notice that the CSS of my panel has been over-written by the website's CSS. I am currently using Eric Meyer's CSS Reset but it does not seem to be doing the trick. Is there something else I can do?
Here's a nifty 'hack' with iframes, where you don't actually instantiate an iframe:
Append an iframe to the DOM, this will be a container for your do dad
Walk into the iframe and add your HTML code to the innerHTML of the body
It looks like this:
var iframe = document.createElement('iframe');
document.documentElement.appendChild(iframe); //fastest way to append to DOM: http://jsperf.com/insertbefore-vs-appendchild/2
iframe.contentDocument.body.innerHTML = 'Normal link!!';
I'm not familiar with Chrome extensions themselves. But you could try scoping your panel within an 'id':
<div id='my-panel'>
PANEL GOES HERE
</div>
And then in the CSS just have #my-panel as the first selector for all of your css. Take the reset css and add the #my-panel identifier to each element defined there too. Might be tedious... but would ensure you're resetting all of your elements, and virtually guarantee that they'll be reset at a higher priority than anything the website might be defining.
An extension that I just wrote ran into similar problems. I've made most of them disappear, but not all of them. I think that I know why, but I haven't gotten around to fixing the exceptions (this is just a school assignment as of now).
Here is what I found: when a stylesheet is injected through the extension manifest or by the background page, it is treated as a user stylesheet, giving it cascade priority over the default browser stylesheet only. Adding !important directives to your rules will not help, at least in my experience. User stylesheets (added by an extension or manually) can contain !important directives, but they are not honoured by Chrome for some reason -- just check how they show up in the Chrome DevTools, without !important. Adding id attributes won't help either, as specificity will only trump where priority is equal otherwise.
What does work for me:
var ninjaCSS = document.createElement("link");
ninjaCSS.setAttribute("rel", "stylesheet");
ninjaCSS.setAttribute("type", "text/css");
ninjaCSS.setAttribute("href", chrome.extension.getURL('ninja.css'));
document.getElementById("head").appendChild(ninjaCSS);
This code is included in a JavaScript file that is listed in the manifest as a content script, and should run at document load. The CSS file is not listed in the manifest, but is included in the extension folder. Now the stylesheet is on an equal footing with the the other author stylesheets.
Of course, that is just the beginning. You can now give all elements in your panel an id attribute (you probably already have). Whether you use a style reset or not is up to you. But you will have to make sure that your styles specify every single rule that a stylesheet in the wild might try to manipulate. If you do not plan to change a rule from its default, you must still specify that default value. Even if the default value is "none";
Finally, you must bravely ignore all warnings that the !important directive is best used sparingly. Quite the opposite applies here. When you add !important to every one of your style rules, it will be as if you had not used it at all as far as your panel's cascade is concerned. On the other hand, you will now be the boss of your panel. Trust me, somebody is going to tack an !important directive on, say, their button:hover background-image rule. Leading your well-crafted buttons to inexplicably morph into concert images of a 1985 bon jovi concert -- but only when the mouse is hovering, so no worries, right?
appendChild solutions works for me (Devin G Rhode and jCyCle answers). But I noticed these solutions just add the attribute xmlns="http://www.w3.org/1999/xhtml". So I tested my code just by adding this xmlns attribute to my link tag (directly, not using JS) and it works too, don't know why.
Failing:
<link rel="stylesheet" type="text/css" href="filesystem:chrome-extension://................/temporary/Content/Styles/style.css" />
Working:
<link xmlns="http://www.w3.org/1999/xhtml" rel="stylesheet" type="text/css" href="filesystem:chrome-extension://.............../temporary/Content/Styles/style.css" />

Real Nested CSS? (Not Selector)

I am first time poster. A question. How do a make a css declaration that only works within one DIV, but, not overwriting the global css? I want to jQuery loading a page into a DIV, however, the page's CSS changed my own site's CSS. I don't want that. Also I can't just take out CSS because I want them looked as intended from the source.
Basically we are going to load an external HTML with its CSS style applied locally ONLY without it changing the style elsewhere. The external HTML is not using inline CSS since we don't have control over it. They are applied to class values or even all element type. We don't want their CSS declaration modifying our own existing CSS outside of the DIV container.
Is this even possible?
Thank You?
If I understand your question correct you would place an id in the div <div id="mystyle"> content </div>. In your CSS you would write #mystyle p { color:red; }. which have no effect on global paragraphs outside the "mystyle" div.
I guess you are asking how to apply an external stylesheet to just one div. There is no way to do this using just CSS. You might be able to emulate this using JavaScript, but it's going to take quite a bit of work. Here's an outline of how you might go about doing this:
Grab the stylesheet filename from the loaded HTML and then get the contents of the CSS file via AJAX.
Somehow parse the CSS and prefix your div ID to each CSS rule, so that it applies only within your div.
Inject the modified stylesheet as inline text into the loaded HTML.
Steps 1 and 3 are relatively simple, step 2 requires a CSS parser written in JavaScript. (There seems to be one available here although there is no documentation.)

Resources