Style an element based on its position within a group - css

I am trying to create a set of boxes. I want to try and see if I can set the size of the box based on its position within the group.
Currently this is possible if I know the number of boxes beforehand and use the :nth-child() selector and the appropriate position.
Since CSS already has the capability to find the position of the element in the group, is it possible to use this positioning as an input for the size.
So for example something like
#boxes:nth-child() {
height:calc(n * 10);
width:calc(n * 10);
}
This purpose can easily be achieved using a server side code or even Javascript but just curious to understand if we can use CSS to achieve this, using calc or any other feature.

In CSS Selectors Level 3, there are no methods for targeting an element then, using variables corresponding to that element's position within a group, tailoring styles for that element.
In CSS, the calc() function does not allow variables. Only mathematical expressions with addition (+), subtraction (-), multiplication (*), and division (/) are allowed as component values.
With Sass, however, a CSS preprocessor, using variables in a calc() function is possible.
References:
CSS Selectors Level 3
8.1. Mathematical Expressions: calc()
Sass Variable in CSS calc() function
Sass Variables

You can't do this in pure css, but you can with scss.
For example:
#for $i from 1 through 5 {
.box:nth-child(#{$i}) {
height: 50px * $i;
}
}
You can play with code here.

Related

Using CSS selectors and combinators (*, ~, >, <, +)

