I was interested whether can I pass value to the css class from the html?
Like this
Example:
<div class="mt(5)"> Some text </div>
style {
.mt(#mpx) {
margin-top: #mpx px;
}
}
I've heard that such way was possible in Less
No, the way you want it is impossible in either CSS or any of its supersets (like Less and others). It's always HTML that uses values from CSS and not in opposite. Thus you'll need some scripting for what you need.
You can however pass values from HTML to CSS via Custom Properties using inline styles:
.c {color: var(--c)}
.m {margin: var(--m)}
<div class="c" style="--c: blue" >Foo</div>
<div class="m" style="--m: 0 2em">Bar</div>
<div class="c" style="--c: green">Baz</div>
Or even like this:
* {
color: var(--c);
margin: var(--m);
/* etc. */
}
<div style="--c: blue" >Foo</div>
<div style="--m: 0 2em">Bar</div>
<div style="--c: green">Baz</div>
But that method is no way different from styling by the plain vanilla method, i.e.:
<div style="color: blue">
... etc.
It is essentially same ugly and non-maintainable.
Many people try to achieve the goal by generating hundreds of predefined classes like .mt-1, .mt-2, ... .mt-99 etc. (since it's extremely easy thing to do in a CSS-preprocessor). But it's even more ugly solution (I won't bother you with details on why it is so. You'll read about that elsewhere or learn yourself after a few projects).
Maybe this is what you looking for? CSS: Attr()
You can bind the value to an attribute and then get this attribute back in the css, like this:
CSS
<p data-foo="hello">world</p>
CSS
[data-foo]::before {
content: attr(data-foo) " ";
}
Result
hello world
Here is a way of doing that without the use of LESS.
Use CSS variables:
Variables can be declared in the style attribute of the HTML elements.
Then, the CSS will catch the values from the HTML and apply the correct styles.
Add some JavaScript:
The values of the variables can now be dynamically modified.
⋅ ⋅ ⋅
Example of use:
Background color is set in the HTML, (fixed)
Padding of div1 will grow if clicked. (dynamic)
// When clicking on the div1, padding is gonna grow up.
document.getElementById("div1").onclick = function(){
var pad = this.style.getPropertyValue("--pad");
this.style.setProperty("--pad", parseInt(pad) + 1);
}
.divs {
background: var(--bg);
padding: calc(var(--pad)*5px);
}
<div id="div1" class="divs" style="--bg: #ff6; --pad: 1;">div1</div>
<div id="div2" class="divs" style="--bg: #f66; --pad: 2;">div2</div>
⋅ ⋅ ⋅
About CSS variables:
The variable names must begin with -- and are case sensitive.
These variables values are applied to the element and its children.
To use it globally, you can declare it on the body tag.
Here is a link with some examples: https://www.w3schools.com/css/css3_variables.asp
Related
I have these elements on the HTML:
<div id="td-status" class="icongb-cancelled"></div>
<div class="ticket-header-text">
<span class="bet-text">TEXT1</span>
<span>TEXT2</span>
</div>
and I want to apply a certain style using LESS to TEXT1 ('bet-text' class) whether its uncle has a cercaion class (in this case icongb-cancelled). I'd like to apply it also to TEXT2 (no class). Would it be possible?
I'm using this code, but it doesn't work:
.icongb_cancelled ~ .ticket-header-text {
& .bet-text {
color: #959595;
}
}
NOTE: I don't want to use JQuery to add or remove any class.
I want to make it just using LESS wihtout any modifying on the HTML.
Thanks in advance.
EDIT: The code was fine, the problem was that I was using an underscore instead of a dash. so you can use that code to apply a style to a nephew element.
You're using .icongb_canceled in the selector, but the class is icongb-canceled.
Dash vs underscore. They need to match.
You can write .icongb-cancelled ~ .ticket-header-text .bet-text, which is valid in CSS, but also is LESS compatible:
.icongb-cancelled ~ .ticket-header-text .bet-text {
color: blue;
}
.icongb-cancelled ~ .ticket-header-text span {
color: green;
}
<div id="td-status" class="icongb-cancelled"></div>
<div class="ticket-header-text">
<span class="bet-text">TEXT1</span>
<span>TEXT2</span>
</div>
EDIT: I would like to implement it with Jekyll, which (as far as I know) does not have PHP, jQuery, and so on...
I have a simple problem with CSS; it must have a simple solution but I just don't find it.
Suppose one has multiple divs with some classes:
<div class="cat">
<div class="dog">
<div class="bird">
<div class="snake">
...
and in a .css we want to style these 'pet' divs; the style is very similar from class to class (for instance we have some photos cat.jpg, dog.jpg... and want to show them). Can this be achieved by a somewhat symbolic method? Something like
div.pet{
width: 50px;
height: 50px;
background: url("/pictures/pet.jpg") no-repeat 0 0;
...
(but there is no class="pet" nor pet.jpg)
I would use sass:
div {
$list: "cat", "dog", "frog";
// generate classes for list elements
#each $element in $list {
&.#{$element} {
background-image: url('images/#{$element}.jpg');
}
}
}
That's not something you can do with CSS. CSS can only style objects and can't make other changes/additions/deletions of DOM objects.
But it is definitely something you can do with jQuery! If you know that you always have a class name class="cat" that is the same as the file name cat.jpg, you can do something like this:
$("div").each(function(){
var petClass = this.attr('class');
var petImg = petClass + ".jpg";
this.append("<img src='"+petImg+"' ... >");
});
Im not sure what your asking But as far as I understand you want to have some global setting for div elements and change the background image:
https://jsfiddle.net/shtjab2k/
Css
#pets > div
{
width:100px;
height:40px;
border:2px solid black;
float:left;
}
.cat
{
background-image: url("https://i.vimeocdn.com/portrait/58832_300x300.jpg");
}
.bird
{
background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Solid_blue.svg/2000px-Solid_blue.svg.png");
}
html
<div id="pets">
<div class="cat "></div>
<div class="dog "></div>
<div class="bird "></div>
<div class="snake "></div>
</div>
The simplest, pure-css way to do this is this:
.dog, .cat, .bird, .snake {
width: 50px;
height: 50px;
background: url("/pictures/pet.jpg") no-repeat 0 0;
}
It doesn't matter that the background we provide doesn't exist, we'll replace it in the css for individual pet types:
.dog {
background-image: url("/pictures/dog.jpg");
}
It seems like you're looking for a way to do this in a single ruleset, which, unfortunately, is not possible. For that, you'd have to look into using Javascript or a CSS superset (see other answers on this post).
Otherwise, you can just write a couple more lines of css and set the background image for each pet type. =P
It isn't possible to add different images sources to the image tags with pure CSS. You may need to use JS, JQuery, PHP , etc.
You may do this using JavaScript/JQuery as follows :
Store all the image names in an array and then run a loop on-load(of page) to get images by using those array element(values).
Using jQuery, you may set img source like this:
$("img:nth-child(i)").attr('src', <new path from array[i th element]>);
The nth-child(i) means ith image.
Using Js, you may do this:
var images = [
'path/to/image1.png',
'path/to/image2.png',
'path/to/image3.png',
'path/to/image4.png',
'path/to/image5.png'
];
function loadImages(imgArr, targetId){
for(var i=0; i< imgArr.length; i++) {
console.log(imgArr[i]);
var img = new Image();
img.src = imgArr[i];
document.getElementById('output').appendChild(img);
}
}
loadImages(images);
You can also invode the loadImage() function from yout button:
<button onclick="loadImages(images)">Start</button>
Refer : JavaScript load Images in an Array
I want to color text based on its value, using css.
ie. if value is less than 20 --> red ,
if value is between 20 - 60 --> orange ,
if value is greater than 60 to 100--> green.
I don't want to add any class in the template depending on the value.
I found this Link: How do I change the background color with JavaScript? but it doesn't suffice as I have too many values to apply color to.
Also I want it to be more maintainable when adding new values in future.
It is not possible only with CSS.
You have to use JavaScript/jQuery to dynamically add the color, based on an object color match, and test if the value in the data-color HTML attribute is between the range for each element.
The JS code dynamically check if the element attribute is in a color range and apply the matched color.
If you will have to add some color and range in the future, simply add new values in the colorMatch hash, and update your CSS color class list.
##CSS
.red {color:red}
###HTML
<p data-color="19">Lorem 19</p>
###JS
var colorMatch = {
'0-19' : 'red',
'20-59' : 'orange',
'60-100' : 'green'
};
Here is the working fiddle
If you do not consider it cheating to not use the actual innerHTML as a condition, but rather construct it from a CSS variable using content you could do something like this (just as an effort to not use JS in this case):
<num style="--num:1"></num>
<num style="--num:99"></num>
<num style="--num:165"></num>
num {
--breakpoint: 100;
--g: calc((clamp(0, var(--num), var(--breakpoint)) - calc(var(--breakpoint) - 1)) * 255);
color: rgb(0, var(--g), 0);
}
num:after {
counter-reset: variable var(--num);
content: counter(variable);
}
In this scenario I am coloring any of the numbers green if they are above 100, but more rules can be added using the same method to serve your use-case.
With that said, I think there is probably no scenario where this would ever be useful, other than just technical trivia, as it is more readable to simply change the class of the element dynamically using plain JS. Still kinda fun way to use counter-reset and counter though.
Here is the same example on jsfiddle: https://jsfiddle.net/msz1aouc/24/
A simple approach could be
HTML
<div class="content">
<p>high</p>
</div>
<div class="content">
<p>low</p>
</div>
<div class="content">
<p>medium</p>
</div>
<div class="content">
<p>critical</p>
</div>
<div class="content">
<p>high</p>
</div>
Jquery
var content = $(".content p").text();
if (content == "high") {
$(this).css("color", "#ffffff");
}
if (content == "low") {
$(this).css("color", "#ccc");
}
if (content == "critical") {
$(this).css("color", "#000");
}
I'm noot good in english, so the title may seem a bit odd.
I want to use css function attr() like this:
I mean i have a container <div> and an inner <div> that i want to have width depending on data-width attribute. For example this would be great, but this doesnt work:
<div class="container">
<div data-width="70%">
</div
</div>
.container {
width: 600px;
height: 200px;
}
.container div {
width: attr(data-width);
height: 100%;
}
Is there any noJS way to use attributes like that?
UPDATE: Guys convinced me that the JS is the only way to do this :)
That's not a big problem (but that's bad. CSS, why youre so illogical? Is the difference between content:attr(data-width) and width: attr(data-width) so big ?).
One of the guys had an idea to go through the all elements with jQuery.
That's ok, but it is very... local? Don't know how to say it in english.
Anyway, i remaked his code a little bit and here it is:
allowed = ['width','color','float'];
$(document).ready(function () {
$('div').each(function (i, el) {
var data = $(el).data(),style = '';
if (!$.isEmptyObject(data)) {
$.each(data, function (attr, value) {
if (allowed.indexOf(attr) != - 1) {
style += attr + ': ' + value + '; ';
}
})
if (style.length != 0) {
$(el).attr('style', style);
}
}
})
})
Idea is simple:
1. We suppose that style we want to add to an element is the only one. I mean there are no scripts that will try to add some other styles,
2. We create an array of allowed attribute names, we need to avoid using wrong names at the style attribute, for example style="answerid: 30671428;",
3. We go through each element, save its data attributes in an object, check if object is empty, and if not - check every attribute if it is allowed, create a string that contains all styles that we need, and - finally - add our style string to the element as the content of style attribute.
That's all, thanks everybody
I would not advise to use CSS alone since it will not allow you to do what you're looking for... instead use a scripting language (in my case jQuery) to accomplish this functionality for you like so: jsFiddle
jQuery
jQuery(document).ready(function(){
var dataElem; // to store each data attribute we come accross
jQuery('div').each(function(){ //loop through each div (can be changed to a class preferably)
dataElem = jQuery(this); //get the current div
if(dataElem.data('width')){ //make sure it exists before anything further
dataElem.width(dataElem.data('width')); //set the element's width to the data attribute's value
dataElem.css("background-color", "yellow");
}
});
});
HTML
<p>The links with a data-width attribute gets a yellow background:</p>
<div>
w3schools.com
</div>
<div class="me" data-width="50"> <!-- change value to see the difference -->
disney.com
</div>
<div>
wikipedia.org
</div>
Notes on the above:
each, data, width.
Instead of doing data-width, use a class attribute. An html tag can have mutliple classes separated by spaces, so if you wanted to be very precise, you could set up as many classes as you need. For instance:
<div class="w70 h100">
</div>
Then in your css:
.w70{
width: 70%;
}
.h100{
height: 100%;
}
And so on.
Is there any noJS way to use attributes like that?
No, you cannot use CSS to set the width of the element to it's data-width attribute. CSS does not allow for this as attr() is only currently available for the CSS content property which is only available on css pseudo elements (::before and ::after).
How can you achieve this with as little javascript as possible?
This is extremely easy to do using the native host provided DOM API.
Select the elements using Document.querySelectorAll().
Iterate the elements and apply the styles using Element.style which can be retrieved from the data-width attribute using Element.dataset
(Demo)
var items = document.querySelectorAll('#container div'), item, i;
for(i = 0; (item = items[i]); i++) item.style.width = item.dataset.width;
I am getting started with learning CSS.
While looking through the tutorial on w3schools.
I realized some of the example start with
.awesome-text-box{}
Is there a different between
.awesome-text-box {} and awesome-text-box{}
without the dot?
What does the dot notation means here
p.one {
border-style: solid;
border-width: 5px;
}
p.two {
border-style: solid;
border-width: medium;
}
p referes to ?
A dot in css is for what is called a class.
They can be called almost anything, for example in your CSS you would create a class and add style for it (in this case, I'm making the background black);
.my-first-class {
background-color: #000;
...
}
and to apply this class to an HTML element, you would do the following
<body class="my-first-class">
...
</body>
this would mean the body of the page would become black.
Now, you can create classes for CSS style or you can reference HTML elements directly, for example (CSS again);
body {
background-color: #000;
}
would directly reference the <body> element on the page and do the same again.
The main difference between the two is that CSS classes are reusable. By comparison, referencing the HTML tag directly will affect all tags on the page (that are the same), for example (CSS again);
body {
background-color: #000;
}
.my-first-class {
background-color: #FFF;
}
and now for some HTML;
<body>
<p class="my-first-class">This is the first line</p>
<p class="my-first-class">This is the second line</p>
</body>
This would produce a black page, with 2 white boxes with text inside them (try it out!)
Now for your last part of the question about p.one {...} CSS.
This is a reference to a <p> tag that has class="one" added to it, <p class="one">...</p>
That CSS will only work on a <p> tag with the one class added (as above).
Extra for experts...
There is also one more selector type and it's called an ID (and I personally do not use these when doing CSS styling but some people like too and I don't know why...)
Much like a class, you can have an id on an HTML element; <p id="my-first-id"></p>
and to add CSS style to this, you would put (in the CSS);
#my-first-id {
...
}
and that would style all elements with that id added.
Hopefully that helped answer all the parts, ask again if you need an even better explanation :)
The dot denotes that the selector is a class. So it will select elements in your page as such:
.awesome-text-box {
}
<div class="awesome-text-box"></div>
Whereas without the dot denotes an element name. Such as:
div {
}
<div></div>
In the other example you gave, the dot notation is using chaining this is where you can select an element with numerous conditions. In your example:
p.one {
}
// Will find
<p class="one"></p>
// However it will not find
<div class="one"></div>
Whilst I am here I can give you a list of other common selectors too:
#awesome-text-box => <div id="awesome-text-box"></div> => ID
.btn.btn-style-1 => <span class="btn btn-style-1"></span> => Chaining classes
p > span => <p><span></span></p> => Child
p span => <p><a><span></span></a><span></span> => Descendant (anything below)
p + span => <p></p><span></span> => Sibling
A '.' refers to a class, while a '#' refers to a id.
When neither a '.' or a '#' are used, the CSS will apply the style to an HTML object.
So for p .one and p .two, the CSS will be applied to the '.one' and '.two' classes that exists within the 'p' object.
For a more detailed example;
<p class = "one">This text will have the CSS of "p .one"</p>
<p class = "two">This text will have the CSS of "p .two"</p>
. means a class. You can call that CSS class with HTML
example
<span class="awesome-text-box"> ABCD </span>
and P means <p> tag in HTML you can call
<p class="one"> ABCD </p>
Ref -
http://www.w3schools.com/css/css_selectors.asp
The dot notation is for class and without dot that would not work. The selector name like div, p don't need dot notation. And use hash (#) for the selector with id.
Ex-
<div id="foo">foo bar</div>
<div class="bar">foo bar</div>
#foo{} /* selects foo with id foo */
.bar{} /* selects foo with class bar */
div{} /* selects the div */
Here . is class selector. It means apply style to all elements which has class awesome-text-box ie,
<div class="awesome-text-box"></div>
while without dot it is tag name like you mention in second example p Here p is tag:
<p>Some text</p>
Similarly p.one apply the style to all p tags which has class one. ie,
<p class="one">Some text</p>