Is is possible to use the parent selector in LESS to specify a value for a parent attribute selector?
I want the following output:
[some-attribute] {
font-weight: normal;
}
[some-attribute~="bold"] {
font-weight: bold;
}
Given this (obviously incorrect) example:
[some-attribute] {
font-weight: normal;
&~="bold" {
font-weight: bold;
}
}
Is something like this possible in LESS?
EDIT: For anyone who might be curious, I did try this abomination:
[some-attribute {
&] {
font-weight: normal;
}
&~="bold"] {
font-weight: bold;
}
}
I'm kind of glad it didn't work. I might have been tempted.
Disclaimer: This is strictly how not to over-complicate things but yeah it is still possible in a way using selector interpolation and mixins.
You could write a mixin like below which makes use of the attribute name as one input parameter and the condition as another. The condition is an optional parameter and when it is not provided, the mixin considers it as only a attribute presence selector.
The rules that have to be attached are also passed as input.
.mixin-attrib-selector(#attr-name, #rule, #param:null){
#sel-start: ~"[";
#sel-end: ~"]";
#{sel-start}#{attr-name}{
& when(#param = null){
&#{sel-end}{
#rule();
}
}
& when not (#param = null){
&#{param}#{sel-end}{
#rule();
}
}
}
}
.mixin-attrib-selector(some-attribute, {
font-weight: normal;
});
.mixin-attrib-selector(some-attribute,{
font-weight: bold;
}, ~"~='bold'");
#output{
.mixin-attrib-selector(some-attr, {
font-weight: normal;
});
.mixin-attrib-selector(some-attr,{
font-weight: italic;
}, ~"~='italic'");
}
The parent selector (&) only holds a reference to an entire complex selector, with the option to extend the selector provided that you use the entire thing as a base:
.one > .two {
&::after, &::before {
// Compiles to .one > .two::after, .one > .two::before
}
& + .three {
// Compiles to .one > .two + .three
&-suffix {
// Compiles to .one > .two + .three-suffix
}
}
}
It cannot be used to reference a part of a compound or simple selector, in particular it cannot be used to reference just the attribute name in an attribute selector. You'll have to stick with vanilla CSS.
The reason that abomination doesn't work is because both preprocessors expect all selectors in style rules to be valid; [some-attribute is not a valid selector. You could write a mixin and/or use selector interpolation, but it still has to result in a valid selector when used with a style rule, since the compiler can't assume that you won't be using the selector in its own set of style declarations (though of course, whether a preprocessor should be controlling the author in this way is up for debate...).
No way that I know of. The closest thing you can do is
[some-attribute] {
font-weight: normal;
&[some-attribute~="bold"] {
font-weight: bold;
}
}
which outputs
[some-attribute] {
font-weight: normal;
}
[some-attribute][some-attribute~="bold"] {
font-weight: bold;
}
but you're better off keeping them separate
[some-attribute] {
font-weight: normal;
}
[some-attribute~="bold"] {
font-weight: bold;
}
Related
This question already has answers here:
What does a space mean in a CSS selector? i.e. What is the difference between .classA.classB and .classA .classB? [duplicate]
(3 answers)
Closed last year.
&:hover{
cursor: pointer;
& .background-image {
transform: scale(1.1);`enter code here`
transition: transform 6s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
& .content{
opacity: 0.9;
}
}"
like in & .background-image we have space
&.large{
height: 380px;
}"
but we don't give space here
The & always refers to the parent selector when nesting. Think of the & as being removed and replaced with the parent selector.
If you leave a space after & symbol, this means you are now referring to its' descendants if you don't leave a space, this means you refer to your parent itself.
For example
.container {
&.red {
background-color: red;
}
}
In this case, this will apply red background to the .container element, if it also has a red class attached to it in your DOM.
Example 2
.container {
& .red {
background-color: red;
}
}
In this case, it will make the background to be red-colored to any child, which has a .red class inside a .container element.
More details and complex examples here
I looking for a seating plan generator to add to my site. My seating information needs to come as an object. And I want to render the seating plan according to that. Is it possible to render something like below?
I have tried react seat picker too. but spaces between seats are not taken
the issue was in my CSS file commenting the blank attribute will fix the error.
div.seat {
background-color: green;
}
div.seat--reserved {
background-color: rgb(209, 7, 7);
}
div.seat--selected {
background-color: blue;
}
.seat-picker {
margin: auto;
}
.seat-picker__row {
}
.seat-picker__row__number {
}
/* div.blank {
display: none;
} */
I am using PostCSS http://cssnext.io/ with my Next.js website combined with butterCMS. I am new to postcss but like what they are trying to do, however coming from a SASS background, I am finding it seems to be going down the rabbit hole of having to add a lot of additional modules and scripts in order to get it working which does not give it a major advantage over preprocessors.
In my package.json I have the following modules:
"postcss-cssnext": "^3.0.2",
"postcss-easy-import": "^3.0.0",
"postcss-loader": "^2.0.6",
"postcss-modules": "^0.8.0",
In my root I have a ./styles/ folder with the following files:
defaults.css
:root {
/* Breakpoints */
#custom-media --small (width >= 576px);
#custom-media --medium (width >= 768px);
#custom-media --large (width >= 1200px);
/* Colors */
--color-black: #000;
--color-white: #fff;
--color-vue-green: #42b983;
/* Typography */
--h1: 2rem;
--h2: 1.5rem;
--h3: 1.25rem;
--h4: 1rem;
--h5: 0.875rem;
--h6: 0.75rem;
/* Utilities */
--accessibly-hidden: {
position: absolute !important;
display: block;
visibility: visible;
overflow: hidden;
width: 1px;
height: 1px;
margin: -1px;
border: 0;
padding: 0;
clip: rect(0, 0, 0, 0);
clip-path: polygon(0 0, 0 0, 0 0, 0 0);
}
--foo: {
font-size:4em;
color:green;}
}
styles.css
#import 'defaults.css';
h1, h2, h3, h4, h5, h6 {
font-weight: normal;
}
h1 { font-size: var(--h1) }
h2 { font-size: var(--h2) }
h3 { font-size: var(--h3) }
h4 { font-size: var(--h4) }
h5 { font-size: var(--h5) }
h6 { font-size: var(--h6) }
.accessibly-hidden {
#apply --accessibly-hidden;
}
.giantext{
#apply --foo;
}
div {
color: var(--color-vue-green);
}
.my-paragraph{
composes: my-paragraph from 'shared.css';
}
.danger{
composes: danger from 'shared.css';
}
In my react script I have:
<p className={classNames['my-paragraph']}>My homepage</p>
<p className={classNames.danger}> This background should be yellow</p>
<div>
<p className={classNames.giantext}> I am huge </p>
</div>
Only the composes directives are working with the remaining utilities and styling not being picked up by my index.js file in next.js. The remainder gives me the following warnings/errors:
(Emitted value instead of an instance of Error) postcss-custom-properties: /Users/user/projects/qubase/styles/styles.css:25:3: variable '--color-vue-green' is undefined and used without a fallback
Or
(Emitted value instead of an instance of Error) postcss-apply: /Users/user/projects/qubase/styles.css:16:3: No custom property set declared for `accessibly-hidden`.
etc
Is there anything about postcss I am missing?
Here is what I've done to get rid of those messages:
I added postcss.config.js file and I added following code in it:
const postcssCssNext = require('postcss-cssnext')
const postcssImport = require('postcss-import')
module.exports = {
plugins: [
postcssCssNext({
features: {
customProperties: {
warnings: false
}
}
}),
postcssImport
]
}
I'm going to create a less code that will give different background-color to element depending on it's class. This will be for list of attachments, so class name is based on attachment extension.
I do support some typical extensions:
.label{
&.label-pdf{
background-color: #c70000;
}
&.label-doc, &.label-docx, &.label-odt{
background-color: #157efb;
}
&.label-xls, &.label-xlsx, &.label-calc{
background-color: #069e00;
}
&.label-ppt, &.label-pptx, &.label-odp{
background-color: #9e3c15;
}
&.label-jpg, &.label-png, &.label-gif, &.label-png, &.label-ttf{
background-color: #95009e;
}
}
but the problem is with some unusual extensions, or even files like: jpg, jpeg, doc, docx, this is why I would like to use expression from CSS. In pure CSS I could use:
.label.[class^="label-"]{
background-color: rgba(0,37,100,0.4);
}
And put this code at the beginning so other classes could override this one.
But unfortunately this sign ^ (I suppose) is breaking my Less compilation. I have been trying to do something like this:
~".label.[class^='label-']{
background-color: rgba(0,37,100,0.4);
}"
AND
.label{
&.~"[class^='label-']"{
background-color: rgba(0,37,100,0.4);
}
}
But still not working. So is it possible to use this selector?
It is not working because your syntax seems to be wrong and not because of any issues with Less.
The below code is invalid because of the . present between the label and the class^="label-"]. Attribute selectors do not require a . before them. It is necessary only for class selectors.
.label.[class^="label-"]{
background-color: rgba(0,37,100,0.4);
}
The correct version would be the following:
.label[class^="label-"]{
background-color: rgba(0,37,100,0.4);
}
and so in Less terms, if you want nesting, it would be as follows:
.label{
&[class^='label-']{
background-color: rgba(0,37,100,0.4);
}
}
.label.[class^="label-"] { /* this won't work */
background-color: rgba(0, 37, 100, 0.4);
}
.label[class^="label-"] { /* this will */
color: green;
}
<label class='label-a label'>Label A</label>
<label class='label-b label'>Label B</label>
Another thing to note is that the ^= is a starts with selector and so when your element has more than one class, the class that resembles label- should be the first class in the list and not the label. If we make the label as the first class then (like seen in below snippet) it won't work because then the class doesn't start with label-.
If the first class in the list is indeed label then you should consider using the *= (contains) selector. But be careful when using the contains selector because it will sometimes select unintended elements like those with class label-not, not-label etc.
.label.[class^="label-"] { /* this won't work */
background-color: rgba(0, 37, 100, 0.4);
}
.label[class^="label-"] { /* this won't too */
color: green;
}
.label[class*="label-"] { /* this will */
border: 1px solid green;
}
<label class='label label-a'>Label A</label>
<label class='label label-b'>Label B</label>
I have same problem. I use this in less file.
[class^="customForm-"] { ... }
But for my HTML it does not works.
<div class="form form-01 customForm-radioList">...</div>
The problem is in tha fact that string "form form-01 customForm-radioList" does not starts with "customForm-" it starts with "form".
Solution
Use contains selector W3 school.
[class*="customForm-"] { ... }
I want to either make a link in Extjs or make a button look like a link and on hover you see the button. They do this in the docs with Code Editor button and the Live Preview button.
If they do this using CSS, what CSS do I use and when/how to I apply it?
I recently wanted a LinkButton component. I tried to find a pre-existing component without any luck, so I ended up writing one from scratch. Its implementation is almost entirely CSS-based.
/******************************************************************************/
/*** LINK BUTTON CSS **********************************************************/
/******************************************************************************/
a.ux-linkbutton {
background-image: none;
border: 0px none;
margin-top: 1px;
}
a.ux-linkbutton.x-btn-default-small-focus {
background-color: inherit;
}
a.ux-linkbutton * {
font-size: inherit !important;
}
a.ux-linkbutton:hover {
text-decoration: underline;
background-color: inherit;
}
/******************************************************************************/
/*** LINK BUTTON JS ***********************************************************/
/******************************************************************************/
Ext.define( "Ext.ux.button.LinkButton", {
extend: "Ext.button.Button",
alias: "widget.linkbutton",
cls: "ux-linkbutton",
initComponent: function() {
this.callParent();
this.on( "click", this.uxClick, this, { priority: 999 } );
},
// This function is going to be used to customize
// the behaviour of the button and click event especially as it relates to
// its behaviour as a link and as a button and how these aspects of its
// functionality can potentially conflict.
uxClick: function() {
//Ext.EventObject.preventDefault();
//Ext.EventObject.stopEvent();
//Ext.EventObject.stopPropagation();
//return false;
}
} );
The click handler is a work-in-progress.
The class does have one minor issue: a pseudo-class style is applied after clicking/focusing that I have not been able to remove. If someone fixes it before I do, please, post the CSS for it.
With Ext 4.0.7 I had managed to do the following:
View:
...
{
xtype: 'button'
,text: 'Discard changes'
,action: 'cancel'
,cls: 'secondary-action-btn'
}
CSS:
....
.secondary-action-btn {
border: none;
background: none;
}
.secondary-action-btn span {
cursor: pointer;
text-decoration: underline;
}
I recall there is an extension called linkButton. You can refer to the extjs forum here