Advanced CSS Selector - Select based on styling - css

Performance issues aside, is it possible to use a style as a selector? For example, something like:
div[background-image="img/someimg.jpg"] {opacity:.5}
My fallback plan is to use javascript and iterate over divs (adding a class when found), but this might end up being even more expensive given that the page is highly dynamic, and I'm not in control of the divs being added.

Even if there are a lot of styles, you can do this by using the asterisk as seen here, so this code:
div[style*="box-sizing: border-box;"] {
background-color: #ffffe0;
}
easily matches this HTML:
<div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, " courier="" new",="" monospace;="" font-size:="" 12px;="" color:="" rgb(51,="" 51,="" 51);="" border-top-left-radius:="" 4px;="" border-top-right-radius:="" border-bottom-right-radius:="" border-bottom-left-radius:="" background-color:="" rgb(251,="" 250,="" 248);="" border:="" 1px="" solid="" rgba(0,="" 0,="" 0.14902);="" background-position:="" initial="" initial;="" background-repeat:="" initial;-en-codeblock:true;"=""><div><font style="font-size: 14px;"><span style="line-height: normal; font-family: Monaco; font-variant-ligatures: no-common-ligatures; color: rgb(54, 86, 138);">func</span><span style="line-height: normal; font-family: Monaco; font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);"> doThis(thing: </span><span style="line-height: normal; font-family: Monaco; font-variant-ligatures: no-common-ligatures; color: rgb(195, 89, 0);">AnyObject</span><span style="line-height: normal; font-family: Monaco; font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);">) {</span><span style="color: rgb(0, 0, 0); font-family: Monaco;">}</span></font></div>
<div><font style="font-size: 14px;"><br></font></div>
<div><font style="font-size: 14px;"><span style="font-variant-caps: normal; line-height: normal; font-family: Monaco; font-variant-ligatures: no-common-ligatures; color: rgb(54, 86, 138);">func</span><span style="font-variant-caps: normal; line-height: normal; font-family: Monaco; font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);"> doThisThing(thing thing: </span><span style="font-variant-caps: normal; line-height: normal; font-family: Monaco; font-variant-ligatures: no-common-ligatures; color: rgb(195, 89, 0);">AnyObject</span><span style="font-variant-caps: normal; line-height: normal; font-family: Monaco; font-variant-ligatures: no-common-ligatures; color: rgb(0, 0, 0);">) {</span><span style="color: rgb(0, 0, 0); font-family: Monaco;">}</span></font></div></div>

From the W3C page on Attributes:
CSS 2.1 allows authors to specify rules that match elements which have certain attributes defined in the source document.
Attributes are the things defined from the HTML code itself, like id, class, src, href, etc.:
<a id="foo" href="bar">Foo</a>
Unless you specifically defined the style from within a style attribute, like this:
<div style="background-image: url('img/someimg.jpg');">Foo</div>
You can't do anything with CSS.
If you did do it inline, you could try this selector:
div[style="background-image: url('img/someimg.jpg');"]
{
/* ... */
}
Now that you're worried about performance, you can try using pure-JS to do this (untested):
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++)
{
var current = divs[i];
if (current.style.backgroundImage == "url('img/someimg.jpg')")
{
current.style.opacity = 0.5; // You'll need more hacks for IE...
}
}

I'd suggest manipulating CSS classes rather than individual styles in this case. For example:
div.some-img
{
background-image: url('img/someimg.jpg');
}
div.some-img-fade
{
opacity: 5;
}
......
$('div.some-img').each(function() { $(this).addClass('some-img-fade'); });

There's something called DOMSubtreeModified which has now been turned into MutationObserver. This can help you watch the dom for when new elements are added:
// identify an element to observe
var elementToObserve = document.querySelector("#targetElementId");
// create a new instance of `MutationObserver` named `observer`,
// passing it a callback function
var observer = new MutationObserver(function() {
console.log('callback that runs when observer is triggered');
});
// call `observe` on that MutationObserver instance,
// passing it the element to observe, and the options object
observer.observe(elementToObserve, {subtree: true, childList: true});
This example is copy/pasted from mdn docs: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe

Related

styling error when added styles using ngClass

