I have an HTML page which looks something like this,
<select id="selectMe">
<option value="option1">Question 1</option>
<option value="option2">Question 2</option>
<option value="option3">Question 3</option>
</select>
<div id="option1">Answer 1</div>
<div id="option2">Answer 2</div>
<div id="option3">Answer 3</div>
I want to use the <select> element to choose which answer <div> to show. Unfortunately, I cannot use any JavaScript and must do this with HTML / CSS only.
Also note I'm not hell-bent on using <select> if some other form elements will make this easier. But not using any JavaScript is a hard restriction for me.
I mean there is one-way (not totally proud of it) but using radio buttons help us to track checked state using the :checked pseudo-selector. We can use the same to map from question1 to option1 and so on.
.options{
display:none;
}
#question1:checked ~ #option1,
#question2:checked ~ #option2,
#question3:checked ~ #option3{
display:block;
}
<input type="radio" name="questions" id="question1" checked/>
<label for="question1">Quesion 1</label>
<input type="radio" name="questions" id="question2"/>
<label for="question2">Question 2</label>
<input type="radio" name="questions" id="question3"/>
<label for="question3">Question 3</label>
<div id="option1" class="options">Answer 1</div>
<div id="option2" class="options">Answer 2</div>
<div id="option3" class="options">Answer 3</div>
I cannot think of a way to hide elements without JS, however, you could use page anchors.
Make the divs match the height of the screen
Use anchors to link to the divs on page
Fix the nav to the top of the screen so that on scrolling it doesn't disappear
Disable the user scrolling which would make it appear to hide/show the divs.
Hope this helps.
<div class="sticky">
Question 1
Question 2
Question 3
</div>
<div id="option1" class="full-height blue">Answer 1</div>
<div id="option2" class="full-height green">Answer 2</div>
<div id="option3" class="full-height red">Answer 3</div>
<style>
body {
overflow: hidden;
margin: 0;
}
.sticky {
position: fixed;
background: white;
}
.full-height {
color: white;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.blue { background: blue; }
.green { background: green; }
.red { background: red; }
</style>
Like it was mentioned before the best way is to use inputs with types radio or checkbox depending on what you want to achieve. The example of using radio buttons and labels is here https://codepen.io/alekskorovin/pen/abBeqzN
.answer-toggle,
.answer {
display: none;
}
.answer-toggle:checked ~ .answer,
.question {
display: block;
}
<label class="question" for="answer1">Question 1</label>
<label class="question" for="answer2">Question 2</label>
<label class="question" for="answer3">Question 3</label>
<div>
<input class="answer-toggle" type="radio" name="answer" id="answer1">
<div class="answer">Answer 1</div>
</div>
<div>
<input class="answer-toggle" type="radio" name="answer" id="answer2">
<div class="answer">Answer 2</div>
</div>
<div>
<input class="answer-toggle" type="radio" name="answer" id="answer3">
<div class="answer">Answer 3</div>
</div>
if you remove the same name="answer" then each answer could be shown independently.
I think you can use the CSS CheckBox Hack. You will however need to build your own <select> because unfortunately it is not possible to put HTML tags inside an <option>.
The basic idea is outlined below. On the linked page you can also find an example for how to hide and show content.
.visually-hidden {
position: absolute;
left: -100vw;
}
.dropdown-header::after {
content: "> Options (Click to expand)";
}
#option1:checked ~ .dropdown-header::after {
content: "Question 1";
}
#option2:checked ~ .dropdown-header::after {
content: "Question 2";
}
#option3:checked ~ .dropdown-header::after {
content: "Question 3";
}
.answer::after {
content: "";
}
#option1:checked ~ .answer::after {
content: "Answer 1";
}
#option2:checked ~ .answer::after {
content: "Answer 2";
}
#option3:checked ~ .answer::after {
content: "Answer 3";
}
.dropdown:hover {
background-color: blue;
}
#dropdown:checked ~ .dropdown {
display: inline;
}
.dropdown {
display: none;
}
<div>
<input type="checkbox" class="visually-hidden" id="dropdown">
<label for="dropdown" class="dropdown-header"></label><br>
<label class="dropdown" for="option1">Question 1</label><input type="radio" id="option1" name="rad" class="visually-hidden" checked><br>
<label class="dropdown" for="option2">Question 2</label><input id="option2" type="radio" class="visually-hidden" name="rad"/><br>
<label class="dropdown" for="option3">Question 3</label><input id="option3" type="radio" class="visually-hidden" name="rad"/><br>
<div class="answer"></div>
</div>
Related
A series of CSS-only tabs
<ul class='tabs'>
<li>
<input type="radio" name="tabs" id="tab_23101" value="23101" checked />
<label for='tab_23101'> </label>
<div id='tab-content_23101' class='tab-content'>
<label><input type="radio" class='imagepick' id="Frame_CD" name="Frame" value="23101_CD"></label>
</div>
</li>
<li>
<input type="radio" name="tabs" id="tab_23102" value="23102" />
<label for='tab_23102'> </label>
<div id='tab-content_23102' class='tab-content'>
<label><input type="radio" class='imagepick' id="Frame_CD" name="Frame" value="23102_CD"></label>
</div>
</li>
each has specific content, which go on to specify for further inputs with names and values which are used by a javascript as selectors for rendering an image. The problem is that a selected value in one line item <li> say 23101_CD is not valid for the second line items (expecting 23102_CD) and would thus render a blank if the second line item were selected.
the javascript is structured as follows
$("input[type=radio]").on("change", function() {
var Frame_image = $("input[name=tabs]:checked").val() + "_" + $("input[name=Frame]:checked").val();
$("#Frame").attr("src", "/small/Frame_" + Frame_image + ".png");
How can one add pairs (multiple) of name and value to the parent input tag as part of the HTML (the desire is to avoid having to alter existing javascript) to act as selected items checked="checked"?
It is unclear as to why you need input tags to have children. You can use adjacency selector (+) to match a tab next to a radiobutton. Here's a minimalist CSS-only tabs demo:
.tabs {
display: flex;
flex-wrap: wrap;
background: #f0f0f0;
border: 1px solid #ddd;
}
.tabs > input {
display: none;
}
.tabs > label {
padding: 0.2em 0.5em;
background: #f0f0f0;
}
.tabs > div {
padding: 0.5em;
width: 100%;
order: 100;
background: white;
}
.tabs > input:checked + label {
background: white;
}
.tabs > input:not(:checked) + label + div {
display: none;
}
<div class="tabs">
<input type="radio" name="t1" id="t1_1" checked/>
<label for="t1_1">Tab 1</label>
<div>
Tab 1!
</div>
<input type="radio" name="t1" id="t1_2"/>
<label for="t1_2">Tab 2</label>
<div>
Tab 2!
</div>
<input type="radio" name="t1" id="t1_3"/>
<label for="t1_3">Tab 3</label>
<div>
Tab 3!
</div>
</div>
I have a specific task to do, and I'm not sure what is the best way to do it.
I have around 60 unique checkboxes and when clicked, display some text on their right side (tied to that clicked checkbox).
I have done it with 64 specific eventListeners, but I'm not sure that this is the best way: I would like to simplify the code.
So, for example, I have bunch of checkboxes in a label that is: test, test1, test2 and so on. And when I click on test checkbox, that the text: "hello world" can appear, if test1 is checked, text: "One 2 three" can appear, if test2 is checked, text: "I've done it" can appear, but if none of them is selected, texts will not be displayed.
This is the code, one event listener I have now:
var forSale = document.querySelector('#for_sale');
var forSaleEmail = document.querySelector('#for_sale_email');
/*For Sale*/
forSale.addEventListener("click", function(){
if(forSale.checked === true){
forSaleEmail.style.display = 'block';
} else {
forSaleEmail.style.display = 'none';
}
});
Where the forSale variable is a checkbox and forSaleEmail is a text that should be displayed.
If you have any suggestions or you can tell me what to look for, it would be greatly appreciated.
HTML Code is as following:
<div><label>For Sale <input type="checkbox" id="for_sale"></label></div>
<div><span id="for_sale_email">
<p>
for sale
</p>
</span></div>
An option is event delegation, where you add one event handler to a parent/ancestor of all the input's, and use the event property event.target to detect the one that were clicked on, and simply toggle a class on its parents div.
Combined with the CSS adjacent sibling selector + it gets as simple as this
Note 1: Having a <p> inside an inline element like a <span> is not valid markup, so I removed it. If you need an extra, use another <span> and give it similar style a <p> has as default.
Note 2: id needs to be unique so make sure you have that taken care of, and for your for_sale_email it doesn't need to be, so I changed it to a class.
Note 3: If you want to "toggle" between the chosen input's, I also added a code part that does that.
Stack snippet
document.querySelector('.inputs_parent').addEventListener('change', function(event) {
// this will "hide" previous checked input
var prev = this.querySelector('div.checked');
if (prev) {
prev.classList.remove('checked');
prev.querySelector('input').checked = false;
}
// remove this "if" statement if won't use the above
if (!prev || !prev.contains(event.target))
event.target.closest('div').classList.toggle('checked');
})
.for_sale_email {
display: none;
}
div.checked + div .for_sale_email {
display: inline-block;
}
<div class="inputs_parent">
<div>
<label>For Sale
<input type="checkbox" id="for_sale1">
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<div>
<label>For Sale
<input type="checkbox" id="for_sale2">
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<div>
<label>For Sale
<input type="checkbox" id="for_sale3">
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<div>
<label>For Sale
<input type="checkbox" id="for_sale4">
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
</div>
If you can make a small markup change, you can actually accomplish this with CSS alone.
Stack snippet
.inputs_parent label:after {
content: 'X';
display: inline-block;
text-align: center;
font-size: 12px;
color: transparent;
width: 12px;
height: 12px;
border: 1px solid black;
margin-left: 5px;
}
.inputs_parent input,
.inputs_parent .for_sale_email {
display: none;
}
.inputs_parent input:checked + div label:after {
color: black;
}
.inputs_parent input:checked + div + div .for_sale_email {
display: inline-block;
}
<div class="inputs_parent">
<input type="checkbox" id="for_sale1">
<div>
<label for="for_sale1">For Sale
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<input type="checkbox" id="for_sale2">
<div>
<label for="for_sale2">For Sale
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<input type="checkbox" id="for_sale3">
<div>
<label for="for_sale3">For Sale
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<input type="checkbox" id="for_sale4">
<div>
<label for="for_sale4">For Sale
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
</div>
And this one toggle's the checked items, using an input type="radio".
Stack snippet
.inputs_parent label:after {
content: 'X';
display: inline-block;
text-align: center;
font-size: 12px;
color: transparent;
width: 12px;
height: 12px;
border: 1px solid black;
margin-left: 5px;
}
.inputs_parent input,
.inputs_parent .for_sale_email {
display: none;
}
.inputs_parent input:checked + div label:after {
color: black;
}
.inputs_parent input:checked + div + div .for_sale_email {
display: inline-block;
}
<div class="inputs_parent">
<input type="radio" name="radio" id="for_sale1">
<div>
<label for="for_sale1">For Sale
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<input type="radio" name="radio" id="for_sale2">
<div>
<label for="for_sale2">For Sale
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<input type="radio" name="radio" id="for_sale3">
<div>
<label for="for_sale3">For Sale
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
<input type="radio" name="radio" id="for_sale4">
<div>
<label for="for_sale4">For Sale
</label>
</div>
<div>
<span class="for_sale_email">
for sale
</span>
</div>
</div>
Your code is totally fine, but you should definetly abstract it into a function:
function selectMessage(checkbockSelector, messageSelector) {
var checkbox = document.querySelector(checkboxSelector);
var message = document.querySelector(messageSelector);
checkbox.addEventListener("click", function(){
message.style.display = checkbox.selected ? 'block' : 'none';
});
}
So that you can just do:
selectMessage("#for_sale", "#for_sale_email");
If there are a lot of elements, it might be a good idea to change the HTML into a structure, that directly relates the labels with the input:
<div id="sale">
<label>For Sale</label>
<input type="checkbox" id="for_sale" class="withhint">
<span class="hint">
<p>for sale</p>
</span>
</div>
Then you can hide them with CSS by default:
.hint { display: none; }
And use javascript to apply the handler to all:
document.querySelectorAll(".withhint").forEach(function(input) {
const hint = input.parentElement.querySelector(".hint");
input.addEventListener("click", function() {
hint.style.display = input.checked ? "block" : "none";
});
});
Try it!
I have created a div tag and wrote some content in it. and have created 3 types of styling effect for that div tag. so have created 3 radio buttons and now i dont know how to connect these things together. If check one of the radio button the div tag should take one of the styling.
Thanks in Advance.
You could do it with css only.
input[value="blue"]:checked ~ div {
background: blue;
}
input[value="yellow"]:checked ~ div {
background: yellow;
}
input[value="orange"]:checked ~ div {
background: orange;
}
div {
width: 80px;
height: 80px;
}
<label for="blue">blue</label>
<input type="radio" value="blue" id="blue" name="group1">
<label for="yellow">yellow</label>
<input type="radio" value="yellow" id="yellow" name="group1">
<label for="orange">orange</label>
<input type="radio" value="orange" id="orange" name="group1">
<div></div>
PLAYGROUND HERE
I'd like to style radio buttons differently if they fit in a single row. For example:
The first container doesn't have enough space to fit all the radio buttons in a single row. Therefore, they appear vertically as normal radio buttons.
The second container has enough space. Therefore, the radio buttons appear as buttons.
Is that possible to achieve this behaviour using CSS only?
If not, Javascript "hack" is welcome.
PLAYGROUND HERE
HTML
<div class="container radio">
<div>
<input id="a1" type="radio" name="radio">
<label for="a1">Yes,</label>
</div>
<div>
<input id="a2" type="radio" name="radio">
<label for="a2">it</label>
</div>
<div>
<input id="a3" type="radio" name="radio">
<label for="a3">is</label>
</div>
<div>
<input id="a4" type="radio" name="radio">
<label for="a4">possible</label>
</div>
<div>
<input id="a5" type="radio" name="radio">
<label for="a5">to</label>
</div>
<div>
<input id="a6" type="radio" name="radio">
<label for="a6">achieve</label>
</div>
<div>
<input id="a7" type="radio" name="radio">
<label for="a7">this</label>
</div>
</div>
<div class="container buttons">
<div>
<input id="b1" type="radio" name="buttons">
<label for="b1">Yes,</label>
</div>
<div>
<input id="b2" type="radio" name="buttons">
<label for="b2">it</label>
</div>
<div>
<input id="b3" type="radio" name="buttons">
<label for="b3">is</label>
</div>
<div>
<input id="b4" type="radio" name="buttons">
<label for="b4">possible</label>
</div>
</div>
CSS (LESS)
.container {
display: flex;
width: 220px;
padding: 20px;
margin-top: 20px;
border: 1px solid black;
&.radio {
flex-direction: column;
}
&.buttons {
flex-direction: row;
> div {
input {
display: none;
&:checked + label {
background-color: #ADFFFE;
}
}
label {
padding: 5px 10px;
margin: 0 1px;
background-color: #ccc;
}
}
}
}
Not possible in CSS, but it doesn't take much JavaScript.
In CSS, add flex-shrink: 0 to > div. This will prevent .container's children from shrinking smaller than their extent.
In JavaScript:
Apply the buttons class.
Use Element.getBoundingClientRect to determine if the last child of .container is outside the extent of .container. If so, switch to the radio class. (You also need to take the right padding into account. Thanks to #Moob for pointing that out.)
Javascript
var container = document.querySelector('.container'),
lastChild= document.querySelector('.container > :last-child'),
paddingRight= parseInt(window.getComputedStyle(container, null).getPropertyValue('padding-right')),
timer;
window.onresize = function() {
clearTimeout(timer);
timer= setTimeout(function() {
container.classList.remove('radio');
container.classList.add('buttons');
if (container.getBoundingClientRect().right-paddingRight <
lastChild.getBoundingClientRect().right) {
container.classList.add('radio');
container.classList.remove('buttons');
}
});
}
Updated JSBin
I can't think of a CSS only solution but you could use JS to test if the items would fit in a row and apply the 'radio' or 'buttons' classname accordingly:
Forgive my rough JS - its inelegant and for modern browsers only but you get the idea:
var containers = document.querySelectorAll(".container"),
test = function(){
for (i = 0; i < containers.length; ++i) {
var container = containers[i],
divs = container.querySelectorAll("div"),
iw = 0;
container.classList.remove("radio");
container.classList.add("buttons");
//get the sum width of the div
for (d = 0; d < divs.length; ++d) {
iw+=divs[d].offsetWidth;
}
var style = window.getComputedStyle(container, null);
var ow = parseInt(style.getPropertyValue("width"));
if(ow<=iw){
container.classList.add("radio");
container.classList.remove("buttons");
}
}
};
window.onresize = function(event) {
test();
};
test();
http://jsbin.com/zofixakama/3/edit?html,css,js,output
(resize the window / panel to see the effect)
Update: If you add .container div {flex-shrink:0;} to the style the JS can be much simpler as we don't have to measure the combined width of the divs (thanks #rick-hitchcock). However, although the code is more elegant, it does not take the container's padding into account.
See: http://jsbin.com/zofixakama/5/edit?html,css,js,output
If I understand what you're asking correctly, you can change your flex-direction portion to row instead of column. This will cause them to align inside the box.
You'll have to do some more styling to properly get the labels to appear the way you want, but this should put them in the row for you. I've updated the playground with my changes.
Try the following example..............
------------HTML-----------
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<div class="table-row">
<div class="col">
<input type="Radio">This
</div>
<div class="col" style="padding-top: 2px;">
<input type="Radio">Is
</div>
<div class="col">
<input type="Radio">Simply
</div>
<div class="col" style="padding-top: 2px;">
<input type="Radio">Possible
</div>
</div>
</body>
</html>
-------CSS-------------
.table-row{
display:table-row;
/* text-align: center; */
}
.col{
display:table-cell;
/* border: 1px solid #CCC; */
}
Wouldn't it work to test for width then if necessary remove the radio button icon and replace with a graphic or shape?
.checkbox {
display:none;
}
.label {
display: inline-block;
height: 20px;
background: url('picture.png');
}
It's probably not that simple but I use that for check boxes and it seems to work in that situation.
You can achieve this only by using css and no need of scripting.
HTML: You have to place the input within tag which will contain the text.
<div>
<label for="a1">
<input id="a1" type="radio" name="radio">Yes,
</label> </div>
CSS: Here in CSS we will have to hide the radio button, so that only the text will be visible. When the user clicks on the text, it actually clicks the radio button.
div lable input#a1{
display:none;
}
there is pretty solution CSS only, but you have to know maximum amount of elements in row. It is based on counter, but not on real size.
For example, if you are sure, that you can put 4 elements into a row, in any case, you may use following selector:
if amount is more less or equal 4:
div:nth-last-child(-n+5):first-child,
div:nth-last-child(-n+5):first-child ~ div {
}
if amount is more then 4:
div:nth-last-child(n+5),
div:nth-last-child(n+5) ~ div {
}
try this: http://jsbin.com/fozeromezi/2/edit (just remove/add divs)
I am building a UI app using JQuery UI elements. I need radio buttons as part of the functionality. While using JQuery buttonset by itself works, once I try to incorporate it with the rest of UI elements they don't align properly:
http://jsfiddle.net/sEunS/2/
Including code here:
$(document).ready(function()
{
$("button").button();
$("#tdiDir").buttonset();
$("#acqMode").buttonset();
});
<div id='primaryLatestControl'
class="ui-corner-top pacontainer"
style='padding: 4px; display: inline-block; '>
<button id="setGain" class="button">Set</button>
<span class="label">Gain Value</span>
<input type="text" id="gainValue" class="value" value="2"></input>
<button id="setLineRate" class="button">Set</button>
<span class="label">Line Rate, HZ</span>
<input type="text" class="value" id="lineRateValue" value="3750"></input>
<button id="setExposeTime" class="button">Set</button>
<span class="label">Exposure Time(ms)</span>
<input type="text" class="value" id="exposeTimeValue" value="100"></input>
<button id="setTDI" class="button">Set</button>
<span class="label">TDI Direction</span>
<form>
<div id="tdiDir">
<label class="checkLabel" for="forward">Forward</label>
<label class="checkLabel" for="reverse">Reverse</label>
<input type="radio" class="value" name="tdiDir" id="forward" checked="checked"/>
<input type="radio" class="value " name="tdiDir" id="reverse"/>
</div>
</form>
<button id="setAcqMode" class="button">Set</button>
<span class="label">Acquisition Mode</span>
<form>
<div id="acqMode">
<label class="checkLabel" for="tdi">TDI</label>
<label class="checkLabel " for="area">Area</label>
<input type="radio" class="value" name="acqMode" id="tdi" checked="checked"/>
<input type="radio" class="value" name="acqMode" id="area"/>
</div>
</form>
.pacontainer {
position: relative;
width: 80%;
}
.label {
float: left;
margin: 10px;
}
.checkLabel {
width: 100px;
float: right;
margin: 10px;
}
.endLine {
clear: right;
}
.button {
float: left;
margin-left: 10px;
clear: left;
}
.value {
float: right;
width: 45px;
height: 20px;
margin: 5px;
background-image: none;
}
I quickly made some changes to your code to give you an idea. http://jsfiddle.net/sEunS/3/
You want your buttons in your buttonset to be ordered because the buttonset gives the outer buttons round corners and the inner buttons get 'squished' margins to be close together. Without the right ordering, the buttonset will always not look right.
Floating the radio's labels will cause the radios to be unordered in the buttonset. I suggest floating the radio's containers instead of the labels.
#acqMode, #tdiDir {
float: right;
}
and remove the float on the .checkLabels as they are no longer needed
.checkLabel {
//float: right;
}
You should also keep your radio's labels together with the radio inputs. This is another ordering issue with buttonsets.
<div id="acqMode">
<label class="checkLabel " for="area">Area</label>
<input type="radio" class="value" name="acqMode" id="area"/>
<label class="checkLabel" for="tdi">TDI</label>
<input type="radio" class="value" name="acqMode" id="tdi" checked="checked"/>
</div>
The last issue is you will need has to do with a clearfix. The buttonset is larger than the text on the same line, so the next line will not look straight without a clearfix. JQuery UI has a helper class
ui-helper-clearfix
I added this class to the line above that was uneven. The class goes on the parent of the last floated element. (try removing this class to get an idea of what I mean).