I have a html structure like this:
<kendo-label>
<label class="k-label"></label>
</kendo-label>
<kendo-textbox class="k-input-solid"></kendo-textbox>
If I click in the textbox (focus), the label should have a different color. For this I have this selector, which works well:
kendo-label:has(+ .k-input-solid:focus-within) .k-label {
color: var(--blue-05);
font-weight: 600;
}
Now, I have a new structure with a div like this:
<kendo-label>
<label class="k-label"></label>
</kendo-label>
<div>
<kendo-textbox class="k-input-solid"></kendo-textbox>
</div>
This div is inserted by the component provider, so I have to accept it as it is.
The question is, how can I now achieve the same result?
I tried this:
kendo-label:has(+ div):has(+ .k-input-solid:focus-within) .k-label {
color: var(--blue-05);
font-weight: 600;
}
But the label isn't selected.
With this I get selected the label:
kendo-label:has(+ div) .k-label {
color: var(--blue-05);
font-weight: 600;
}
But I need this rule only, if the textbox has focus. How should I attach this rule too?
Put all the requirements into the same has function:
kendo-label:has(+ div .k-input-solid:focus-within) .k-label {
color: var(--blue-05);
font-weight: 600;
}
.test:has(+ div .k-input-solid:focus) .k-label {
color: blue;
font-weight: 600;
}
<div class="test">
<label class="k-label">test</label>
</div>
<div>
<input class="k-input-solid"/>
</div>
Related
Here is my little tryings in this, tried using checked and target but did'nt work out
.label-test {
font-size: 13;
color: #6b7072;
}
.label-test:active {
color: #fff;
text-transform: capitalize;
}
<input type="checkbox" class="input-test" id="work">
<label for="work" class="label-test">all works</label>
I'm not entirely clear on the objective, but if it is to apply the text-transform: capitalize when the checkbox is checked, then the following CSS will do that:
input.input-test:checked + label.label-test {
text-transform: capitalize;
}
This works by changing the styling of the label after the input when the input is checked.
Here's a working snippet showing it in action:
.label-test {
font-size: 13;
color: #6b7072;
}
.label-test:active {
color: #fff;
text-transform: capitalize;
}
input.input-test:checked + label.label-test {
text-transform: capitalize;
}
<input type="checkbox" class="input-test" id="work">
<label for="work" class="label-test">all works</label>
I have a .header div with a span maindomain and a div otherdomains inside of it:
<div class="header"><span class="maindomain">LatestFooty.co.uk</span> is currently available for sale, along with:
<div class="otherdomains">
LatestFootie.com<br>
LatestFootie.co.uk
</div>
</div>
I'm trying to target the is currently available for sale, along with:, without touching the contents of .maindomain or .otherdomains. I understand that the best approach to this might be to wrap it in a span and target that instead, but at this point I'd like to figure out why I can't get the :not pseudo-class working.
Here is what I have:
#media (min-width:300px) and (max-width:450px) {
.header:not(.maindomain):not(.otherdomains) {
font-style: italic;
}
}
As far as I can tell, the syntax is correct, and I don't think it's a specificity issue because !important doesn't make a difference. What am I doing wrong?
.header:not(.maindomain):not(.otherdomains) only targets elements which have the .header class and don't have the .maindomain and/or the .otherdomain class themselves.
Your rules currently say:
<div class="header"> is targeted
<div class="header maindomain"> is not targeted
<div class="header otherdomains"> is not targeted
<div class="header maindomain otherdomains"> is not targeted
But this is not what you want to do here obviously.
You cannot apply rules to the .header class depending on classes of its children with CSS alone.
There's an approved answer to your question here which might guide you in the right direction (using JavaScript or jQuery in that case).
You will need two selectors:
.header {
font-style:italic;
}
.header .otherdomains,
.header .maindomain {
font-style:initial;
}
/* OR
.header * {
font-style:initial;
}
*/
<div class="header"><span class="maindomain">LatestFooty.co.uk</span> is currently available for sale, along with:
<div class="otherdomains">
LatestFootie.com<br>
LatestFootie.co.uk
</div>
</div>
I'm trying to target the "is currently available for sale, along with:", without touching the contents of .maindomain or .otherdomains.
You can't target anonymous elements in CSS.
CSS rules need a "hook" in the HTML to attach to. That hook is an HTML tag. Without the tag, CSS has nothing to target. This concept applies across box models.
From MDN:
An anonymous box is created when there is not an HTML element to use for the box. This situation happens when, for example, you declare display: flex on a parent element, and directly inside there is a run of text not contained in another element. In order to fix the box tree, an anonymous box is created around that run of text. It will then behave as a flex item, however, it cannot be targeted and styled like a regular box because there is no element to target.
(emphasis mine)
Everything is in the demo itself, the JavaScript is for demo purposes.
Demo
const lnx = [...document.links];
lnx.forEach(lnk => lnk.addEventListener('click', viewHTML));
function viewHTML(e) {
const link = e.target;
const headers = document.querySelectorAll('.'+this.dataset.tag);
headers.forEach(hdr => {
if (!hdr.matches('.hide')) {
link.className = 'off';
let str = hdr.outerHTML;
let txt = document.createElement('div');
txt.className = 'txt';
hdr.insertAdjacentElement('afterend', txt);
hdr.nextElementSibling.insertAdjacentText('beforeend', str);
hdr.classList.add('hide');
} else {
link.className = '';
hdr.classList.remove('hide');
hdr.nextElementSibling.remove();
}
});
}
body {
font: 400 2.5vw/1.5 Consolas
}
[class^=header] {
font-family: Arial;
}
/* Header (OP)
Selector fails -- :not() is prefixed incorrectly
.header:... means .header is targeted
.header :... means the descendants of .header is targeted
There is no .header.A, .header.B, nor .header.A.B
so .header without .A and/or .B will have everything in italics
*/
.header:not(.A):not(.B) {
font-style: italic;
}
/* Header 1
Best solution with no extra HTML tags:
Assign font-style: normal...
directly (.C1, .D1)
or by class (.N)
*/
.header1 {
font-style: italic;
}
.C1,
.D1,
.N {
font-style: normal;
}
/* Header 2
Using :not() needs extra HTML tag:
Wrap second textnode in an inline or inline-block tag
As content of a descendant tag, the text can be targeted
*/
.header2 *:not(.E):not(.F) {
font-style: italic;
}
/* Header 3
Smart solution with extra HTML tag:
Wrap second textnode in <i> or <em>
*/
.header3 {
/* no styles needed */
}
/* Header 4
Slickest solution with least HTML:
Wrap text that needs italics in <i> and then style lines with CSS
*/
.header4 {
white-space: pre-line;
}
/* For Demo Purposes */
.dash {
border-style: dashed;
}
.edge {
border-style: ridge;
border-width: 3px;
}
summary:hover {
color: lime;
background: #000;
cursor: pointer;
}
summary + u {
display: inline-block;
text-decoration: none;
white-space: pre-line;
}
code {
color: green;
background: rgba(0, 0, 0, 0.2);
white-space: pre;
}
summary + code {
display: block;
}
a {
display: block;
text-decoration: none;
text-align: center;
}
a:link,
a:visited {
color: cyan;
background: #000;
}
a:hover,
a:active {
color: blue;
background: none;
}
a::before {
content: 'View .'attr(data-tag);
}
a.off::before {
content: 'Hide .'attr(data-tag);
}
a::after {
content: ' HTML';
}
.hide {
display: none;
}
.txt {
color: blue;
background: rgba(0, 0, 0, 0.2);
white-space: pre;
}
<main>
<hr class='edge'>
<details><summary>Header (OP)</summary>
<u>Selector fails -- :not() is prefixed incorrectly
.header:... means .header is targeted 👎
.header<code>␣</code>:... means the descendants of .header is targeted 👍
There is no .header.A, .header.B, nor .header.A.B so
.header <em>without</em> .A and/or .B will have everything in italics</u></details>
<details><summary>CSS</summary>
<code>.header:not(.A):not(.B) {
font-style: italic;
}</code>
<a href='#/' data-tag='header'></a>
</details>
<hr>
<div class='header'>
<span class="A">LatestFooty.co.uk</span> is currently available for sale, along with:
<div class="B">
LatestFootie.com<br> LatestFootie.co.uk
</div>
</div>
<hr class='edge'>
<details><summary>Header 1</summary>
<u>Best solution with no extra HTML tags:
Assign <code>font-style: normal</code>...
directly (.C1, .D1)
or by class (.N)</u></details>
<details><summary>CSS</summary>
<code>.header1 {
font-style: italic;
}
.C1,
.D1,
.N {
font-style: normal;
}</code>
<a href='#/' data-tag='header1'></a>
</details>
<hr>
<div class="header1">
<span class="C1">LatestFooty.co.uk</span> is currently available for sale, along with:
<div class="D1">
LatestFootie.com<br> LatestFootie.co.uk
</div>
</div>
<hr class='dash'>
<div class="header1">
<span class="C2 N">LatestFooty.co.uk</span> is currently available for sale, along with:
<div class="D2 N">
LatestFootie.com<br> LatestFootie.co.uk
</div>
</div>
<hr class='edge'>
<details><summary>Header 2</summary>
<u>Using :not() needs extra HTML tag:
Wrap second textnode in an inline or inline-block tag
As content of a descendant tag, the text can be targeted</u></details>
<details><summary>CSS</summary>
<code>.header2 *:not(.E):not(.F) {
font-style: italic;
}</code>
<a href='#/' data-tag='header2'></a>
</details>
<hr>
<div class='header2'>
<span class="E">LatestFooty.co.uk</span> <span>is currently available for sale, along with:</span>
<div class="F">
LatestFootie.com<br> LatestFootie.co.uk
</div>
</div>
<hr class='edge'>
<details><summary>Header 3</summary>
<u>Smart solution with extra HTML tag:
Wrap second textnode in <code><i></code> or <code><em></code></u></details>
<details><summary>CSS</summary>
<code>.header3 {
/* no styles needed */
}</code>
<a href='#/' data-tag='header3'></a>
</details>
<hr>
<div class='header3'>
<span class="G">LatestFooty.co.uk</span> <i>is currently available for sale, along with:</i>
<div class="H">
LatestFootie.com<br> LatestFootie.co.uk
</div>
</div>
<hr class='edge'>
<details><summary>Header 4</summary>
<u>Slickest solution with least HTML:
Wrap text that needs italics in <code><i></code> and then style lines with CSS</u></details>
<details><summary>CSS</summary>
<code>.header4 {
white-space: pre-line;
}</code>
<a href='#/' data-tag='header4'></a>
</details>
<hr>
<header class='header4'>LatestFooty.co.uk <i>is currently available for sale, along with:</i>
LatestFootie.com
LatestFootie.co.uk
</header>
</main>
Sorry for the generically worded title, anyway, I have some simple HTML like so:
<div class="block flex-1 mx-4 relative w-1/2">
<div class="form-group label-floating">
<label class="control-label">Password</label>
<input class="form-control" placeholder="" type="password">
<span class="material-input"></span>
</div>
</div>
Now, whenver a person clicks the input, I am shrinking the label size like so:
With the following css:
&.label-floating {
&:focus-within {
& > .control-label {
top: 10px;
font-size: 11px;
line-height: 1.07143;
}
}
}
Now, my problem is, if the input is not empty and the user leaves the input, the label will return to the normal size. So I have tried things like so:
with the following css:
&.label-floating {
&:focus-within {
& > .control-label {
top: 10px;
font-size: 11px;
line-height: 1.07143;
}
}
& input:not(:empty){
& .control-label {
top: 10px;
font-size: 11px;
line-height: 1.07143;
}
& < .control-label {
top: 10px;
font-size: 11px;
line-height: 1.07143;
}
}
}
With no avail, so, my question is, is there a way to achieve what I want, with pure css?
edit: can someone please edit the OP to embed the images, please.
Updated with pure css:
.form-group {
margin-bottom: 1.5rem;
position: relative;
}
.form-group > .control-label {
color: #888da8;
}
.form-group.label-floating:focus-within > .control-label {
top: 10px;
font-size: 11px;
line-height: 1.07143;
}
.form-group.label-floating input:not(:empty) .control-label {
top: 10px;
font-size: 11px;
line-height: 1.07143;
}
You cannot target an input that contains a value without checking if the content is valid. You can, however, use a round-about way to check if the input has no value.
Your input has a placeholder attribute. The CSS selector :placeholder-shown will target inputs which are showing a placeholder; that is, inputs that have a placeholder attribute specified and are not empty.
You must therefore style the empty input's label.
.form-control:placeholder-shown ~ .control-label {
font-size: 20px;
color: red;
}
.label-floating:focus-within > .control-label,
.form-control ~ .control-label {
font-size: 11px;
color: blue;
}
<div class="form-group label-floating">
<input class="form-control" placeholder="" type="password">
<label class="control-label">Password</label>
</div>
Note that :placeholder-shown is not implemented in IE/Edge, despite being highly requested; there are, however, polyfills available.
I have a dropdown select element with car names and their available colors inside parentheses. I would like to be able to do something like this:
<select class="cars">
<option>Rolls Royce Phantom <span class="car-color">(silver)</span></option>
<option>Ferrari 488GTB <span class="car-color">(yellow)</span></option>
<option>Chevrolet Camaro <span class="car-color">(black)</span></option>
</select>
where
.cars {
color: black;
font-weight: bold;
}
.car-color {
color: grey;
font-weight: normal;
}
This code above is not working, unfortunately. How do I reach a desired effect?
You can't style option elements because it's rendered by the OS, not HTML. That is why it can't be styled via CSS.
Either you could use some plugins to reach what you are trying to do,
W3schools has a simple way to style the drop down, check it here.
You can use something like this
.carcolor{
color: grey;
}
$('<option>').val('india').text('india').attr('class','carcolor')
.appendTo('#groupid');
Try like below css , First example is for all option and second is for specific nth child, if you have multiple styles
.cars1,.cars2 {
color: green;
font-weight: bold;
}
.cars1 option{
color: red;
font-weight: normal;
}
.cars2 option:nth-child(2) {
color: red;
font-weight: normal;
}
<select class="cars1">
<option>Rolls Royce Phantom <span class="car-color">(silver)</span></option>
<option>Ferrari 488GTB <span class="car-color">(yellow)</span></option>
<option>Chevrolet Camaro <span class="car-color">(black)</span></option>
</select>
<br/><br/><br/>
<div></div>
<select class="cars2">
<option>Rolls Royce Phantom <span class="car-color">(silver)</span></option>
<option>Ferrari 488GTB <span class="car-color">(yellow)</span></option>
<option>Chevrolet Camaro <span class="car-color">(black)</span></option>
</select>
I don't understand why the text-decoration: none does not work in the following code. It fails to remove the underline of the word yes.
.button {
color: black;
text-decoration: none;
}
body {
font-family: 'Roboto', 'Microsoft JhengHei', sans-serif;
font-size: 24px;
}
<a href="www.example.com">
<div class="button" id="yes">
Yes
</div>
</a>
As you can see from the example below, the child can override the parent. This is contradictory to the problem above.
.b {
color: black;
}
.c {
color: yellow;
}
<div class="b">
<div class="c">
abc
</div>
</div>
By default the a tag has underline effect (using text-decoration:underline), So to remove this, you must remove from a tag not from its child element.
If you are talking like color values can be overridden from parent to child element but why not text-decoration?
This is because the text-decoration property doesn't inherit the style from its parent element but relies upon its own element.
Check w3c reference.