When I only use class name like error and info the css works
Example: https://stackblitz.com/edit/github-i4uqtt-zrz3jb (using Angular latest version)
but when I renamed the css class and add more styles like for the example below the css and [ngClass] no longer work. Any idea guys ?
#HTML
<div fxLayout="row" fxLayoutAlign="space-between">
<div fxLayout="column" fxFlex="0 0 7%">
<mat-icon
[ngClass]="password.hasError('mininum') ? 'error-check-outline' : 'info-check-outline'">
check_circle_outline </mat-icon>
</div>
<div fxLayout="column" fxFlex="0 0 100%">
<span
[ngClass]="password.hasError('mininum') ? 'text-info-error' : 'text-info'">
8 characters mininum</span>
</div>
</div>
#ts
validateMinimumPassword: ValidatorFn = (control: AbstractControl) => {
if (control.value.length < 8) {
return { minimum: true };
}
return null;
};
#CSS
.text-info {
font-family: Inter;
font-style: normal;
font-weight: normal;
font-size: 14px;
color: #4caf50;
font-family: Manrope;
margin-top: 2.5px;
}
.text-info-error {
font-family: Inter;
font-style: normal;
font-weight: normal;
font-size: 14px;
color: #DDD;
font-family: Manrope;
margin-top: 2.5px;
}
.error-check-outline {
transform: scale(.74);
color: #DDD;
}
.info-check-outline {
transform: scale(.74);
color: #4caf50;
}
You have to wrap your ngClass condition in {} also change syntax
For Example:
[ngClass]="{'error-check-outline': password.hasError('minimum'), 'info-check-outline' : !password.hasError('minimum'
)}"
Everything should work, if you correct your typo mininum. Its minimum.
Working example: https://stackblitz.com/edit/so-68358839
Update: Why its green
You have the expression "password.hasError('mininum') ? 'text-info-error' : 'text-info'"
The ternary(conditional) operator syntax is like,
condition ? exprIfTrue : exprIfFalse
You gave password.hasError('mininum') and as it has a typo it returns null, which is falsey. So now the expression on the left is false,
and the .text-info will get selected. As that style makes the color green, it will become green.
you can write a method to return class based on condition
setClass(type) {
if (type == 'minimum') {
return 'class-one';
} else if (type == 'maxmimum') {
return 'class-two';
}
}
and then use this method in HTML like below
<div [ngClass]="setClass('minimum')"><div>
using this way you can clean your HTML

Custom fonts with L.divIcon Leaflet not showing

