I have the following HTML and CSS selector chain:
<div className="form-group">
<div class="control-custom-checkbox position-relative">
<input type="checkbox" class="custom-input" id="check1" checked>
<label className="custom-label" htmlFor="check1"></label>
</div>
</div>
.control-custom-checkbox .custom-input:checked~.custom-label::after { }
Next I added another div into the HTML:
<div class="form-group">
<div class="control-custom-checkbox position-relative">
<div class="required">
<input type="checkbox" class="custom-input" id="check1" checked>
</div>
<label class="custom-label" htmlFor="check1"></label>
</div>
</div>
I wrapped the markup in a new <div class="required"> and my styles broke. How should I change my CSS selector?
To keep it work, how it was before another div, you didn't need to change anything in your selector - it still will work and target needed HTML element.
You can check it there: https://codepen.io/anon/pen/BELXqW
The problem was your use of the 'sibling selector' in your CSS selector (~).
This requires that your .custom-label element be a sibling (i.e. next to each other within the DOM tree) of the .custom-input element. When you added the extra div it broke that relation (they were no longer 'next to' each other) so it broke your styling. (The fact that the div had the required class is irrelevant).
There aren't one size fits all fixes for this kind of issue but the safest fix would probably be to adjust the HTML so that they continue to be siblings.
<div class="form-group">
<div class="control-custom-checkbox position-relative">
<div class="required">
<input type="checkbox" class="custom-input" id="check1" checked>
<label class="custom-label" htmlFor="check1"></label>
</div>
</div>
</div>
(Or, as suggested in a comment, just add required onto an existing wrapper.)
If, however, that is not a possibility for some reason. You may be able to get away with removing the sibling selector requirement. E.g.
.control-custom-checkbox .custom-label::after {
/* Your CSS here */
}
Of course that selector may have been put there for a reason and removing it may have unintended side effects, especially if this will affect a large codebase. You will have to judge for yourself if it is safe to remove that sibling selector. I imagine it should be fine if .control-custom-checkbox always contains HTML structured just like your example, but there's no way to be sure without knowing more about the project.
Related
I have the following code:
<label class="el-checkbox el-transfer-panel__item"><span class="el-checkbox__input"><span class="el-checkbox__inner"></span><input type="checkbox" aria-hidden="false" class="el-checkbox__original" value="6" aria-labelledby="checkbox_5" id="checkbox_5"></span><span class="el-checkbox__label"><span>Total amount due</span><!----></span></label>
Every time I move my keys over it, the speech viewer shows blank. I tried many ways to fix it but its always showing the blank
The issue here is in how you are using aria-labelledby. This property should point to the ID of something which describes the item. In your code, you are pointing the element at itself which doesn't give it any details to work with.
The <label> property is what a screen-reader would refer to and that requires a for="" value (which your markup doesn't have). The code below illustrates a better way to approach this for accessibility.
<label for="checkboxID">
<div class="el-checkbox__input">
<div class="el-checkbox__inner"></div>
<input type="checkbox" name="checkboxName" id="checkboxID"> <span class="el-checkbox__label">Total amount due</span>
</div>
</label>
I have swapped the <span> tags for <div> because span tags should only be used for inline elements and shouldn't be used to wrap around block-level elements (such as the <input>).
Here's an example from the MDN of how you could use aria with a checkbox:
<span role="checkbox" aria-checked="false" tabindex="0" aria-labelledby="tac"></span>
<span id="tac">I agree to the Terms and Conditions.</span>
I have a HTML document with the abbreviated HTML content:
<div class="list">
<form name="signupForm">
<label class="item item-input">
<input>
</label>
<label class="item item-input">
<input>
</label>
<label class="item item-input">
<input>
</label>
<label class="item item-input">
<input>
</label>
<label class="item item-button">
<input class="button button-block button-positive">
</label>
<label class="item item-button">
<input class="button button-block button-signup">
</label>
</form>
</div>
My expected behavior is that the CSS selector .item.item-input:last-of-type will grab the 4th label element and the last .item.item-input element of the form parent.
What am I doing wrong?
:last-of-type matches an element which is the last element of its type (tag) within its (first-level) parent, period. It doesn't know or care about what other selectors you may have combined, including class selectors such as .item-input, or anything else.
There is no straightforward way in CSS to accomplish what you want, which could be expressed as :last-of-selector. Some alternatives that have been suggested include
Wrap the first four elements in a separate div, so you can do :last-of-type within it.
Have somebody (server, local JS) mark the element you want with a specific class, and refer to it.
Other hacks, such as hard-wiring the number of extra elements at the end that you want to skip, and use :nth-last-of-type.
Give the elements in question a different tag, if you can so manage, and then you can use last-of-type.
Apparently :last-of-type (from the MDN Docs) can only be used with namespace and type selectors (tag name selectors like input).
I suggest changing your HTML structure to wrap the .item-input elements in a <div>. Alternatively, I have also seen a .last class manually added to substitute the pseudo-selector.
Finding the .class:last-of-type is not possible. The :last-of-type CSS pseudo-class represents the last sibling with the given element name in the list of children of its parent element. The correct syntax is element:last-of-type
You might be interested in :nth-last-of-type(n), you could then use the following selector to target that element.
label:nth-last-of-type(3) { style properties }
The :nth-last-of-type(n) selector matches every element that is the nth child, of a particular type, of its parent, counting from the last child.
However, you'll need to use Javascript if you can't edit the markup and the number of items isn't fixed.
I'm wondering if there is a CSS selector to select any label which refers to an input type checkbox.
<label for="checkbox_1">First checkbox</label>
<input type="checkbox" name="checkbox_1" value="1">
so what works easily:
label[for='checkbox_1'] { /* styles */ }
but then I have to repeat this for every label which refers to a checkbox.
I would like to do something like:
label[type='checkbox'] { /* styles */ }
Any thoughts?
You can use the selector that selects all LABELS with the type attribute starting with the word "checkbox":
label[type^='checkbox']
More information about attribute selectors here: http://www.w3.org/TR/css3-selectors/#attribute-substrings
This is currently not possible with pure CSS, as far as I know. You do have a couple of options for workarounds, though:
The [attribute^='value'] selector
This will work if your labels actually start with the same identifier/word when associated with checkboxes, similarly to the code example you provided.
Example:
HTML
<label for='chckbx'>Foobar</label>
<input type='checkbox' name='chckbx_1' value='1' />
CSS
label[for^='chckbx']{/* styles */}
Writing your HTML in a certain way
This will work if you already have your <label>s and their associated <input />s in their own container, or if you can modify your HTML to be that way. The trick is to select the checkbox element's container via CSS, and then style it's child <label>s.
Example:
HTML
<div class='checkboxContainer'>
<label for='foo'>Foobar</label>
<input type='checkbox' name='foo' value='1' />
</div>
CSS
.checkboxContainer > label{/* styles */}
Using JS
I can write a simple code example to do this with JavaScript(/jQuery), if you want me to.
I have this HTML and CSS
http://jsbin.com/uciya5/3/edit
where the problem is that the radio buttons are treated as individual elements and therefore inherent the properties of class="cellData". Notice how wide the radio buttons are spaced vertically.
<div class="cellData">
<input name="ctype" value="individuel" type="radio" checked/> Individuel <br>
<input name="ctype" value="course" type="radio" /> Course </div>
</div>
Is it possible to control this vertical spacing of the radio buttons, or perhaps wrap a DIV around them to protect them?
Update
Removed template tags.
You could add another class to the div containing radio buttons:
<div class="cellData cellRadios">
with CSS (similar to this):
.cellRadios { line-height: 1 }
See: http://jsbin.com/uciya5/2
Provided that in your CSS you define .cellRadios after .cellData, the line-height from .cellRadios will be the one that's applied.
I'd probably also change .cellRadios to a better name.
If you prefer it, you could instead wrap the radio buttons in an extra div, as you suggested in your question.
<div class="cellData">
<div class="cellRadios">
<input name="ctype" value="individuel" type="radio" <TMPL_VAR IN>/> Individuel
<br>
<input name="ctype" value="course" type="radio" <TMPL_VAR CO>/> Course
</div>
</div>
You could delete this from the CellData stye: line-height:4em
You could also try using a table, it would be a lot simpler.
I have a very simple page like this
!!### apparently I cant add link to my page on jsbin since new users aren't allowed to add links.
I want to have certain amount of gap between different options provided to the user (say 15px).
Code I have is following:
<div id="question" >
What month is it?
<div style="padding-right: 15px;" id="options">
<input type="radio" name="question1" />Jan
<input type="radio" name="question1" />Feb
<input type="radio" name="question1" />May
<input type="radio" name="question1" />Dec
</div>
</div>
I thought that adding padding to the right will add padding to each of the radio buttons inside div id options. However, it is only adding padding to the whole div.
What is the bes way to handle this?
You can add the following rule:
div#options input { padding-right: 15px }
It will add padding to the right of each "input" element under the div with the id of "options"
UPDATED: In the sample, an "id" is being used several times. Id's must be unique, so classes would be more appropriate. See the following example:
div.options input { padding-right: 15px; }
<div class="options">
<input type="radio">...
The class can be reused for other elements that you'd like to share the same style.
Your code is asking the browser to place 15px of padding on the right of the DIV so you need to be more specific with your CSS declaration:
#options input { padding-right:15px; }
If you place that between style tags or in a style sheet, it should work out just how you want it.
I think the root of the problem is in the HTML not so much the CSS.
Your HTML is not as good/helpful as it could be. You are presenting a list of months, so mark them up using a list:
<ol id="options" class="formList">
<li>
<input type="radio" name="question1" />Jan
<li/>
....
</ol>
A side effect of this now being nice semantic HTML is that it gives you all the correct hooks for your styling. Each part of the form is in it's own element making applying CSS much easier - to add space around the list items use something like:
.formList li {margin:15px;}
//off topic:
You should really add label elements to you markup too. Using label elements in forms explicitly associates the text label of a form element with that form element, making the site more accessible and usable - a user can click on the text to activate the radio button which gives them a bigger target making your forms nicer and your users happier.
<label><input type="radio" name="question1" />Jan</label>
or
<input type="radio" id="radio1" name="question1" /><label for="radio1">Jan</label>
The thing to remember is that an inline style will apply to the element in which tag it is defined. To affect the inputs you'd need to target them directly (demo: 1) by either adding a class to them, target all inputs (demo: 2) or, as jthompson suggests, target those inputs that are descendants of the particular div (see jthompsons' answer).
`input {padding-right: 15px; }`, or
`input[type="radio"] {padding-right: 15px; }` // this is CSS3 only, I think.
add `class="q1-radio-inputs"` and use the CSS `.q1-radio-inputs {padding-right: 15px; }`
It's also worth noting that using inline styles doesn't make much sense, except where it needs to override a particular style one time only, it's always (so far as I can tell) wiser to use an external sheet, in order for caching (if nothing else) and for making it slightly easier to affect all styles when redesigning/reworking the site.
And, as an addenda, styles are applied in the following order:
inline-stlyes override styles defined in the header, which in turn override external stylesheets. Unless a style is defined with the !important marker, in which case it is not overridden (all being well).
The following (sort of) helps: http://www.w3.org/TR/CSS2/cascade.html
Edited in response to comments:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<style type="text/css" media="screen">
.div#options input { padding-right: 15px }
</style>
</head>
<body>
<div id="question" style="padding-bottom: 15px">
What day is it today?
<div id="options">
<input type="radio" name="question1" />Sunday
<input type="radio" name="question1" />Monday
<input type="radio" name="question1" />Saturday
<input type="radio" name="question1" />Tuesday
</div>
</div>
<div id="question" >
What month is it?
<div id="options">
<input type="radio" name="question1" />Jan
<input type="radio" name="question1" />Feb
<input type="radio" name="question1" />May
<input type="radio" name="question1" />Dec
</div>
</div>
</html>
If the html, above, remains representative of your site (as linked in the comments to this answer), the problem may well be:
.div#options
the period is used to indicate a class name, the pound '#' is used to indicate a div name, and only one or the other can be used at one time:
div.options /* is fine, indicating a 'div' of class-name 'options' */
div#options /* is also fine (and both within the same document is, also, fine) indicating a div of id-name 'options' - an id is unique, and can be used only *once* per document */
.div#options /* could be fine, but appears to be targeting an element of id-name 'options' within an element of class-name 'div,' which is not found within your document. */