Access body lang in SCSS in Angular 6 - css

I am using #ngx/translate core for lang change.
I want to define sass on the basic of
<body lang="en">
or
<body lang="fr">
by if else condition.
Inside my component sass i want to do something like this
#if( bodylang = en)
/these rules
else
// these rules
How can i achieve this?

As it is SCSS you are able to use CSS attribute selectors for this, for example:
a[target="_blank"] {
background-color: yellow;
}
Which in your case would be:
body[lang="en"] {
// Your code
}
body[lang="fr"] {
// Your code
}
You can also nest them like such:
body {
background-color: orange;
&[lang="en"] {
background-color: blue;
}
}
This selector is more specific than just referring to the body tag itself. This means that it will apply the regular body CSS if none of the matching langcode tags are found. You can find more attribute selectors here: https://www.w3schools.com/css/css_attribute_selectors.asp

If you want to do it in your component SCSS file you have to do something like bellow code:
:host-context([lang="en"]){
// Your code
}
:host-context([lang="fa"]){
// Your code
}
If you are doing it in your styles.scss file you can achieve your goal with following code:
[lang="en"] {
// Your code
}
[lang="fr"] {
// Your code
}

rsangin's answer is the correct one.
If you want to select every language that is not en, you can just use :not([lang="en"])

Related

How to handle/use path images with css variables? Angular

I receive a configuration JSON that has colors and the paths of the images that I must use in my CSS, I correctly set the variables in the html and it would have a result similar to this:
<html lang="en" style="
--c-logo-square:https://linkener-design-tokens.s3.eu-west-1.amazonaws.com/localhost/temp%20belike%20small.png;
--c-background-image:https://linkener-design-tokens.s3.eu-west-1.amazonaws.com/localhost/mainBg.png;
--c-primary:green;
--c-secondary:purple;">
I can use the color variables correctly, but I don't know how to use the image paths as background.
// Works
.my-html-component {
color: var(--c-primary);
}
// Error
logo {
background: url(var(--c-background-image));
}
When working with Angular and SCSS I understand that I could use some function that allows me to do what I need, but I don't know how to do it.
Instead of defining url in the attribute, define it as a part of the variable. Dont forget to add :root.
:root {
--c-background-image:url(https://linkener-design-tokens.s3.eu-west-1.amazonaws.com/localhost/mainBg.png);
}
.logo {
background: var(--c-background-image);
width:500px;
height:500px;
}
<div class="logo"></div>

extend from class name in another file sass

So I'm currently doing some styling, following the BEM standard.
An example of what I'm doing could be this:
.block{
&__element {
}
}
what i would like to do is this:
// file a
.block {
...
}
-
// file b
// add magic to reference the `block`class in file a
&__elelemnt {
...
}
What I'm currently doing:
// file a
.block {
...
}
-
// file b
.block__elelemnt {
...
}
(manually adding the block part to the name)
Is there any way to reference this in a smarter way?
Thanks in advance
You can have this file structure:
block-1/
--block-1.scss
--element-1.scss
--element-2.scss
block-2/
--block-1.scss
--element-1.scss
--element-2.scss
And import elements files info block files.
block.scss:
.block {
color: red;
#import "element-1.scss";
#import "element-2.scss";
}
element-1.scss:
&__element-1 {
color: green;
}
Compiles to:
.block {
color: red;
&__element-1 {
color: green;
}
}
This is perhaps the best you can do.
$namespace: "block";
.#{$namespace}-myClass {
...
}
OUTPUT
.block-myClass {
...
}
You can keep a variable $namespace at the top of your file or in a different file and import it. The advantage of using a variable is you can update it once and all your references will be updated.
SASS is all about DRY.
As in, if you want to modify anything, you should be able to modify it from one single place. If you need anything available across multiple files, consider defining its value in a _vars file and including it everywhere you need it. Also note this has nothing to do with code shortness, but with code maintainability and flexibility.
In fact, even if you do get to write more code (which, in practice, doesn't happen), the advantage of DRY far outweighs it.
Here's how it should be done:
/* _vars.scss: */
$block:block;
/* a.scss: */
#import _vars;
.#{$block} {
...
}
/* b.scss: */
#import _vars;
.#{$block}__element {
...
}
Now, whenever you need to change block value, you can do it from one place: _vars.scss.
But, in practice, most people use the initial technique (nesting):
.block {
...
&__element {
...
}
}
Chances are .block and .block__element are related and, overall, it makes more sense to put them in same file. As your app grows in complexity, you'll find it harder to keep track of your code if you over-complicate it.