Using the icomoon internet service to create custom icon-fonts, having trouble to make them visible on Leaflet map. Somehow I can not fetch the icons, what have I missed!? I have the data on the map as I can open up the popup, the problem is there is no icons visible....
I have the fonts folder in the correct place and stylesheet is loaded
This is part of the CSS from icomoon I have in a custom-style.css
#font-face {
font-family: 'icomoon';
src: url('myplace/customer/fonts/icomoon.eot?bf4cat');
src: url('myplace/customer/fonts/icomoon.eot?bf4cat#iefix') format('embedded-opentype'),
url('myplace/customer/fonts/icomoon.ttf?bf4cat') format('truetype'),
url('myplace/customer/fonts/icomoon.woff?bf4cat') format('woff'),
url('myplace/customer/fonts/icomoon.svg?bf4cat#icomoon') format('svg');
font-weight: normal;
font-style: normal;
font-display: block;
}
[class^="icon-"], [class*=" icon-"] {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'icomoon' !important;
speak: never;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-bb .path1:before {
content: "\e900";
color: rgb(35, 31, 32);
}
.icon-bb .path2:before {
content: "\e901";
margin-left: -1em;
color: rgb(0, 0, 0);
}
.icon-bb .path3:before {
content: "\e902";
margin-left: -1em;
color: rgb(0, 0, 0);
} etc....
Then I created a function to look for customer name and give them a className
function getCustomer(x){
x === 'customerBB' ? 'icon- icon-bb' :
x === 'customerCA' ? 'icon- icon-ca' :
x === 'customerCE' ? 'icon- icon-ce' :
'leaflet-div-icon'; //default blue icon if no match
Then a function to return className depending on the results found in feature.properties.customer_name
var setDivIcon = function(feature){
return {
className: getCustomer(feature.properties.customer_name)
};
}
var customerIcon = L.divIcon(setDivIcon);
Later on I use the pointToLayer to add the GeoJSON to the map
customerLayer = L.geoJson(json, {
pointToLayer: function(feature, latlng) {
var time = feature.properties.timeMean_numb;
var point
if (time < 0.167){
point = L.marker(latlng, {icon: L.divIcon(setDivIcon(feature)) }).addTo(time_1);
}
else if (time >= 0.167 && time <= 0.334){
point = L.marker(latlng, {icon: L.divIcon(setDivIcon(feature)) }).addTo(time_2);
}
In your fontface rule you are missing some src:? This could explain them not being fetched

Styling element in shadow dom

I have two custom elements
<desktop-canvas id="desktop">
#shadow-root (open)
<desktop-window>
</desktop-window>
<desktop-canvas>
I'm trying to style <desktop-window> like so:
#desktop::shadow desktop-window {
background-color: red;
padding: 25px;
margin: 25px;
display: block;
}
But desktop-window dosen't receive the style. What am I doing wrong? The same syntax seems to be working in this codepen (not by me): https://codepen.io/matt-west/pen/FtmBL
As announced here...
Starting in Chrome 63, you cannot use the shadow-piercing selectors ::shadow and /deep/ to style content inside of a shadow root.
According to that page you are only affected if you use Shadow DOM v0 components. You either use the shady DOM polyfill, switch to Shadow DOM v1 components or place the styles inside the component and use :host:
var XProductProto = Object.create(HTMLElement.prototype);
XProductProto.createdCallback = function() {
var shadow = this.createShadowRoot();
var img = document.createElement('img');
img.alt = this.getAttribute('data-name');
img.src = this.getAttribute('data-img');
img.width = '150';
img.height = '150';
img.className = 'product-img';
shadow.appendChild(img);
img.addEventListener('click', function(e) {
window.location = this.getAttribute('data-url');
});
var link = document.createElement('a');
link.innerText = this.getAttribute('data-name');
link.href = this.getAttribute('data-url');
link.className = 'product-name';
shadow.appendChild(link);
var styleEl = document.createElement('style');
styleEl.innerHTML = `
:host .product-img {
cursor: pointer;
background: #FFF;
margin: 0.5em;
}
:host .product-name {
display: block;
text-align: center;
text-decoration: none;
color: #08C;
border-top: 1px solid #EEE;
font-weight: bold;
padding: 0.75em 0;
}`;
shadow.appendChild(styleEl);
};
var XProduct = document.registerElement('x-product', {
prototype: XProductProto
});
body {
background: #F7F7F7;
}
x-product {
display: inline-block;
float: left;
margin: 0.5em;
border-radius: 3px;
background: #FFF;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
font-family: Helvetica, arial, sans-serif;
-webkit-font-smoothing: antialiased;
}
<x-product data-name="Ruby" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/ruby.png" data-url="http://example.com/1"></x-product>
<x-product data-name="JavaScript" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/javascript.png" data-url="http://example.com/2"></x-product>
<x-product data-name="Python" data-img="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4621/python.png" data-url="http://example.com/3"></x-product>
CSS Scoping Module Level 1 provides an answer to: Why is the shadow host so weird?:
The shadow host lives outside the shadow tree, and its markup is in control of the page author, not the component author.
It would not be very good if a component used a particular class name internally in a shadow tree stylesheet, and the page author using the component accidentally also used the the same class name and put it on the shadow host. Such a situation would result in accidental styling that is impossible for the component author to predict, and confusing for the page author to debug.

SCSS override variable in nested class [duplicate]

I'd like to know if it's possible to define a variable in Sass depending on if a class is set or not. I need to do some font type tests and would like to change the font-variable $basicFont dynamically based on the body class.
E.g.:
$basicFont: Arial, Helvetica, sans-serif;
body {
&.verdana {
$basicFont: Verdana, sans-serif;
}
&.tahoma {
$basicFont: Tahoma, sans-serif;
}
}
Is there a possibility to handle this in Sass?
No. What you're asking for would require Sass to have knowledge of the DOM. Sass only compiles directly to CSS, it is never sent to the browser.
With your sample code, all you're doing is overwriting $basicFont every time. In version 3.4 or later, your variable will only exist within the scope of the block where it was set.
So, your only real options are to make use of mixins or extends.
Extend
This is effective, but is only suitable for very simple cases.
%font-family {
&.one {
font-family: Verdana, sans-serif;
}
&.two {
font-family: Tahoma, sans-serif;
}
}
.foo {
#extend %font-family;
}
Output:
.one.foo {
font-family: Verdana, sans-serif;
}
.two.foo {
font-family: Tahoma, sans-serif;
}
Mixin
This is the method I would recommend if you want a little more fine grained control over which variables are used where.
$global-themes:
( '.one': ('font-family': (Verdana, sans-serif), 'color': red)
, '.two': ('font-family': (Tahoma, sans-serif), 'color': blue)
);
$current-theme: null; // don't touch, this is only used by the themer mixin
#mixin themer($themes: $global-themes) {
#each $selector, $theme in $themes {
$current-theme: $theme !global;
&#{$selector} {
#content;
}
}
}
#function theme-value($property, $theme: $current-theme) {
#return map-get($theme, $property);
}
.foo {
#include themer {
font-family: theme-value('font-family');
a {
color: theme-value('color');
}
}
}
Output:
.foo.one {
font-family: Verdana, sans-serif;
}
.foo.one a {
color: red;
}
.foo.two {
font-family: Tahoma, sans-serif;
}
.foo.two a {
color: blue;
}

