Anyone Know a Way to Inherit the Parent of an Extended Class? - less

Background:
Im working on a framework that has browser classes applied to the HTML element.
Im trying to apply a cross browser fix (for safari5) whenever I extend to a mixin.
Example Markup:
<html class="safari5">
<div class="child"></div>
</html>
LESS:
.mixin{
content:"cool style mixin that breaks on safari";
}
.safari5{
.fix{content:"hacks safari5's bullshit and semi-fixes cool style mixin"!important;}
}
.child{
&:extend(.mixin);
&:extend(.fix);
}
/*
Expected CSS Output:
.mixin,
.child {
content: "cool style that breaks on safari";
}
.safari5 .fix,
.safari5 .child{
content:"hacks safari5's bullshit and semi-fixes cool style mixin"!important;
}
*/
Thanks!

See extend all. E.g.:
.mixin {
1: 1;
}
.safari5 {
.fix {2: 2}
}
.child {
&:extend(.mixin, .fix all);
}

Related

Set CSS class dynamically without template

For each component with prefix mycomponent- I would like to add a class with the name of the component. I don't want to have to modify the component in order to do this.
My first thought was to use mixins and somehow add the class in beforeCreate but I haven't managed to add classes dynamically without using the template.
Do I have to use $el.classList.add(this.$options.name) in beforeUpdate or similar? Is there some more Vue-ish way to do it?
Here it is, wrapped up as plugin:
const addComponentNameAsClass = {
install(Vue, options) {
const fn = Vue.prototype.$mount;
Vue.prototype.$mount = function() {
fn.apply(this, arguments);
if (this.$options._componentTag?.startsWith("mycomponent-")) {
this.$el.classList.add(this.$options._componentTag);
}
}
}
}
Vue.use(addComponentNameAsClass);
// that's all you need
// see it working:
['a', 'b', 'foo', 'whatever'].forEach(type => {
Vue.component('mycomponent-' + type, {
template: '<div><slot /></div>'
})
});
new Vue({
el: '#app'
})
[class^="mycomponent-"] {
border: 1px solid;
margin-bottom: 4px;
padding: 1rem;
}
.mycomponent-a {
border-color: red;
}
.mycomponent-b {
border-color: blue;
}
<script src="https://cdn.jsdelivr.net/npm/vue#2.6.12"></script>
<div id="app">
<mycomponent-a>I should get a red border.</mycomponent-a>
<mycomponent-b>I should get a blue one.</mycomponent-b>
<mycomponent-foo>bar</mycomponent-foo>
<mycomponent-whatever>Meh.</mycomponent-whatever>
</div>
Notes:
you should not expect this to work on Vue3. Why? Because whenever you're using internal props starting with _ Vue does not guarantee they'll still be there in the next major version update. But, on the other hand, the name of the component is not saved anywhere else (other than $options._componentTag).
the above won't work if you use components as <MycomponentA></MycomponentA>. However, you can swiftly get around it by running the value of $options._componentTag through a helper function (e.g: kebabCase from lodash).
note on note: if you want the added class to always be kebab-case, you'll have run the value passed to .classList.add() through kebabCase, as well). Otherwise, <MycomponentA> will add MycomponentA class and <mycomponent-a> will add mycomponent-a class, for obvious reasons.
Ref. "Vue-ish way": whatever the end goal of applying this "component" class is, chances are it can be achieved cleaner.
The very idea of placing classes denominating component type doesn't feel Vue-ish at all.
It feels WordPress-ish and Angular-ish. To me, at least.

Using mixins as functions

I need to return value form LESS Mixin to less CSS attribute. It is simple in SCSS but unable to replicate it in Less. Anyone who can resolve this issue for me. Thanks in advance. Below is the example what I wanted to achieve form LESS Mixin.
In LESS
.rem(#pixel) {
#em: unit(#pixel*0.025,rem);
}
Not able to return this value like in SCSS
In SCSS
#function pxtorem($pixels, $context: 0.0625) {
#return #{$pixels*$context}rem;
}
.div {
font-size: rem(16);
}
output:
.div {
font-size: 1rem;
}
Want to return the value like in SCSS
See Using Mixins as Functions.
I.e. in your case it will be something like:
.pxtorem(#pixels, #context: 1./16) {
return: 1rem * #pixels * #context;
}
.div {
font-size: .pxtorem(8)[];
}

