Button inside a label - html

I have a label with "for="the pointer to the checkbox input"" and as long as I know, this for can be added only for label. Therefore, I need to add inside of the label a <button>(I need it), but the click event isn't working properly - it doesn't check the checkbox the for is pointing to.
What are the possibilities I can use here if I must place <button> inside the label, with only html+css coding?
some code for example:
<input type="checkbox" id="thecheckbox" name="thecheckbox">
<div for="thecheckbox"><button type="button">Click Me</button></div>

It turns out you can make a <button> operate an input, but only if you put the <label> inside the <button>.
<button type="button">
<label for="my-checkbox">Button go outside the label</label>
</button>
<input type="checkbox" id="my-checkbox">
Although this contravenes the W3C specs:
The interactive element label must not appear as a descendant of the button element.
https://www.w3.org/TR/html-markup/label.html

You can do dis:
<label>
<button></button>
</label>
CSS
label {
cursor: pointer; // not necessary but probably a good idea.
display: block; // depending on your structure.
}
button {
pointer-events: none;
}
The display: block on label will only be necessary so that the bounding box of the label fully encapsulates it's children (the button in this case).

You can use transparent pseudo element that overlays the checkbox and the button itself that will catch mouse events.
Here's an example:
html:
<label>
<input type="checkbox">
<button class="disable">button</button>
</label>
css:
.disable{pointer-events:fill}
label{position:relative}
label:after{
position: absolute;
content: "";
width: 100%;
height: 100%;
background: transparent;
top:0;
left:0;
right:0;
bottom:0;
}

HTML:
<label for="whatev"
onclick="onClickHandler">
<button>Imma button, I prevent things</button>
</label>
JS:
const onClickHandler = (e) => {
if(e.target!==e.currentTarget) e.currentTarget.click()
}
Target is the click target, currentTarget is the label in this case.
Without the if statement the event is fired twice if clicked outside of the event preventing area.
Not cross browser tested.

The best solution is to style is like a button.
If you're using a CSS framework, like bootstrap, you can give the label classes such as btn and btn-default. This will style it like a button. You may need to adjust the css property of the line-height manually like so:
label.btn {
line-height: 1.75em;
}
Then, to get the on click styles as a button, add these styles:
input[type=radio]:checked ~ label.btn {
background-color: #e6e6e6;
border-color: #adadad;
color: #333;
}
This will take the input that is checked and give the next label element in the dom that has the class btn, bootstrap btn-default button clicked styles. Adjust colors as fit.

Related

How does css checkbox hack work?

