SASS styles injected by innerHTML don't work - javascript

I want to inject style to div in component. My issue is it's scss and in application we use scss but style does not want to work. When inject the same style as css one. Everything works fine. The question is how can I force my component to execute style like this? Is it even possible or should I convert scss style to css one?
HTML.TS
<div id="myExampleId">
<div #htmlContainer [innerHtml]="htmlToDisplay | safehtml"></div>
</div>
Style to display in component:
<style>
#myExampleId {
table {
border-collapse: collapse;
width: 100%;
}
th{
background-color:#fe996b;
}
td, th {
border: 1px solid #999;
padding: 0.5rem;
text-align: left;
}
body {
background-color: #fe996b;
}
}
</style>

Import the styles not in the template but in the component itself.
Look in Angular docs https://angular.io/guide/component-styles

Related

Is there a way to select an element based on background color?

I want to change the background-color of a child of a div with a certain background color and was wondering if this could be done with CSS. I'll explain the case below.
something like:
.container[background-color=some color] .content {
background-color: some other color
}
My guess is that it can't be done because you would then be able to do something along the lines of:
.div {
background-color: some color
}
.div[background-color=some color] {
background-color: some other color
}
Which would create some kind of circularity where the div would be selected, set to the other color, then not be selected anymore and fall back on the original definition, but then be selected again because it has that original color.
I don't think the :has, :is and :where selectors work this way either but I was hoping there was some way this could be done while avoiding doing it in Javascript.
The Case
Divs are created dynamically based on errors in user input. These divs may or may not contain a certain type of error for which another div is needed
// simple errors
<div class="errors">
<p>Error 1</p>
<p>Error 2</p>
<p>Error 3</p>
<p>Error 4</p>
</div>
// more complex errors
<div class="errors">
<p>Error 1</p>
<div class="complex-error">
<p>Complex Error 1</p>
</div>
</div>
I give the errors div a background color with odd/even
.errors {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto;
border-radius: 4px;
margin: 8px 0px;
}
.errors:nth-child(odd) {
background-color: #dee2e6;
}
.errors:nth-child(even) {
background-color: #f8f9fa;
border: 2px solid #dee2e6;
}
I was wondering whether or not the elements with class errors could be selected based on background color to then select it's child.
I'll post my own solution as the answer.
The best way to do it without using JavaScript would be with classes. You can add the first background-color with a class that you add to the children that need to have that background color. Then, you change the background-color of only the children that have that class. And if you need to you can add and remove the class dynamically with JavaScript (as you are not providing an example of the whole app I don't fully understand the behaviour you are looking for).
div.black {
background-color: black;
}
div.white {
background-color: white;
}
div.black {
background-color: #5A5A5A;
}
This is the way you could do it. Separate the class out to style the background color then use the class selector .class1.class2 to apply the rule to only the parent. Use the descendent class combinator to apply the background colour to the child.
Here's an example
.parent {
border: 1px solid black;
padding: 1rem;
font-size: 1.5rem;
margin-top: 1rem;
}
.yellow-backgroud {
background-color: yellow;
}
.red-background {
background-color: red;
}
/* this selects all child divs where the parent has the parent class AND the yellow-background class */
.parent.yellow-background div {
background-color: green;
}
/* this selects all child divs where the parent has the parent class AND the red-background class */
.parent.red-background div {
background-color: orange;
}
<div class='parent yellow-background'>
Parent
<div>
This is a the child of the yellow background parent
</div>
</div>
<div class='parent red-background'>
Parent
<div>
This is a the child of the red background parent
</div>
</div>
<div class='parent'>
Parent
<div>
This is a the child with no parent background color set.
</div>
</div>
The odd/even selector can already be used to select those elements.
.errors:nth-child(odd) {
background-color: #dee2e6;
}
.errors:nth-child(odd) .complex-error {
background-color: #f8f9fa;
}
.errors:nth-child(even) {
background-color: #f8f9fa;
border: 2px solid #dee2e6;
}
.errors:nth-child(even) .complex-error {
background-color: #dee2e6;
}
There was no reason to select them after the fact when you can just select them at the place where they are defined.

Using dark or light mode

what is the best way to incorporate something like this into my site? I've tried using plugins but I cant get it to work. Doesn't have to be fancy.
Does anyone have it or have used one in the past they can recommend? Otherwise, is there a way to code it using JavaScript?
You could just set a button to trigger a boolean for example and based on its values, change the background-color of the items you want to change into dark mode.
I personally used react context for this one, something like this (kinda perfect how they used theme as an example). You should study it.
It depends on your framework, but if you use Material-UI, it has this option.
you can change palette type from light to dark and vice versa to achieve your requirements. Take a look here.
But if you don't use any framework, you should make a css structure that has two classes, light and dark, have some properties like color and background color and etc., and when the toggle theme button clicked, you will change all your classes from light to dark for example, also you can use animation for the effects.
There is a multiple solutions for this problem, if you are using a specific framework I suggest you check if there a way to do it with it, if you are not using any framework you still have multiple solutions and I suggest to create for each element you want to change his properties to dark mode another CSS class for each one, and with JavaScript create a function (that can call by a button on the html) that change all the element you want to those external classes, and if you click this button once again is reverse the function and make all the classes be with the original CSS classes
Maybe this should help you to kickstart.
<html class="theme-light">
<style>
html, body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
}
.theme-light {
--color-primary: #0060df;
--color-secondary: #fbfbfe;
--color-accent: #fd6f53;
--font-color: #000000;
}
.theme-dark {
--color-primary: #17ed90;
--color-secondary: #243133;
--color-accent: #12cdea;
--font-color: #ffffff;
}
.container {
display: flex;
width: 100%;
height: 100%;
background: var(--color-secondary);
flex-direction: column;
justify-content: center;
align-items: center;
}
.container h1 {
color: var(--font-color);
}
.container button {
color: var(--font-color);
background: var(--color-primary);
padding: 10px 20px;
border: 0;
border-radius: 5px;
}
</style>
<script>
// Set a Theme
function setTheme(themeName) {
localStorage.setItem('theme', themeName);
document.documentElement.className = themeName;
}
// Toggle From light and dark theme and Vice-Versa
function toggleTheme() {
if (localStorage.getItem('theme') === 'theme-dark') {
setTheme('theme-light');
} else {
setTheme('theme-dark');
}
}
// Onload Theme
(function() {
if (localStorage.getItem('theme') === 'theme-dark') {
setTheme('theme-dark');
} else {
setTheme('theme-light');
}
})();
</script>
<body>
<div class="container">
<h1>Theme Switcher</h1>
<button id="switch" onclick="toggleTheme()">Switch Theme</button>
</div>
</body>
</html>
This is a simple approach that I've used several times:
On the main html file, I load the default theme, for example the light one:
<link rel="stylesheet" href="/themes/light/theme.css" id="linkTheme" />
Then, on the theme changer button/menu option, I change the CSS file of the above link to load the corresponding one, something like:
const handleToggleTheme = (dark) => {
const lightUrl = "/themes/light/theme.css";
const darkUrl = "/themes/dark/theme.css";
if (dark) {
document.getElementById('linkTheme').setAttribute('href', darkUrl);
}
else {
document.getElementById('linkTheme').setAttribute('href', lightUrl);
}
}