Flex 4 MX AdvancedDataGrid embedded font in header reverting to Times for only some users

I have a Flex 4.5 Application. We are using Spark DataGrids for the majority of our tables. However, there are a couple of instances where we need to use the MX AdvancedDataGrid as we need to do multi-sort and have locked columns.
The problem is the fonts show up perfectly fine within the Spark DataGrid headers. Within the MX AdvancedDataGrid headers (and only in the headers, the data shows the font perfectly fine), the font reverts to Times. However this does not happen for all users. Most of our developers see the font fine, but some of our users see the Times font within the MX ADGs. I am at a loss for what I am missing.
I am using an embedded font in the application, embedded both for CFF and non CFF (with all variations included such as italic and light):
#font-face {
src: url("assets/fonts/SourceSansPro-Regular.ttf");
fontFamily: SSP;
fontStyle: normal;
fontWeight: normal;
embedAsCFF: true;
}
/* embed non CFF fonts for MX controls */
#font-face {
src: url("assets/fonts/SourceSansPro-Regular.ttf");
fontFamily: SSPNoCFF;
fontStyle: normal;
fontWeight: normal;
embedAsCFF: false;
}
I have set styles up for both spark DataGrid and mx AdvancedDataGrid:
mx|AdvancedDataGrid,
.standardDataGrid,
mx|DataGrid {
alternating-item-colors: #ffffff, #f6f6f6;
border-visible: false;
headerColors: #e6e6e6, #e6e6e6;
headerStyleName: standardDataGridHeader;
headerSeparatorColor: #d0d0d0;
headerSeparatorAlpha: 1;
horizontal-grid-lines: true;
horizontal-grid-line-color: #d0d0d0;
selection-color: #c2e5f2;
roll-over-color: #d4ebf3;
vertical-grid-lines: true;
vertical-grid-line-color: #d0d0d0;
user-roll-over: false;
text-align: left;
header-background-skin: ClassReference("org.pcpgm.gis.flex.skins.DataGridHeaderBackgroundSkin");
header-separator-skin: ClassReference("org.pcpgm.gis.flex.skins.DataGridHeaderSeparatorSkin");
vertical-separator-skin: ClassReference("org.pcpgm.gis.flex.skins.DataGridVerticalSeparatorSkin");
vertical-locked-separator-skin: ClassReference("org.pcpgm.gis.flex.skins.DataGridVerticalLockedSeparatorSkin");
}
s|DataGrid {
alternating-row-colors: #ffffff, #f6f6f6;
selection-color: #c2e5f2;
roll-over-color: #d4ebf3;
skinClass: ClassReference("org.pcpgm.gis.flex.skins.GIDataGridSkin");
}
skins|GIDataGridSkin {
border-visible: false;
}
grid|DefaultGridHeaderRenderer {
vertical-align: middle;
padding-top: 0px;
padding-right: 5px;
padding-bottom: 0px;
padding-left: 5px;
color: #4f4f4f;
text-align: left;
roll-over-color: #e6e6e6;
}
grid|DefaultGridHeaderRenderer #labelDisplay {
fontFamily: SSPLight;
font-size: 14pt;
}
And I have set the item renderers for spark and mx components separately to allow for nonCFF versions of the fonts.
mx|Alert,
mx|DataGrid,
mx|Menu,
mx|DateChooser,
mx|Panel,
mx|TabNavigator {
fontFamily: SSPNoCFF;
defaultDataGridItemEditor: ClassReference("mx.controls.MXFTETextInput");
defaultDataGridItemRenderer: ClassReference("mx.controls.dataGridClasses.FTEDataGridItemRenderer");
}
mx|AdvancedDataGrid,
controls|SearchSortedAdvancedDataGrid{
fontFamily: SSPNoCFF;
defaultDataGridItemEditor: ClassReference("mx.controls.MXFTETextInput");
defaultDataGridItemRenderer: ClassReference("mx.controls.advancedDataGridClasses.FTEAdvancedDataGridItemRenderer");
}
Any help is greatly appreciated,
GD

Resources