Dynamically add styles in css/less by using class name - html

Is there a way where I could dynamically add the styles in css/less file by just passing in class name ?
For example:
<div class="xyz_20"></div>
<div class="xyz_40"></div>
Instead of writing:
.xyz_20 {width:20px;} .xyz_40 {width:40px;}
Is there a way where i could write a single class .xyz_i and width be automatically added based on the i value, like .xyz_i {width: i px;}` without involving javascript.
If so, Please suggest.

This is not possible, as far as I know, however this is a great use case for inline styling:
<div class="xyz" style="width:20px"></div>
If you wanted to support a finite number of widths, then you can use recursion to generate classes:
.widthgen(#count) when (#count > 0) {
.widthgen((#count - 10));
.xyz_#{count} {
background-color: red;
width: #count * 1px;
}
}
.widthgen(50);
Output:
.xyz_10 {
background-color: red;
width: 10px;
}
.xyz_20 {
background-color: red;
width: 20px;
}
.xyz_30 {
background-color: red;
width: 30px;
}
.xyz_40 {
background-color: red;
width: 40px;
}
.xyz_50 {
background-color: red;
width: 50px;
}
Lists Plugin
You could use the lists plugin (to install: npm install -g less-plugin-lists) if your widths you want to support are not easily captured in a linear pattern:
#widths: 10, 20, 40, 50;
.for-each(#i in #widths) {
.xyz_#{i} {
background-color: red;
width: #i * 1px;
}
}
You would compile that with:
lessc --lists in.less out.css
And you would get:
.xyz_10 {
background-color: red;
width: 10px;
}
.xyz_20 {
background-color: red;
width: 20px;
}
.xyz_40 {
background-color: red;
width: 40px;
}
.xyz_50 {
background-color: red;
width: 50px;
}

No.
There is no way to write classes and expect the browser to infer meaning from them.
The only way to accomplish something similar to this would be with javascript (which OP said they did now want to use).

Related

Overwrite primary Bootstrap 4 color with internal CSS

I need to change the default primary Bootstrap 4 color (after the Bootstrap stylesheet has been loaded) to a custom color (choosed by user) for a dynamic Bootstrap component with an internal CSS stylesheet.
I could do, for example, .btn-primary { background-color: red; } but this works just for buttons and, however, it doesn't change the other btn-primary states like ":hover", ":active" and "disabled". It also doesn't change the "primary" color throughout the entire CSS for .alert-primary, .text-primary, .bg-primary, .btn-outline-primary, .badge-primary, etc...
What's the possible solution?
You need to download the Bootstrap Sass files. You can do so from this link.
Once you have them you can open the main bootstrap .scss file and search for:
$theme-colors: (
"primary": #0074d9,
"danger": #ff4136
);
Change "primary" to what you need and then recompile to CSS. If you don't have Sass installed on your machine you can use various online tools to accomplish this. Example.
Source: https://getbootstrap.com/docs/4.3/getting-started/theming/
You can do so by using the variables concept(https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties)
Bootstrap 4 also works on the variables
You can try changing the variable values at run time as mentioned below:
:root {
--main-bg-color: brown;
}
.one {
color: white;
background-color: var(--main-bg-color);
margin: 10px;
width: 50px;
height: 50px;
display: inline-block;
}
.two {
color: white;
background-color: black;
margin: 10px;
width: 150px;
height: 70px;
display: inline-block;
}
.three {
color: white;
background-color: var(--main-bg-color);
margin: 10px;
width: 75px;
}
.four {
color: white;
background-color: var(--main-bg-color);
margin: 10px;
width: 100px;
}
.five {
background-color: var(--main-bg-color);
}
// get variable from inline style
element.style.getPropertyValue("--main-bg-color");
// get variable from wherever
getComputedStyle(element).getPropertyValue("--main-bg-color");
// set variable on inline style
element.style.setProperty("--main-bg-color", "red");
There are different ways do it. I am describing one of them.
Import below lines to your scss file.
#import '~bootstrap/scss/bootstrap.scss';
After that write below code to override it.
$primary = 'red';
$gray = 'gray';
.btn {&.btn-primary {
#include button-variant($primary, $primary, $primary, $primary);
&.disabled,
&:disabled {
border: $gray;
background-color: $gray;
}
&:hover {
opacity: 0.85;
}
}
}
Check the link to use sass mixins to override bootsrap classes.

SCSS + BEM style children structure when parent has modificator

Please is possible to set scss for element inside --rounded ? I do not wanna use .box__something, but I need to modify children that is depend on parent modifier
<div class="box">
<div class="box__something">Hello</div>
</div>
<div class="box box--rounded">
<div class="box__something">Hi</div>
</div>
.box {
&__something {
background: blue;
}
&--rounded {
background: green;
.box__something { // <<< Is some better selector?
background: pink;
}
}
}
Sass doesn't have any great built-in solutions to solve your issue, this is a problem that has been explored many times. You can however acheive the result you are after in a slightly un-elegant manner by using the & helper to join the classes that you wish to join. I have included a live example here.
While this does work, you must realise that if you want to style the .box--rounded class directly you must have it inside it's own class as illustrated below, you cannot use it with the trailing & class that we have placed &__something on.
I recommend you play around with my sassmeister gist and see what results you can come up with.
.box {
&__something {
background: blue;
}
&--rounded {
background: green;
}
&--rounded & {
&__something {
background: pink;
}
}
}
I hope this has solved your issue.
The modifier should be used not on the parent, and the child element .box__something
If I understand your problem correctly, I feel your pain! As soon as you nest a nested property & changes to the parent.
You can however cache the original class name as a variable like this:
$box: box;
.#{$box} {
.#{$box}__something {
background: blue;
}
.#{$box}--rounded {
background: green;
.#{$box}__something { // <<< Is some better selector?
background: pink;
}
}
}
The only problem with the method above is that you end up with a larger volume of compiled CSS. This renders to:
.box .box__something {
background: blue;
}
.box .box--rounded {
background: green;
}
.box .box--rounded .box__something {
background: pink;
}
To reduce the size of the output you could combine & with the variable method like so:
.box {
$box: &;
&__something {
background: blue;
}
&--rounded {
background: green;
#{$box}__something {
background: pink;
}
}
}
This renders to:
.box__something {
background: blue;
}
.box--rounded {
background: green;
}
.box--rounded .box__something {
background: pink;
}
That way you can change the class name in the variable and everything gets updated, I also think it reads a bit better.

Styling multiple data-tooltips

I have multiple tooltips on my website which I created using data-tooltip. The problem is that it's an attribute so I can't just apply a class in front of it and use it. So what I want is for instance different width for one tooltip or different color etc.
This is an example in the css for the "data-tooltip"
[data-tooltip] {
position: relative;
z-index: 2;
cursor: pointer;
}
Can you please provide some additional html?
It's possible to use a class:
.my-class-1[data-tooltip] {
width: 100px;
}
.my-class-2[data-tooltip] {
width: 200px;
}
<div class="my-class-1" data-tooltip="true">...</div>
<div class="my-class-2" data-tooltip="true">...</div>
or you could also use another data-attribute:
[data-tooltip][data-tooltip-small] {
width: 100px;
}
[data-tooltip][data-tooltip-big] {
width: 200px;
}
<div data-tooltip="true" data-tooltip-small="true">...</div>
<div data-tooltip="true" data-tooltip-big="true">...</div>

Back to the parent selector using ampersand?

I'm using Less to write CSS, it totally saved much time for me. Now I have small issue, here is my code:
largest fight gym in Australia
Less
.btn{
position: relative;
padding: 15px 22px;
color: #color-black;
&-black-bg{
background: #color-black;
color: #color-white;
}
&-right-skew{
position: relative;
&:after{
content: '';
position: absolute;
right: -10px;
top: 0px;
width: 20px;
height: 100%;
.skewX(-15deg);
}
}
}
Now I my goal is if btn-black-bg so btn-right-skew has black background too. In CSS, I can handle with this code:
.btn-black-bg.btn-right-skew:after{
background: #000;
}
But I don't know how to do this in LESS. Hope everyone can help me out.
Based on your HTML, adding the background: #000 to .btn-black-bg:after (one of the 2 classes) alone is enough but I assume you want to apply some properties only when both classes are present on the same element. For that, you can use the parent selector like below:
.btn {
&-black-bg&-right-skew:after {
background: #000;
color: #fff;
}
}
You cannot nest this into the &-black-bg or &-right-skew (as the order of classes doesn't matter in CSS) and make use of the parent selector because the parent selector would always refer to the full parent and not just the immediate parent. The best that can be done with nesting would be the below but the would need the .btn to be statically added to the innermost selector instead of using &.
.btn {
&-black-bg {
&.btn-right-skew:after {
background: #000;
color: #fff;
}
}
}
You can make use of variables to achieve nesting like mentioned here but I wouldn't recommend it for your scenario because the selector given above is more simple and readable.
I would recomend to separate the clases into a base class "btn" and modifier classes "black-bg" and "right-skew". (In my opinion this makes it easier to understand what is applied and how it can be combined.)
see my axample on codepen: http://codepen.io/fabiandarga/pen/bVNpLE
largest fight gym in Australia<br />largest fight gym in Australia
css:
.btn {
display: inline-block; // added to let the padding affect the height
position: relative;
padding: 15px 22px;
color: #color-black;
&.black-bg{
background: #color-black;
color: #color-white;
}
&.green-bg{
background: #color-green;
color: #color-white;
}
&.right-skew{
position: relative;
&.black-bg { // combine both classes = .right-skew.black-bg
&:after {
background: #color-black;
}
}
&.green-bg:after { // or short form
background: #color-green;
}
&:after {
content: '';
display: block; // was missing;
position: absolute;
right: -10px;
top: 0px;
width: 20px;
height: 100%;
transform: skewX(-15deg); // changed to make it work in the example on codepen
}
}
}

Simplifying CSS root selector

Please refer below css code
#AdminUser .admin-label-margin {
margin-left: 160px;
margin-top: -25px;
padding-bottom: 10px;
}
#AdminUser #entitytitle h4 {
margin-left: 175px;
padding-bottom: 13px;
}
#AdminUser input[type='text'] {
width: 180px;
}
#AdminUser .admin-label-span {
margin-left: -15px !important;
margin-right:12px;
}
Each and every time I am specifying the root element and applies the css to specific control. I don't want to this kind of scenario. How can i simplify the above css and specify root selector in one time ?
CSS does not support this. You can however use a preprocessor like Sass/SCSS.
With SCSS:
#AdminUser {
.admin-label-margin {
/* snip */
}
/* snip */
}
Note that the final code will look similar to the original one, SCSS translates the above code to the one you currently have, so that you can develop more easily.
You could use a CSS pre-processing library like LESS which allows you to express your css using nested statements.
So it will allow you to write
#AdminUser {
.admin-label-margin {
margin-left: 160px;
margin-top: -25px;
padding-bottom: 10px;
}
#entitytitle h4 {
margin-left: 175px;
padding-bottom: 13px;
}
input[type='text'] {
...
}
.admin-label-span {
...
}
}
but once processed it would output the CSS to the browser in the standard non-nested format. ie. it would generate your original CSS :
#AdminUser .admin-label-margin {
margin-left: 160px;
margin-top: -25px;
padding-bottom: 10px;
}
#AdminUser #entitytitle h4 {
margin-left: 175px;
padding-bottom: 13px;
}
#AdminUser input[type='text'] {
width: 180px;
}
#AdminUser .admin-label-span {
margin-left: -15px !important;
margin-right:12px;
}
Bear in mind that if you use LESS you have a few considerations :
running compilation of .less to .css files as part of your build process
or using on the fly conversion with the less javascript
you might get FOUC's
you'll need to check that your webserver is happy serving the less mime type
On the plus side you'll get mixins, variables and all the goodness that LESS brings you alongside the coding syntax convenience you're looking for.
LESS might be useful:
#AdminUser {
& .admin-label-margin {
margin-left: 160px;
/* ... */
}
/* ... */
}
There is no way to simplify it in CSS.
You could use a CSS preprocessor language, such as SASS, which would allow you to:
#AdminUser {
.admin-label-margin {
margin-left:160px;
margin-top:-25px;
padding-bottom:10px
}
#entitytitle h4 {
margin-left:175px;
padding-bottom:13px
}
input[type='text'] {
width:180px
}
.admin-label-span {
margin-left:-15px!important;
margin-right:12px
}
}