I'm trying to do a sort of pure html/css tabs system. I have
<div>
<input class="tab1" type="radio" checked/>
<input class="tab2" type="radio"/>
</div>
<div class="content">
<div class="tab-1">
</div>
<div class="tab-2">
</div>
</div>
And my css
.content > div {
opacity:0;
}
input.tab1:checked ~ .tab-1, input.tab2:checked ~ .tab-2 {
opacity: 1
}
However the tilde ~ isnt working as its supposed to (because the divs aren't exactly a sibling) - How can I get the css to sort of work across to other nodes? Is there a way of 'saying' and in css?
You would have to go up one level and you cannot do that in CSS as there is no parent selector in CSS. You might want to read this article: why we don't have a parent selector in CSS (there will be a parent selector in CSS4, however)
What you can do:
Option 1: change your HTML:
.a
<input class="tab1" type="radio" checked/>
<input class="tab2" type="radio"/>
<div class="content">
<div class="tab-1"></div>
<div class="tab-2"></div>
</div>
and use input.tab1:checked ~ .content .tab-1
.b Try a structure like described here: http://css-tricks.com/functional-css-tabs-revisited/ - basically, the idea is that you don't make a group of tabs and a group of tab contents, but you group each tab with its corresponding content.
Option 2: use JavaScript (which goes against the idea of a pure CSS tab system, it's true)
Important note: keep in mind that setting opacity < 0 on a parent node makes all the children have the same opacity value and there is nothing you can do to change that (except setting the opacity of the parent to 1 again :P ).
Use a , instead of a ~.
Check out the list of all CSS Selectors:
W3 CSS Selectors
You can't do this with pure CSS. There is no relation between tab1 and tab-1.
I believe this is taken from jQuery tabs markup? You are probably better off sticking to using jQuery tabs than trying to do it this way.
Sadly you cannot, as there is no CSS way to travel up the hierarchy. You will have to do this with Javascript.
Related
How to create a css selctor for a checkbox with :: before selector. I want to create css selector of a radio button .
I am using the selector for eg: [data-model-cid="c279"]>label in firepath and it shows me the element.However in the test script its unable to get the element.In google console when I try to get the element by $('[data-model-cid="c279"]>label') it is unable to fetch the element.So I think the :: before selector needs to be added in the selector to search the element. The Html is given below.How to write a selector with the :: before ?
<div class="radio" data-model-cid="c279">
:: before
<input id="pac-item-care-plan-4 years-45924345-view261" class="js-care-plan-update" type="radio" value="45924345" name="pac-item-care-plan-view261" data-analytics-id="cpradio" data-groupid="472AB3B8BDAD4A4AA78A7CF484FFA7E4" data-offerid="F259143E766145DF8F50DF46F9EC10B7" data-action="add" checked="checked"/>
<label class="no-wrap" for="pac-item-care-plan-4 years-45924345-view261">
:: before
4 years
<strong>(+ $39)</strong>
</label>
</div>
From what I know you cannot do this, mainly because an input is an empty tag (self-closing) and it basically has no content.
within a <div> element if you look at the following example
<style>
.my-div::before {
content: 'before';
}
.my-div::after {
content: 'after';
}
</style>
<div class="my-div"></div>
You'll notice in the chrome devtools you'll get something like this
<div class="my-class">
::before
::after
</div>
This is possible because the ::before and ::after psuedo-elements live inside the div tag, if you add another child div with a height and a background you'll see the words before pop up above the child div and after pop up after the child div - this is because they are basically children but inserted in a different way (through CSS).
The following is what you're looking for the browser to do
<input type="radio"></input>
to
<input type="radio">
::before
::after
</input>
But this is wrong already since the input tag shouldn't have any content in it. Most browsers will probably ignore this or even try to fix your markup for you but you simply won't be able to get this working.
From the documentation on MDN
"The :before and :after pseudo-elements elements interact with other
boxes... as if they were real elements inserted just inside their
associated element."
A correct <input> tag looks like this:
<input type="radio" />
And since this doesn't have any room to place the ::before and ::after in it won't work. You'll have to find an alternative solution unfortunately.
So i have this situation:
<div class="wrapper">
<div class="optional">
<h3>one</h3>
<textarea/>
</div>
<div class="optional">
<h3>one</h3>
<textarea/>
</div>
</div>
inside wrapper there are more elements.
Sometimes I have 1 optional and other times more than once.
I want to add different
.optional{textarea{ height: 150px; }}
.optional:only-of-type{textarea{ height: 75px; }} //sass
but sadly this is not working (I know.. only on elements, not classes).
So - is there a way without JS to give a different height to the textarea when there is only one?
As you have stated, :only-of-type doesn't scope itself to classes.
Since CSS doesn't yet provide an analogue of *-of-type for arbitrary selector sub-matching, and additionally CSS does not provide a way to determine if an element is the only grandchild of its type (or the only grandchild, period), you will have to do this with JS.
So, I have my solution now -
Instead of div.optional I Just chose an other rare element (section), and then I can select only-of-type again.
Simple but ugly :)
The question I want to ask is, "Is it possible/good practice to refer to a child of an element that is not a direct child?"
For instance, if you have HTML like this:
<form class="formation">
<p>
<span>
<input class="phone input">
</span>
</p>
<p>
<span>
<input class="text input">
</span>
</p>
</form>
And you want to refer in CSS to the inputs only in that particular form, so you call the class of the form followed by the class of the inputs without referring to the elements in between, like this:
.formation .input {
width: 10px;
}
will this work properly?
I tend to think I've done this already on projects and it has worked properly but usually I refer to all the children in between (because I don't go that deep). But I'm currently working on a media query for a wordpress site that doesn't seem to be respecting this rule. Is this bad practice? Or is this downright incorrect? Thanks for all your help!
Yes, it is not only possible but also advisable to do so. Choose your selectors for your css rules as lean as needed to reduce dependency on your markup structure. This is not only wise for performance reasons, it also saves you quite some work in case your markup should ever change, e.g. later on you notice the span is not needed any longer and you remove it to keep your markup as clean as possible. In case you used the full DOM path to your .input you will then also have to adjust your css selectors. Same if for any reason in the future your <p> should become a <div>.
Just make sure you give the rules as much DOM context as necessary to not apply your rules to the same classed element in other contexts (if you have any at all, and if you want to apply a different set of style rules for it).
Yes, it'll work fine. What youv'e got with .form .input allows for any number of intermediate nodes between the two classes.
If you'd had .form > .input, then your CSS wouldn't match at all. > is the "immediate descendant" selector, so
.form .input { color: green }
.form > .input { color: red }
<div class="form">
<div class="input">This is red</div>
<div class="whatever">
<div class="input">This is green</div>
</div>
</div>
I have a code snippet:
<fieldset class="shareMe"><br />
<input type="checkbox" id="share_me" name="share_me" value="1" {if $default_share_pref}checked="checked"{/if} onclick="if (this.checked) { var perms = 'publish_stream'; fb_login_cached(function(response){ if (!response.perms.match(new RegExp(perms))) $('share_me').checked = false; }, perms); }"/>
<label for="share_me">Post this question to my friends on
<span class="">
<a class="fb_button fb_button_small">
<span class="fb_button_text">Facebook</span>
</a>
</span>.
</label>
</fieldset>
I want to change the text in <label for .. > field via CSS.
I know i can do it by placing duplicate copy of this snippet and use css to toggle. However, i want to do it minimum code change. May be using some CSS trick to change <label for..> text and not affecting the code inside <label for...> at all.
You can't change text with CSS. The exception to this rule is the ::before and ::after psuedo-elements. In theory you could use classes to toggle the text like so:
label[for="share_me"]:before{content:'Post this question to my friends on '}
label[for="share_me"].othertext:before{content:'Some other text!'}
However, just because you can doesn't mean you should. It's an accessibility nightmare, and can you imagine coming back later and trying to work out where the text is coming from if not from the HTML?
Following the example at https://blog.escapecreative.com/how-to-replace-text-with-css/, this is what worked for me:
label[for="donate-choice-14724"]{
visibility: hidden;
position: relative;
}
label[for="donate-choice-14724"]:after{
visibility: visible;
position: absolute;
top: 0;
left: 0;
content:'Make this donation monthly';
}
You can only change the content of :before and :after pseudoelements with CSS. Ali Bassam's answer below shows a 'hacky' way to display the pseudoelements content over the parent so that you can control it. Problems with this solution include, well, how hacky it seems and also the limited IE support of pseudo elements. But that might not be problematic for your project.
Another thing to consider is that you'd have limited control over the toggle with CSS. Your two options are media queries and the familiar pseudo classes. If your toggling needs go beyond what those guys can do, you'd do best turning to Javascript.
suppose I have a simple container which have three element:
<div>
<span>hello world</span>
<input id="ipt" type='test'>
<input id="rge" type='range'>
</div>
but it show the last #rge always higher then the other two,
like this (view in chrome):http://jsfiddle.net/hh54188/SYNPa/1/
Why this happened?How can I solve this problem without adding other html element?just work with css
You should add the following CSS to your #rge definition:
vertical-align:middle;
This aligns the element centred vertically on the line.