I am working with CSS selector symbols to create complex element selectors. I am currently stuck with selector symbols which I cannot create combinations with.
For instance, I am trying to create: body and children elements of body that are not of #foo id using
body > *:not(#main-div) + body
but the combinations of the elements don't work. I have used each of the selectors individually at least once before, but never tried their combinations. This feature seemed very useful to me and so I wanted to know whether it is possible to create combinations of these selector symbols. If yes, what is the correct syntax to follow?
In order to apply styles to both the body and all immediate children of the body (excluding the #main-div) element, you should use the following selector list:
body,
body > *:not(#main-div) {
...
}
Commas should be used to group selectors into selector lists. The + is an adjacent sibling combinator.
The Mozilla Developer Docs has a great primer on forming CSS selectors and rulesets here: https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors
This feature seemed very useful to me and so I wanted to know whether it is possible to create combinations of these selector symbols. If yes, what is the correct syntax to follow?
Yes it is possible but i think the syntax you are using is incorrect instead you must use
body > :not(#main-div),body
And according to me there's no use of * and + because by even not mentioning * it will exclude all the id's that are #main-div and + is only used when the element is right after the current element.

How to put less than operater on css3 selector?

If I have a tag like this
<div id='testdiv' style='height:300px;'></div>
How can I write a css rule that says
select tag with id testdiv where it contains a style attribute that has height property whose value is less than 400px
Is this possible?
This is not possible in the current standard of CSS. CSS4 might include a selector for it, but that's for far in the future. However it is possible using JavaScript or jQuery.
It must be noted that IDs must be unique. You should use classes if you want to use the same name.
In jQuery, the filter function should be able to solve this.
var smallDivs = $(".test-div").filter(function() {
return $(this).css("height") < 400;
});
It might also be possible in SASS, where you can create functions.

Can I style content:counter based on counter value?

I am using CSS2.1 counters to apply numbers to men on the board in the implementation of a board game whose board diagrams use HTML and CSS, by doing something like:
.ply {counter-increment:main;}
.move:before {content:counter(main);}
With HTML structured as
<ply>
<move...>
<ply>
<move...>
</ply>
</ply>
All this works fine, but I would like to conditionally style the counter value differently if it's two digits in length (squeeze the two digits together with a negative letter-spacing, for example). Any ideas about how to do this or workarounds?
It turns out that we can retrieve the value of the counter in question with getComputedStyle, using the second argument which specifies the pseudo-element for which the counter was specified as the content:
value = window.getComputedStyle(elt, ':before').content;
Then we can apply a style such as
if (value>=100) { elt.style.letterSpacing = "-2px"; }
Which is what we want, although it requires traversing all the potentially affected elements with JS whenever they might have changed.
You can't do this using only CSS as there is nothing in css selectors about the size of the content.
That could be an anwser but if you want a workaround, it's possible using javascript.
Here's an example (using jquery) in which I change the color of the text when it's more than 2 chars long :
$('.move').each(function(){
if ($(this).text().length>2) $(this).css({color:'red'});
});​
Demonstration : http://jsfiddle.net/dystroy/nKVvG/
I know it's not really what you wanted, but I made some research and couldn't find any css only way to do this, basically because as stated by #dystroy
"You can't do this using only CSS as there is nothing in css selectors about the size of the content."
So there's no way for the css to know how long is the content in the :before part.
So I guess you should really use jQuery a bit. Try this jsfiddle.
Basically what you can do is iterate over the elements you're indexing with the css counter and then use the .index() attribute to see wheter their counter is double or triple digit.
Remember .index() starts from 0 when the counter starts from 1, so in the double digit condition check you should put
if($(this).index() > 8) ...
because counter = index + 1 -> if(counter > 9) = if(index > 8)
If the counter is double digit then you add a class to your movie element so you can freely style it in your css.
I think what you are looking for is discussed in this post: Selecting and manipulating CSS pseudo-elements such as ::before and ::after using jQuery. I don't think you can do this via plain css, but I may be mistaken.

Can a CSS selector reference another selectors property?

I've just noticed that Webkit now has some support regarding the CSS Values and Units Module Level spec. And I was wondering if anyone knows if there is a way to reference another CSS selectors (or DOM style) property from a CSS selector?
I'm expecting something like this to be the answer here. Which I know is most likely the case for current browser implementations; but please keep reading...
For instance, in the case where an animation might resize an element (NOTE the ${.element2.width} is fictitious syntax):
<style type="text/css">
.element1 {
.width: /*-webkit-,-o-,-moz-*/calc(80% - ${.element2.width});
}
.element2 {
.width: 100px;
}
.element2:hover {
width: 200px;
transition: all 0.4s ease-in-out;
}
</style>
In this case I would expect the .element1's width to be re-evaluated based off the transition triggered from the hover events on .element2.
I realize that the aforementioned spec. is only a working draft but perhaps the syntax for referring to such a 'referential selector property' is defined within another spec. which I'm yet to discover? Or simply just not a case for concern (thanks to an overlooked work around)?
I added an answer to the question you linked: https://stackoverflow.com/a/11071806/137626
You can use the same declaration block with as many selectors as you want by grouping them (selectors are separated by commas)
You can't reuse the same declaration block later with a different CSS selector without rewriting the whole declaration block preceded by this selector or using a preprocessor/macro that'll do that for you. Or add it to the existing declaration block as above
Now with your example of an element resized by CSS itself: you could use CSS3 Media Queries and its #media rules containing as many declaration blocks as you want. These media queries would adapt to the width of viewport here.
Mixing expanding elements via animation and media queries that would've the reverse effect will be very soon very complicated (and I'll wonder what content you're playing with); if you want to Keep It Simple, then JS is the way to go. There are variables, loops, events ;) and you can start a CSS3 animation by adding or removing a single class from an element (or whatever CSS selector).
CSS3 won't replace JS (and you shouldn't use JS to style HTML as JS isn't activated or existing everywhere and there's already a nice fallback named CSS).
Other than using a pre-compiler such as sass/scss or less, I believe all you can do is wait or hard-code it.

How to apply styles to an element with a prefixed ID?

I need to apply a style on a recurring element which has a fixed prefix in its ID. e.g. for the generated ID old-price-520, old-price is the prefix, and the numeric suffix will vary.
How do I apply styles to these elements, or how do i refer to them using CSS?
Here's an illustration of what i'd like to do:
#old-price-* {
// some styles
}
div[id|="old-price"]
would select all div Elements with id = old-price-*
Handycap is it's performance which is pretty poor, compared to the power of the # id-selector. Also it has a lower specificity than the normal #.
edit:
fiddle
You can try to use CSS3 attribute selectors like this:
div[id^=old-price]
{
// some styling
}
However you will need to add some javascript for browsers that do not support it
you can do so with the 'begin-with' attribute selector in CSS3, like so:
[Attr^="value"]
and the concrete example would look like this:
*[id^="old-price-"]
there are probably more methods of achieving the same outcome, a quick search came up with this attribute selectors depiction for a quick reference.
You can use jQuery to do this with an 'Attribute starts with selector'
http://api.jquery.com/attribute-starts-with-selector/

Resources