Is there a CSS selector that applies when matching specific values in the URL?

Is there a selector that specifies CSS to only applied when matching a specific URL or part of URL?
For example, here is my CSS stylesheet:
p {
color: green;
}
url("home.html") {
color: blue;
}
url("about.html") {
color: yellow;
}
path("/path/index*") {
color: indigo;
}
When the user visits home.html I want the home.html selector to be applied. When I'm on the about.html URL I want the about.html to be applied.
CSS media queries allow you to switch to a different set of styles when the width of the view changes. It also lets you specify a different set of styles when the user is going to view on the screen or send it to a printer.
My question again is, "Is it possible to specify a different set of styles depending on the URL or values in the URL." So it's not a question of how to do what I'm asking but if it's possible to.
I am using a CMS and it has a theme that allows you to add your own CSS. There is one stylesheet. That's it. Not two but one.
And I have one page that has specific CSS to that page and only that page. That is the origin of this question. There may be a thousand workarounds but my question is not about the workarounds.
However since this has been answered I do not mind workaround answers related to the question.
It looks like the #document rule was proposed for just this case but it was removed from CSS3 spec and planned for CSS4. From my tests it does not appear to be supported and it's not listed on caniuse at the time of this posting.
The syntax is as follows:
#document url("http://www.example.com/widgets/") {
body {
color: white;
background: tomato;
}
}
/* The above applies styles only to the page at the given URL */
#document url-prefix("http://www.example.com/widgets/") {
/*
Styles written here are applied to all URLs that
begin with 'http://www.example.com/widgets/'
*/
}
#document regexp("https:.*") {
/* Styles written here are applied to all URLs that begin with 'https:' */
}
Test code using #media query for comparison:
var styleTag = document.createElement ("style");
document.head.appendChild (styleTag);
var sheet = styleTag.sheet;
sheet.insertRule ("#media (min-width:600px) { html {color:red}}", 0);
console.log(document.styleSheets.length);
Results:
// no errors, stylesheet is added
Test code testing #document rule:
var styleTag = document.createElement ("style");
document.head.appendChild (styleTag);
var sheet = styleTag.sheet;
sheet.insertRule ("#document url('http://www.google.com') { html {color:red}}", 0);
Results:
/*
Exception: SyntaxError: An invalid or illegal string was specified
#Scratchpad/3:4:0
*/
TIL about #document thanks to #BoltClock
More info
You could attach a data-url custom attribute to an element's parent tag, either in the HTML or using JavaScript, and then query that data's value in CSS. Here's a working example:
const urlHolder = document.getElementById("url-holder");
document.getElementById("changer").onclick = () => {
urlHolder.dataset.url = "https://mywebsite.com/about"
};
#url-holder[data-url*="blog"] .url-based{
background-color: red;
}
#url-holder[data-url*="blog"] .url-based::after{
content: "You're on the blog page!"
}
.url-based::after{
content: "You're not on the blog page."
}
.box{
width: 200px;
height: 200px;
border: 2px solid black;
margin: 5px;
}
<button id="changer" type="button">Change data-url to "https://mywebsite.com/about"</button>
<div id="url-holder" data-url="https://mywebsite.com/blog">
<div class="box url-based"></div>
<div class="box not-url-based"></div>
</div>
No idea how performant such a solution would be though.
To be sad there is no pseudo classes to select element's based on URL.The only way you can do it is by adding class to the body tag or specific element and then override the CSS.
if just for only HTML, use jQuery
<script>
var currentLocation = window.location.pathname;
if (currentLocation == 'home.html'){
$('head').append('<link href="home-style.css" rel="stylesheet">');
} else if (currentLocation == 'about.html'){
$('head').append('<link href="about-style.css" rel="stylesheet">');
} else {
$('head').append('<link href="index-style.css" rel="stylesheet">');
}
</script>
If use you WordPress:
Add your theme function.php
function site_stil_script() {
if ($_SERVER['REQUEST_URI']=='/YOURPAGE/') {
wp_enqueue_style( 'theme_css', get_template_directory_uri() . '/assets/css/theme-difrent-style.css', array(), '20120208', 'all' );
} else {
wp_enqueue_style( 'theme_css', get_template_directory_uri() . '/assets/css/theme-style.css', array(), '20120208', 'all' );
}
//other lines....
}
add_action( 'wp_enqueue_scripts', 'site_stil_script' );