JS Sapper + Bulma breakpoints in (S)CSS

I'm trying to use Sapper with Bulma and (S)CSS.
My goal is to apply various paddings on "main" inside of src/routes/layout.html, with padding on desktop devicees, and without (or a smaller one) on mobile.
Using the predefined breakpoints or mixins doesn't work properly for me, as the following code raises an SCSS error :
EDIT: this is the svelte component:
<script>
import 'bulma/css/bulma.css'
// or import 'bulma/bulma.sass' ???
</script>
<style type="text/scss">
main {
position: relative;
max-width: 56em;
background-color: white;
margin: 0 auto;
sizing: border-box;
padding: 0.5em;
+desktop-only {
padding: 2em;
}
}
</style>
What's wrong and how to fix it ?

Is it possible to assign a class to :root?

As I am thinking about solutions to another problem of mine, I am trying to understand to which extend CSS elements can inherit from other elements. Specifically, having the following definition
.dark {
background-color: black;
}
.light {
background-color: white
}
is it possible to programmatically assign (with JS, probably) one of these classes to the :root element?
It can be done easily with JS.
Select the element:
const root = document.querySelector(':root')
Assign the class to it:
root.classList.add('light')
All together:
const root = document.querySelector(':root')
root.classList.add('light')
Or, instead of having two classes, it might be better to have a :not() selector:
:root:not(.dark){
background-color: white;
}
:root.dark{
background-color: black;
}
I would use (and have used) CSS variables for this.
:root {
--background-color: black;
}
.background {
background-color: var(--background-color);
}
Then change the CSS variable with javascript.
In HTML, :root is equivalent to <html> (doc):
In HTML, :root represents the element and is identical to the
selector html, except that its specificity is higher.
A possible solution would be to apply the class to <html>:
document.getElementsByTagName("html")[0].classList.add('dark')
.dark {
background-color: red;
}
<html>
hello
</html>

Rubaxa sortable with polymer / Drag and Drop not working depending on display:

I have tried to get rubaxa sortable (http://rubaxa.github.io/Sortable/ ) working with polymer.
I started with rubaxa-sortable, which should do exactly that, and works well for standard items ( https://github.com/divshot/sortable-list/blob/master/sortable-list.html)
However, as soon as I use custom elements the effects become strange.
An old thread (http://polymer-dev.narkive.com/YWiwS9A9/custom-element-drag-and-drop) has given me the hint to check different display types.
Behavior is as follows:
display: block: no dragging possible
display: inline: dragging possible, but ghost is far from mouse
display: inline-block: dragging possible, but ghost is far from mouse
Any ideas on how to fix that? The other post seems to suggest it is a bug, but that was a year ago..?
To illustrate I have copied the sortable-list code to jsbin and extended it: http://jsbin.com/zemugeyulo/1/edit?html,output
Any ideas if that is fixable? I have just started with those topics, so I might have missed something obvious..?
Solution
My mistake was to put the display tag in the wrong place. I did:
<polymer-element name="custom-element" attributes="text display">
<template>
<style>
div {
display: {{display}};
background: grey;
border: 1px solid #ddd;
border-radius: 3px;
padding: 6px 12px;
margin-bottom: 3px;
width: 80%;
}
</style>
<div>
<b>{{text}}</b>
</div>
</template>
<script>
Polymer({});
</script>
Where the correct solution would be
<polymer-element name="custom-element" attributes="text display">
<template>
<style>
:host {
display: {{display}};
}
div {
background: grey;
border: 1px solid #ddd;
border-radius: 3px;
padding: 6px 12px;
margin-bottom: 3px;
width: 80%;
}
</style>
<div>
<b>{{text}}</b>
</div>
</template>
<script>
Polymer({});
</script>
#rubaxa: Thanks for the support and the great library!
As I understand it, you can fix this by specifying display directly at custom-element.
Or something like that (although it is not pretty):
// Bind on `mousedown`
function fixDisplay(evt) {
var el = evt.target;
if (el.shadowRoot) {
var realEl = evt.target.shadowRoot.lastElementChild;
var style = window.getComputedStyle(realEl);
el.style.display = style.display;
}
}
http://jsbin.com/fageve/1/edit?html,output

Categories