Select variating position NTH child with CSS - html

I have an item (X) in a menu that changes the position depending of the user, for example:
Regular user:
N | N | N | X | N
Admin User:
N | N | N | N | X
I need to select that item using NTH-CHILD, the item has no ID or CLASS or any fields, this needs to be done using NTH-CHILD, so using the first example to select the item in a regular user menu:
element:nth-child(4)
But this instead should work for both cases in a single selector
element:nth-child(4 or 5 will always be the same with the algorithm)

Selectors match elements based on information relayed by the markup. This information does not include text content. That's why Johannes and dippas have suggested adding the appropriate class names to the body or some other element — because that's precisely the sort of thing classes were meant for.
If your markup does not discriminate based on whether the user is a regular user or an administrator, then as far as CSS is concerned, your markup is identical in either case, and there's nothing you can do to ensure that your selector always matches the right element.

If you have the possiblity to put different classes into the body tag (or any other tag that is on a higher level) depending on the status admin/not-admin, you could adress it this way:
.user-page ... element:nth-child(4), .admin-page ... element:nth-child(5) {
...
}

there has to be something to differentiate the regular user from the admin user, usually is a class added to html or body tag, if you have that, then you could use the nth-child or nth-of-type based on the parent.
Something like this:
(used section for snippet/demo)
div {
background: green;
display: inline-flex
}
.regular div:nth-of-type(4) {
/* nth-last-of-type(2) */
background: red
}
.admin div:last-of-type {
/* or nth-of-type(5) or nth-last-of-type(1)*/
background: red
}
<section class="regular">
<div>normal</div>
<div>normal</div>
<div>normal</div>
<div>NOT normal</div>
<div>normal</div>
</section>
<hr />
<section class="admin">
<div>normal</div>
<div>normal</div>
<div>normal</div>
<div>normal</div>
<div>NOT normal</div>
</section>

Related

Is the CSS [attribute="value"] Selector unnecessary? [duplicate]

This question already has answers here:
Select elements by attribute in CSS
(6 answers)
Closed 3 years ago.
I'm taking one of the edX classes on CSS and they've included:
[class*='example'] { background-color: orange; }
in the CSS stylesheet. Not familiar with that type of an attribute, so I looked it up. Essentially it just adds a style to anything using a specific class [(or id), depending on the specific attribute]. Why wouldn't you just add:
background-color: orange;
to the appropriate class, or id, and be done with it? Is there a significant purpose to this type of attribute that I'm missing?
The * in [class*='example'] is a selector that retrieves all elements that contains example in the class-name and not just elements with the class-name example.
So [class*='example'] will target all of the following:
<div class="iamanexample"></div>
<div class="example"></div>
<div class="whereisyourexample"></div>
Whereas .example or [class='example'] will only target the second element <div class="example"></div> from the above three.
Other attribute selectors in CSS includes the:
~ selector: This selector retrieves all elements whose targeted attribute's value contains the exact queried value. This selector can include multiple values in the form of a whitespace-separated list of words.
| selector: This selector retrieves all elements whose targeted attribute's value is exactly the queried value or begins with queried value immediately followed by a hyphen.
^ selector: This selector retrieves all elements whose targeted attribute's value starts with the queried value.
$ selector: This selector retrieves all elements whose targeted attribute's value ends with the queried value.
Check and run the following Code Snippet for a practical example and explanation in the code comments on how each of the above selector works:
/* all elements whose abc value contains "ment" */
div[abc*="ment"] { font-weight: 700; }
/* all elements whose abc value is exactly "element-1" */
div[abc~="element-1"] { color: blue; }
/* all elements whose abc value is exactly "element" or begins with "element" immediately followed by a hyphen */
div[abc|="element"] { background-color: green; }
/* all elements whose abc value starts with "x" */
div[abc^="x"] { background-color: red; }
/* all elements whose abc value ends with "x" */
div[abc$="x"] { background-color: yellow; }
div { margin: 5px 0px; }
<div abc="element-1">Hello World!</div>
<div abc="element-2">Hello World!</div>
<div abc="xElement1">Hello World!</div>
<div abc="xElement2">Hello World!</div>
<div abc="element1x">Hello World!</div>
<div abc="element2x">Hello World!</div>

Pass a value from HTML to CSS

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

What is the different between [att|=val] and [att~=val] in css

I am facing very difficulty to understand these two different attribute in CSS [att|=val] and [att~=val]. Can anyone simply give me explanation for it
thanks
[attr|=val] matches a word in val in any form, so [class=div] would match .my-div, .div, but not .mydiv.
[attr~=val] matches a complete word in val, so [class~=div] would match .div, but not .mydiv or .my-div.
Example:
HTML
<div id="myDiv"></div>
<div id="myDiv2"></div>
<div id="new-div"></div>
CSS
div[id|=myDiv] {
/* Matches the first div */
}
div[id|=my]{
matches first two divs
}
div[id|=new]{
/* Matches second div - the hyphen counts as a word separator */
}
div[id~=Div]{
/* Matches nothing - "Div" is not a separate word */
}

CSS Dot Notation Naming Convention

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>

html/css what do elements with multiple dots mean

If I want multiple css classes applied, I use <div class = "c1 c2 c2">
I am looking at some code.
What does <div class = "c1.c2.c3"> mean?
The code that you have is correct, however you don't need the dots in your second <div> element (<div class='c1.c2.c3'></div>). (Unless you actually have an element that is explicitly named c1.c2.c3, which might cause some issues with CSS style declarations, unless you escape the leading slashes)
The dots are referring to CSS style rules, indicating an element has multiple classes, or in this case, classes c1, c2 and c3.
.c1.c2.c3
{
//Styles an element that has classes c1, c2 and c3
}
.c1.c2
{
//Styles an element that has classes c1 and c2
}
whereas with spacing, it refines the scope:
.c1 .c2 .c3
{
//Styles an element that has class c3 within an element c2,
//within an element c1.
}
Example of both cases
<div class = "c1.c2.c3"> means exactly what it looks like: the class name of this div element is c1.c2.c3. The CSS selector for it would look like this:
.c1\.c2\.c3 {
// styles here
}
This is very different from the CSS selector for <div class="c1 c2 c3">, which looks like this:
.c1.c2.c3 {
// styles here
}