Is possible to make an important property value from CSS selector a non important one?

Is possible to make an important property value from CSS selector a non important one?
For example: Bootstrap 3 defines .hide class as:
.hide { display: none !important; }
Is possible to remove the important value without modifying the BS3 source code?
Thinking at somethingl iike
.hide { display: none !remove-important; }
Note that I want to keep the same value! I don't want to set block !important to .hide class because that would not be correct...
I already added a new class .hide-non-important and used it where it was needed:
.hide-not-important { display: none; }
...but the question is: is there any alternative to this?
You don't need to edit the original source code. Just create a stylesheet and place it after the Bootstrap stylesheets and add this to it:
.hide { display: block !important; }
Now, having said this, I would be very careful about doing this. You don't know how many elements across your site have applied this class, and you will almost certainly get unanticipated results.
There is obviously a reason that this class has been applied, I would suggest either:
don't do this
add some other class to the element and add styles to that. Adjust your markup (or use js to apply the class if need be) to something like:
<div class="hide custom-hide-reset"></div>
Then add this style to the stylesheet you've created:
.custom-hide-reset { display: none; }
You can overwrite this with:
body .hide { display: none !important; }
.someclass.hide { display: none !important; }
those two examples have higher priority
The stylesheet objecs are accessible from javascript
var sheets = document.styleSheets
Once you have the stylesheet array, you can iterate over the rules
var rules = sheets[i].cssRules || sheets[i].rules // browser dependency
Each rule has a style property, which is mutable in the usual way.
rule.style[cssPropName] = value;
There is a method on the sheet to delete a rule by index, either deleteRule or removeRule, depending on the browser.
Bottom line, you can find the rule and either edit it or delete and re-add it in a modified form.
Reference: http://www.javascriptkit.com/dhtmltutors/externalcss3.shtml#.Ujsin4ZmjAs
Since the question can be splitted in
how can I remove !important from a rule applied to my page but
without changing its value and
without editing the original CSS file
For pure spirit of adventure only, I think it would be possible in the following way:
load the CSS with jQuery;
perform a replacement of its content, by searching .hide { display: none !important; } and replacing it with .hide { display: none; };
apply the new in-memory altered CSS to the page.
Taking for good the solution posted in this answer, it could be modified with something (totally untested, just to get the idea) like:
$.get(myStylesLocation, function(css)
{
var alteredCss = css.replace(".hide { display: none !important; }",".hide { display: none; }");
$('<style type="text/css"></style>')
.html(alteredCss)
.appendTo("head");
});
You can override the current !important value by another one like
.col{ color:red !important; }
.col{ color:green; } // wont work
.col{ color:blue !important; } // will work and set color blue instead of red
DEMO.
Update :
This question is not about JavaScript but as an alternative you can accomplish the task using these technique, remove the rule using JavaScript and then add a new rule again.
function getCSSRule(ruleName, deleteFlag) {
ruleName=ruleName.toLowerCase();
if (document.styleSheets) {
for (var i=0; i<document.styleSheets.length; i++) {
var styleSheet=document.styleSheets[i];
var ii=0;
var cssRule=false;
do {
if (styleSheet.cssRules) {
cssRule = styleSheet.cssRules[ii];
} else {
cssRule = styleSheet.rules[ii];
}
if (cssRule) {
if (cssRule.selectorText.toLowerCase()==ruleName) {
if (deleteFlag=='delete') {
if (styleSheet.cssRules) {
styleSheet.deleteRule(ii);
} else {
styleSheet.removeRule(ii);
}
return true;
} else {
return cssRule;
}
}
}
ii++;
} while (cssRule)
}
}
return false;
}
function killCSSRule(ruleName) {
return getCSSRule(ruleName,'delete');
}
function addCSSRule(ruleName, v) {
if (document.styleSheets) {
if (!getCSSRule(ruleName)) {
if (document.styleSheets[0].addRule) {
document.styleSheets[0].addRule(ruleName, v,0);
} else {
document.styleSheets[0].insertRule(ruleName+'{'+v+'}', 0);
}
}
}
return getCSSRule(ruleName);
}
// Check the rule before deleting
console.log(getCSSRule('.col')); // .col { color:red !important; }
// At first remove the current rule
killCSSRule('.col');
// Now assign nre rule
addCSSRule('.col', 'color: red');
// Check the rule after deleting
console.log(getCSSRule('.col')); // .col { color:red; }
DEMO. ( Source : Totally Pwn CSS with Javascript )