I just came across the switch toggle button which is created only using css. It known as the checkbox hack.
For those who doesn't know what a checkbox css hack is, Please read it here
https://css-tricks.com/the-checkbox-hack/
I tried it out and it was working perfectly fine. But I didn't understand how this is working because we are not clicking on the checkbox.
So I have 2 questions
How is this working ?
Instead of absolute positioning I tried it with display: none;
It still worked. Does this method have any drawbacks?
The way it works is by using the <label> element. Any input element can (and usually should) have a label. You can tell the browser which label belongs to which label by using a for attribute, referring to the input's name:
<input name="myName" />
<label for="myName">Label</label>
Whenever you click the label, it focuses the input (or in case of checkboxes, toggles it).
The label and checkbox don't have to be near each other. You could add a few hidden checkboxes at the start or end of a document and place the labels anywhere on the page, and they'd still focus the input.
Hiding the checkbox through display: none could cause buggy behavior on certain browsers. Just hiding it from view by a position: absolute is safer.
You can bind labels to checkboxes/radios using the for= attribute. When this is set, clicking on the label toggles the checkbox. This is a standard HTML attribute.
You can hide the checkbox using display: none, but do test it to make sure that its value is still submitted with the form.
CSS is aware of the current checked state of a checkbox input
This awareness, in combination of siblings selectors such as + (immediate next sibling) and ~ (next sibling somewhere) allows styling different styles, for checked/unchecked states, to anything that comes after the input element. The key here is the word "after".
Basic example:
/* styles when checkbox is unchecked */
div{ border:2px solid blue; margin:10px }
div h3{ color:red; }
/* when checkbox is checked */
input:checked ~ div{ background:blue; }
input:checked ~ div h3{ color:gold; }
<input type=checkbox>
<div><h3>very<h3></div>
<div><h3>cool<h3></div>
As others have said (but is not a must) - HTML label element allows to interact with input elements, and in checkbox/radio types' case - it allows to toggle their checked state by clicking the label itself, which is "linked" to a specific input element by the for attribute:
<label for='x`>click</label>
and the id attribute no the linked input:
<input type='checkbox' id='x'>
For the method to work, the input element must to be placed before whatever element(s) it is intended to control via CSS.
In real-word use cases, one would often want to use the CSS-toggling features of a checkbox over next siblings, but to obscure the fact there is a checkbox involved. The best way is by applying the hidden attribute on the input, which only toggles off the rendering of the input, nothing else.
The example below showcase such use case for a simple accordion component:
Practical example: Accordion
.accordion{ width: 300px; border: 1px solid silver; }
.accordion label{ display:block; padding:1em; cursor:pointer; }
.accordion label:hover{ color:red; }
.accordion > div:not(:last-child){ border-bottom:1px solid silver; }
.accordion .more{ max-height:0; transition:.5s; color:green; padding:0 1em; overflow: hidden; }
/* checked toggled */
.accordion input:checked + .content{ background:#EEE; }
.accordion input:checked + .content .more{ max-height:200px; }
<div class='accordion'>
<div>
<input type='checkbox' id='checkbox_item_1' hidden>
<div class='content'>
<label for='checkbox_item_1'>Title 1</label>
<div class='more'>
<p>This is cool<p>
<p>Yes it is</p>
</div>
</div>
</div>
<div>
<input type='checkbox' id='checkbox_item_2' hidden>
<div class='content'>
<label for='checkbox_item_2'>Title 2</label>
<div class='more'>
<p>This is also cool</p>
<p>So much fun</p>
</div>
</div>
</div>
</div>
You can hide the checkbox with visibility: hidden; or opacity: 0; besides display: none; but i'm not sure which one is better.

How to hide label on radio checked using css

I have a checkbox in label tag like this.
<label class="duck duck1">
<input type="checkbox">
</label>
I want if i click on checkbox, label and checkbox both should be display:none without jquery.
I tried this.
.duck input[type=checkbox]:checked + label.checkbox {display: none;}
jsfiddle
unfortunately, as i said before: using css, you can only select an element that comes after the one you clicked, not before and not a parent.
you can work around that however. Have a look at the following code:
if you reconstruct your html to have the label after the checkbox, and add the animated classes to the checkbox as well, to align it with the label:
<div class="main">
<input type="checkbox" class="duck duck1 cb_1"></input>
<label class="duck duck1"></label>
</div>
you will be able to select both in the following way:
input[type=checkbox].cb_1:checked,
input[type=checkbox].cb_1:checked + label {
display: none;
}
here is a fixed Fiddle
(the .cb_1 class is only meant for the z-index to make checkbox appear above the lable, and to avoid other checkboxes on the page hide irrelevant labels)
UPDATE:
another workaround would be to create the label (or duck image sprite) using the :after pseudo selector:
.duck:after{
content:'';
width: 50px;
height: 50px;
position: absolute;
}
here is an example with the :after selector: Duck Fiddle

Change checkbox label css property with checkbox checked

I have the following html:
<label>
<input type="checkbox" value="cb_val" name="cb_name">
my checkbox text
</label>
With CSS I added a background-color to the <label> tag.
label { background-color:#333; color:#FFF; }
Now I'd liked to change the background color of the label when the checkbox is checked.
I know how to do it with javascript, but is there a way to to it just using CSS?
I have seen some solutions, but they use the adjacent sibling selector and only work when the label appears after the checkbox.
I still hope to fix this without javascript, does anyone have a clue?
UPDATE:
As I was afraid of, it cannot be done this way, so i must do it with JS, or achieve the same visual effect with a different HTML structure.
I want to set the background color of the label and the textbox in one go, so I can go with a solution where the checkbox is placed absolute on top of the label. Good point PlantTheldea!
Or I can apply the background color to the label and the checkbox both.
Thanks everyone!
You can achieve this with pure css like so,
<input type="checkbox" id="cb_1" value="cb_val" name="cb_name">
<label for="cb_1">
my checkbox text
</label>
With this css,
label { background-color:#333; color:#FFF; }
input[type="checkbox"]:checked + label {
background: brown;
}
JSFIDDLE
Keep in mind
The label has to be after the checkbox so you will need to style it around more to keep the same look you had.
Here is an option of styling it more to have the same appearance as you wanted, New fiddle. THIS DOES NOT involve positioning anything absolute, just some trickery.
You can't style the label itself directly via only CSS when the label is checked, but you can style a sibling of the checkbox.
http://jsfiddle.net/QdDpL/
HTML
<label>
<input class="check" type="checkbox" />
<span class="label-text">Checkbox</span>
</label>
CSS
label {
background: yellow;
}
label .label-text {
background: cyan;
}
label input.check:checked + .label-text {
background: lime;
}
You may also be able to fiddle with floats and padding to make the checkbox appear as if it was inside the .label-text span.
See the following links for browser support on the sibling selector:
http://caniuse.com/css-sel2
Alternately as another answer said, you can style the label if it is a sibling of the checkbox - but then just like my answer still would not contain the checkbox in the label.

Input placeholder using CSS only

I know there are lot's of questions regarding this query here but none of them provide the solution for me.
HTML
<input id="tb1" type="text" class="note" />
<br>
<p class="note1"> This is not done.</p>
CSS
p.note1:before{
content: "Note:";
}
tb1.note:before{
content: "Enter your number";
}
I am trying with above code and the variation as found on the web but none seems to work for input tag. It's working for p tag.
EDIT: I can't add value attribute to input tag and manage css for the desired result. It's the limitation of the system.
EDIT2: Forget about my css, is there any way that placeholder text is possible without using placeholder attribute and just with plain css for input type="text"
:before creates a pseudo-element that is the first child of the element matched.
The selected element MUST be a container tag. An empty tag like <input> doesn't have any children element.
If you can't edit your HTML code manually, you're still able to that by using JavaScript:
document.getElementById("tb1").setAttribute("placeholder", "Enter your number");
Update
If you want to achieve this by using CSS only, you need to have a container element wrapping your <input> (or come after it).
BUT It doesn't work correctly as placeholder do. You'll not able to check the value of <input> by CSS. If you write something inside the <input>, after blur event, the generated placeholder will be displayed over the <input> again.
HTML:
<label>
<input id="tb1" type="text" class="note">
</label>
CSS:
label {
position: relative;
}
label:after {
content: 'Enter your number';
position: absolute;
left: 5px;
top: 0;
color: #bbb;
}
#tb1 {
position: relative;
}
#tb1:focus {
z-index: 10;
}
JSBin Demo
It doesn't work for the simple fact that this:
<input id="tb1" type="text" class="note"></input>
is not valid. <input /> elements are not containers. As the spec notes, endtags are forbidden (and essentially ignored by the browser): http://www.w3.org/TR/html401/interact/forms.html#h-17.4
If you cant manipulate the html and use placeholder="". Use javascript to manipulate the placeholder. Every css approach is hack-isch anyway.
E.g. with jQuery:
$('#myFieldId').attr('placeholder', 'Search for Stuff');
I have found this method but not supported by all browsers:
#tb1.note:empty:before{
content: "Enter your number";
}
Note: you have forgot to place an id selector # tb1.note
see this link
EDIT:
Try this for starters: (Note: you'll need some js to detect if text has been entered in the input)
Apart from this - I don't think this there is a css solution for placeholder text on an input element without using the placeholder attribute.
FIDDLE
Markup
<div class="container">
<input />
<div class="fakePlaceholder">Some placeholder text</div>
</div>
css
.container
{
position: relative;
}
input
{
background: transparent;
}
input:focus + .fakePlaceholder
{
display: none;
}
.fakePlaceholder
{
color:gray;
position:absolute;
top: 3px;
left: 5px;
z-index: -1;
}
You can't use pseudo elements on an input tag - or any other non-container elements for that matter
From the Pseudo-Elements tag info:
you cannot use them (pseudo elements) with replaced elements (see
below) which do not have actual content. This is because the generated
content resides within the element.
...
Replaced Elements
Any element whose appearance and/or dimensions are determined by some
external resource is considered to be a replaced element. Some
pseudo-elements cannot be applied to replaced elements because they
have no "content" or get replaced with something (such as user
interface controls). Replaced elements include images (<img>), inline
frames (<iframe>), line breaks (<br>), horizontal rules (<hr>),
plugins (<object>), form elements (<button>, <textarea>, <input>, and
<select>), videos (<video>), audio sounds (<audio>), and canvases
(<canvas>). Any other element is considered to be a non-replaced
element.
Another way this can be accomplished, and have not really seen any others give it as an option, is to instead use an anchor as a container around your input and label, and handle the removal of the label via some color trickory, the #hashtag, and the css a:visited. (jsfiddle at the bottom)
Your HTML would look like this:
<a id="Trickory" href="#OnlyHappensOnce">
<input type="text" value="" id="email1" class="inputfield_ui" />
<label>Email address 1</label>
</a>
And your CSS, something like this:
html, body {margin:0px}
a#Trickory {color: #CCC;} /* Actual Label Color */
a#Trickory:visited {color: #FFF;} /* Fake "Turn Off" Label */
a#Trickory:visited input {border-color: rgb(238, 238, 238);} /* Make Sure We Dont Mess With The Border Of Our Input */
a#Trickory input:focus + label {display: none;} /* "Turn Off" Label On Focus */
a#Trickory input {
width:95%;
z-index:3;
position:relative;
background-color:transparent;
}
a#Trickory label {
position:absolute;
display:block;
top:3px;
left:4px;
z-index:1;
}
You can see this working over at jsfiddle, note that this solution only allows the user to select the field once, before it removes the label for good. Maybe not the solution you want, but definitely an available solution out there that I have not seen others mention. If you want to experiment multiple times, just change your #hashtag to a new 'non-visited' tag.
http://jsfiddle.net/childerskc/M6R7K/

