is this a legitimate use of * selector, and if so are there references to how browsers support this? it seems to work in all browsers I have test, but I haven't used older ones or IE
body * {
float: left;
}
Yes it is, but you should avoid the use of it. You can make it more clear. But if you really want all elements to float left it is a good way to do it. But why do you want this?
All browsers support this, source: http://www.quirksmode.org/css/contents.html#t10
Yes it is! The asterisk is a wildcard, it will select all elements within that DOM element you set it to.
For example, if I you want to apply an attribute to your whole site:
* {
attribute: value;
}
Or as you did it with a special DOM element!
element * {
attribute: value;
}
You could also use something like:
* {
attribute: value;
}
* * { ... }
* * * { ... }
* div * { ... }
Which is a bit difficult... like a recursion.
Yes, your example is a legitimate, if not heavy-handed use of the * selector. This will cause every child element of the body element to be floated left.
Related
this is my first question here, so please be patient if I am doing something wrong :)
I have some weird problem and I still haven't found a solution, even though I've spent a few hours searching on Google.
So I have a CSS custom property called --vh that I set up dynamically with JavaScript.
In order to make life easier and not write all this long syntax with the var every time, I wanted to create the Sass variable called $vh and use it wherever I need it:
$vh: var(--vh, 1vh);
$m-distance: $vh * 2;
$input-height: $m-distance * 1.6;
$sm-distance: $m-distance * 0.5;
$l-distance: $m-distance * 1.6;
$xl-distance: $m-distance * 2;
// And there are dosens of places in my app where I later use these variables...
But when I do that right away in the next line I get an error:
SassError: Undefined operation: "var(--vh, 1vh) times 2".
on line 21 of src/styles/setup/_variables.scss
from line 4 of /home/joisadler/github/fymdaily/client/src/styles/global.scss
>> $m-distance: $vh * 2;
-------------^
And if for example instead of $vh: var(--vh, 1vh); I write just $vh: 1vh;, everything passes successfully. But this is not what I want because I need my vh to be rather dynamic.
I have found lots of explanations for the reverse case when I want to use the Sass variable within the custom property definition. But I need to do the exact opposite and use custom property within the definition of the Sass variable.
Does anyone have any idea how to do such things?
Thanks in advance!
I have now come up with a pretty simple solution on how to do what I wanted, I checked and it really works great.
First of all I defined all my variables as custom properties:
// _base.scss
:root {
// --vh property itself defined dynamically by JavaScript
--m-distance: calc(var(--vh, 1vh) * 2.5);
--input-height: calc(var(--m-distance) * 1.6);
--sm-distance: calc(var(--m-distance) * 0.5);
--l-distance: calc(var(--m-distance) * 1.6);
--xl-distance: calc(var(--m-distance) * 2);
}
And after that I just defined sass variables with the same names:
// _variables.scss
$m-distance: var(--m-distance);
$input-height: var(--input-height);
$sm-distance: var(--sm-distance);
$l-distance: var(--l-distance);
$xl-distance: var(--xl-distance);
And now I enjoy two worlds: also get the --vh property dynamically from JavaScript and can also use Sass variables with shorter and nicer syntax in all the other files in my app.
I've tested the following on https://www.sassmeister.com/ and it seems to work.
Input
:root {
--vh: 10vh;
}
$var: var(--vh, 1vh);
body {
height:$var;
}
Output
:root {
--vh: 10vh;
}
body {
height: var(--vh, 1vh);
}
Have you tried declaring a default value for --vh inside the Sass file so the compiler recognises it and doesn't produce an error?
Yes, but not to calculate with SASS functions
Why assign a SASS variable to the value of a CSS custom property? For calculations (as in your question) and useful built-in functions like color.scale(). You won't be able to use these tools with values derived from CSS custom properties.
#use "sass:color";
:root {
--basic_color: #FF0000; // Red
}
$sassy_color: var(--basic_color, #00FF00); // Red with green fallback
$pure_color: #FF0000; // Red
body {
background-color: $sassy_color; // ✅ Red background
color: color.scale($pure_color, $lightness: +90%); // ✅ Red text, or
color: color.scale($sassy_color, $lightness: +90%); // 👎 Error: not a color
}
As Josh Bonnick shows, you can put a CSS custom property insertion statement into a SASS variable, as in background-color: $sassy-color, but that's not very useful; it might as well be a custom property insertion. Unfortunately, this is only a string, and SASS won't evaluate the var() function call.
Let's say we want to change the lightness of the color, as in color: color.scale(). If our SASS variable uses a color primitive ($pure_color), it works as intended, but if we use a variable that represents an CSS custom property ($sassy_color), it fails, because it can't do math on the string var(--basic_color, #00FF00);.
So why do it? Organization
In a beautiful SASS architecture proposal, Felippe Regazio lays out a method for making CSS custom properties his styling modules using SASS functions as getters and setters. This is essentially all string manipulation, and it shows how useful it can be to access CSS custom properties with SASS variables even if you're not going to use them for calculations.
/**
* Retrieve a css variable value with prefix
*
* Usage
*
* .selector {
* color: get(primary-color);
* }
*
* Will result in
*
* .selector {
* color: var(--prefix-primary-color);
* }
*/
#function get($name, $prefix: pm) {
#return var(--#{$prefix}-#{$name});
}
/**
* Update a css variable value
*
* Instead of
*
* .selector {
* --#{$prefix}-button-height: 56px;
* }
*
* Usage
*
* .selector {
* #include set(button-height, 56px);
* }
*/
#mixin set ($name, $value: '', $prefix: pm) {
--#{$prefix}-#{$name}: #{$value};
}
Read the article for more details.
I'm trying to select input elements of all types except radio and checkbox.
Many people have shown that you can put multiple arguments in :not, but using type doesn't seem to work anyway I try it.
form input:not([type="radio"], [type="checkbox"]) {
/* css here */
}
Any ideas?
Why :not just use two :not:
input:not([type="radio"]):not([type="checkbox"])
Yes, it is intentional
If you're using SASS in your project, I've built this mixin to make it work the way we all want it to:
#mixin not($ignorList...) {
//if only a single value given
#if (length($ignorList) == 1){
//it is probably a list variable so set ignore list to the variable
$ignorList: nth($ignorList,1);
}
//set up an empty $notOutput variable
$notOutput: '';
//for each item in the list
#each $not in $ignorList {
//generate a :not([ignored_item]) segment for each item in the ignore list and put them back to back
$notOutput: $notOutput + ':not(#{$not})';
}
//output the full :not() rule including all ignored items
&#{$notOutput} {
#content;
}
}
it can be used in 2 ways:
Option 1: list the ignored items inline
input {
/*non-ignored styling goes here*/
#include not('[type="radio"]','[type="checkbox"]'){
/*ignored styling goes here*/
}
}
Option 2: list the ignored items in a variable first
$ignoredItems:
'[type="radio"]',
'[type="checkbox"]'
;
input {
/*non-ignored styling goes here*/
#include not($ignoredItems){
/*ignored styling goes here*/
}
}
Outputted CSS for either option
input {
/*non-ignored styling goes here*/
}
input:not([type="radio"]):not([type="checkbox"]) {
/*ignored styling goes here*/
}
Starting from CSS Selectors 4 using multiple arguments in the :not selector becomes possible (see here).
In CSS3, the :not selector only allows 1 selector as an argument. In level 4 selectors, it can take a selector list as an argument.
Example:
/* In this example, all p elements will be red, except for
the first child and the ones with the class special. */
p:not(:first-child, .special) {
color: red;
}
Unfortunately, browser support is somewhat new.
I was having some trouble with this, and the "X:not():not()" method wasn't working for me.
I ended up resorting to this strategy:
INPUT {
/* styles */
}
INPUT[type="radio"], INPUT[type="checkbox"] {
/* styles that reset previous styles */
}
It's not nearly as fun, but it worked for me when :not() was being pugnacious. It's not ideal, but it's solid.
If you install the "cssnext" Post CSS plugin, then you can safely start using the syntax that you want to use right now.
Using cssnext will turn this:
input:not([type="radio"], [type="checkbox"]) {
/* css here */
}
Into this:
input:not([type="radio"]):not([type="checkbox"]) {
/* css here */
}
https://cssnext.github.io/features/#not-pseudo-class
I know you can select the elements if the attribute exists
[data-value] { /* rules */ }
Or that its values starts with some val
[data-value^="foo"] { /* rules */ }
But, can I check if any elements contain contains a prefixed attribute?
[^data-] { /* something like it? /*}
This question came when I was trying to query all attributes of the page that has a prefixed aria atrittube. eg. aria-hidden, aria-live...
Unfortunately it is not possible to do what you want with just CSS selectors, you would have to specify each attribute that you want to include. For example:
[aria-hidden], [aria-live]
{
}
It would be possible however to do something with javascript, so you may want to look into that if it's an option for you.
ok I know how to do both these things separately:
#elemID { } /* selects only one element */
#elemID * { } /* selects all its children elements but not the element itself */
And I know I can do it like this:
#elemID, #elemID * { }
But is there a way to avoid this repeating ?
No, there is nothing shorter than that.
Note that if you really only want all the children of #elemID, and not all the descendants, you need to use the child combinator:
#elemID, #elemID > *
And as Šime Vidas has commented, some properties like color are automatically inherited by descendant elements by default. If you're trying to give text color to #elemID, you should not need to apply it explicitly and recursively to the elements inside it. See the SitePoint Reference on inheritance in CSS for details.
No. But you could select its parent if an equivalent selector exists:
.parent * { ... }
I'm trying to select input elements of all types except radio and checkbox.
Many people have shown that you can put multiple arguments in :not, but using type doesn't seem to work anyway I try it.
form input:not([type="radio"], [type="checkbox"]) {
/* css here */
}
Any ideas?
Why :not just use two :not:
input:not([type="radio"]):not([type="checkbox"])
Yes, it is intentional
If you're using SASS in your project, I've built this mixin to make it work the way we all want it to:
#mixin not($ignorList...) {
//if only a single value given
#if (length($ignorList) == 1){
//it is probably a list variable so set ignore list to the variable
$ignorList: nth($ignorList,1);
}
//set up an empty $notOutput variable
$notOutput: '';
//for each item in the list
#each $not in $ignorList {
//generate a :not([ignored_item]) segment for each item in the ignore list and put them back to back
$notOutput: $notOutput + ':not(#{$not})';
}
//output the full :not() rule including all ignored items
&#{$notOutput} {
#content;
}
}
it can be used in 2 ways:
Option 1: list the ignored items inline
input {
/*non-ignored styling goes here*/
#include not('[type="radio"]','[type="checkbox"]'){
/*ignored styling goes here*/
}
}
Option 2: list the ignored items in a variable first
$ignoredItems:
'[type="radio"]',
'[type="checkbox"]'
;
input {
/*non-ignored styling goes here*/
#include not($ignoredItems){
/*ignored styling goes here*/
}
}
Outputted CSS for either option
input {
/*non-ignored styling goes here*/
}
input:not([type="radio"]):not([type="checkbox"]) {
/*ignored styling goes here*/
}
Starting from CSS Selectors 4 using multiple arguments in the :not selector becomes possible (see here).
In CSS3, the :not selector only allows 1 selector as an argument. In level 4 selectors, it can take a selector list as an argument.
Example:
/* In this example, all p elements will be red, except for
the first child and the ones with the class special. */
p:not(:first-child, .special) {
color: red;
}
Unfortunately, browser support is somewhat new.
I was having some trouble with this, and the "X:not():not()" method wasn't working for me.
I ended up resorting to this strategy:
INPUT {
/* styles */
}
INPUT[type="radio"], INPUT[type="checkbox"] {
/* styles that reset previous styles */
}
It's not nearly as fun, but it worked for me when :not() was being pugnacious. It's not ideal, but it's solid.
If you install the "cssnext" Post CSS plugin, then you can safely start using the syntax that you want to use right now.
Using cssnext will turn this:
input:not([type="radio"], [type="checkbox"]) {
/* css here */
}
Into this:
input:not([type="radio"]):not([type="checkbox"]) {
/* css here */
}
https://cssnext.github.io/features/#not-pseudo-class