Declare a global CSS property ? Is this possible?

I have a very wierd question, I dont know wether if its possible in css or not
Suppose I have say 3 different css classes as shown below, as you can see I have a common property of all these classes, I want to declare this color somewhere else and pass a reference to it here, so if next time I want to change the color I can simply change at one place rather than changing in all the 5 classes.
I know that you can use body{}, or a wrapper for this but that would affect the colors of the entire site right ? Is there a way to do this ?
Is this even possible ?
.abc {
color:red;
}
.abc2 {
color:red;
}
.abc3 {
color:red;
}
.abc4 {
color:red;
}
.abc5 {
color:red;
}
The bad news: you can't do it in CSS.
The good news: you can write in a meta-CSS language like LESS, which then processes a LESS file to pure CSS. This is called a "mixin".
In LESS:
#errorColor: red;
.error-color {
color: #errorColor;
}
#error-1 {
.error-color;
}
.all-errors {
.error-color;
}
More info: http://lesscss.org/#-mixins
if you want to declare all of them at a time, you can use:
.abc, .abc2, .abc3, .abc4, .abc5 {
color:red;
}
Or you can declare an additional class & add to all the .abc, .abc2.... & make its color:red;.
This can not be done with CSS, but that is still a very popular thing to do by using a CSS preprocessor such as LESS, SASS, SCSS, or Stylus.
A preprocessor will let you define a variable (say $red = #F00). It will replace the variable in your CSS document with the variable value for you, allowing you to write very DRY and module CSS.
This functionality is referred to as "CSS variables", which is part of the future spec, but not yet implemented on any browsers.
For now, the best way to do this in pure CSS is to declare an additional class for the desired "global", and then add that class to all relevant items.
.abc_global { color: red; }
.abc1 { /* additional styling */ }
.abc2 { /* additional styling */ }
<div class="abc1 abc_global"></div>
<div class="abc2 abc_global"></div>
With LESS
You are able to define that red color once:
.myRedColor {
color:red;
}
Now you can call that red on any CSS styles. Even NESTED styles! It's a wicked tool!
.abc1 {
.myRedColor;
}
.abc2 {
.myRedColor;
}
.abc3 {
.myRedColor;
}
.abc4 {
.myRedColor;
}
NESTED EXAMPLE:
.abc {
.itsEasyAsOneTwoThree{
.myRedColor;
}
}
Now all of our "itsEasyAsOneTwoThree" classes that are properly nested inside of an "abc" class will be assigned the red style. No more remembering those long #867530 color codes :) How cool is that?!
You can also use PostCSS with the plugin postcss-preset-env and support custom properties/variables, then use the :root selector to add global css variables.
:root {
--color-gray: #333333;
--color-white: #ffffff;
--color-black: #000000;
}

Resources