CSS how to style a parent item when a textarea is in focus?

I have the following
<div class="comment-wrap">
<textarea></textarea>
</div>
Whenever the textarea is in focus, I want to style the comment-wrap div. I've tried:
#hallPost-inner + textarea:focus {
background: red;
}
This does not work. Any ideas on how I can style the comment-wrap div whenever the textarea is in focus, meaning the cursor is blinking in the textarea and the user can type?
Thanks
Not sure what #hallPost-inner is, but in general CSS selectors cannot ascend, meaning you would need to have the textarea:focus selector, but then would need to style an ancestor element, which cannot be done in css. Here's a good resource, among many others. The link shows how an easy javascript solution can be achieved as well.
With JavaScript and jQuery, you could do:
$("textarea").live("focus", function(e) {
$(this).closest(".comment-wrap").css({
"background": "red"
});
});
Use the pseudo selector :focus-within. Note that any child in focus will effect the parent. If you have more children and just wanna apply when the event hits the <textarea>, you will need JS.
Link for more details. (css-tricks)
Ex.:
form{
padding: 20px;
background-color: gainsboro
}
input{
text-align: center
}
form:focus-within {
background-color: yellow
}
<form>
<input type="text" placeholder="name">
<input type="text" placeholder="lastname">
<input type="button" value="Go!">
</form>
Note: not all browsers support :focus-within