Defining a:focus selector

I have the below HTML structure.
<html>
<a class="customcssstyle" href="#'>Link</a>
</html>
Now I need to have a style, such that on focus on the link , it should appear in red.
For that in normal CSS, we write it as:
a.customcssstyle:focus
{
color:red;
}
May I know how we can write it using Less CSS.
CSS syntax is valid in less. But also you can do something like:
.customcssstyle
{
a {
&:focus {
color:red;
}
}
}
First of all: a is an inline element and should be inside a block element (not html). Then in css for calling a class you need a dot, e.g. .customcssstyle and not the value of the attribute class only. At least to select the focus state of this element just call the class with the pseudo selector :focus.
.customcssstyle:focus {
color: red;
}

How can I target an element within a class using less?

I would like to target specific elements within a class using less.
In this case, I would like to target elements of class button, but within that I would like to target an anchor tag a.
Currently I have:
.button {
/* lots of bits and pieces go here, hence
the need to keep it at a class level
*/
/* further down, but still in .button */
/* Attempt 1 - fails: compiled = a .button (note the space)
a& {
height:20px;
}
/* Attempt 2 - fails: compiled = .buttona
&a {
height:20px;
}
}
I basically want it to compile to:
a.button
This is so I can create elements such as:
<a class="button">
<button class="button">
But slightly alter it when its an anchor. I don't want to throw in the it's a bug in less! card too early, but if I use &.another-class it works as expected (compiled: .button.another-class, but not when targeting elements
You're using an old version of less. The code below generates the correct CSS using less 1.3.3
.button {
a& {
height:20px;
}
}
generates:
a.button {
height: 20px;
}
#Allen Bargi answer is correct, yet only for this specific scenario. I am a little confuse about what you want to achive.
As #Allen Bargi pointed out, this will target "a" lements with a "button" class and generates a
.button {
a& {
height:20px;
}
}
It generates:
a.button {
height: 20px;
}
Meanwhile, this below will target "a" elements contained whitin an element with a "button" class. which seems to me was your original objective.
.button {
a {
height:20px;
}
}
It generates:
.button a {
height:20px;
}
Both solutions migt work fine in this case because you are using the same "button" class for both the parent and the child elements, but they are not targeting the same elements.
I hope this helps.

LESS - structuring the document

i started using LESS to have a simple tool for creating .css files.
My question is, what is the most common way to handle such css class-construct:
<div id="wrapper">
<div id="left">
<h2>Left</h2>
</div>
<div id="right">
<h2>Right</h2>
</div>
</div>
The boxes #left and #right have exactly the same stylesheet, the h2 in each box should be different.
I would have solved it with this code:
#wrapper {
#left, #right {
width:50%;
float:left;
}
#left h2 {
color:black;
}
#right h2 {
color:red;
}
}
or you can solve it like this:
.left_right {
width:50%;
float:left;
}
#wrapper {
#left {
.left_right;
h2 {
color:black;
}
}
#right {
.left_right
h2 {
color:red;
}
}
}
What is the 'right' way or is it just a personal choice...
P.S: And is there any way to get highlighting in CODA for .less files?
Thanks
Personal preference for sure. The first example, for me, is easier to read and should result in less CSS, which is the purpose of LESS after all!
As for syntax highlighting in CODA, I don't use it myself, or have access to a Mac right now, but a quick Google search turned up a few results.
Instructions for one way can be found here: http://christophercasper.com/2010/09/less-syntax-highlighting-in-coda/
I also found a that there was a plugin for CODA, but it's now been turned into it's own app. Not sure how useful it is, but you can find it here: http://incident57.com/less/