Four-region selection box

Is there a way to create a quad state checkbox without using a set of images for various icons? I know how to have a tri-state checkbox with indeterminate, but I need to rotate through 4 states. Are there any more elegant solutions available?

Answer №1

By using radio buttons and some CSS (CSS3), you can create a similar effect of cycling through states without the need for JavaScript:

.cyclestate {
 display: inline-grid;
}
.cyclestate label {
 grid-area: 1 / 1;
 background-color: white; 
 color: black;
 z-index: 0;
 opacity: 0;
}
.cyclestate input {
 position: absolute;
 z-index: -1;
}
.cyclestate input:checked + label {
 opacity: 1;
}
.cyclestate input:first-of-type + label {
 z-index: 2;
}
.cyclestate input:checked + label + input + label {
 opacity: 0;
 z-index: 2;
}
/* -- Unrelated and accessibility -- */
.cyclestate { border: none; padding: 0; }
.cyclestate legend { position: absolute; }
.cyclestate label { padding: 1em; text-align: center; display: inline-block; cursor: pointer; user-select: none;
}
.cyclestate label::before { content: '← '; }
.cyclestate label::after { content: ' →'; }
.cyclestate label::before, label::after { color: transparent; }
.cyclestate input:focus-visible + label { outline: solid; }
.cyclestate input:focus-visible + label::before,
.cyclestate input:focus-visible + label::after { color: currentcolor; }
:root { background: dimgray; color: snow; }
:link { color: aqua; } :visited { color: lime; }
<fieldset class="cyclestate">
  <legend>Pick a number</legend>
  <input id="one" type="radio" name="r" checked>
  <label for="one">One</label>
  <input id="two" type="radio" name="r">
  <label for="two">Two</label>
  <input id="three" type="radio" name="r">
  <label for="three">Two Plus One</label>
  <input id="four" type="radio" name="r">
  <label for="four">Four</label>
</fieldset>

<p><button onclick="x.classList.toggle('cyclestate')">Toggle condenseness ↑</button>

This method involves layering labels on top of each other using modern CSS techniques like grid, ensuring that only the checked input's label is visible while maintaining accessibility.

(Note: Testing with screen readers and older browsers is recommended.)


The original 2015 snippet provided has questionable accessibility practice, it is advised to avoid using it altogether:

.cyclestate input:not(b),
.cyclestate input:not(b) + label {
  display: none;
}
.cyclestate input:checked + label {
  display: inline-block;
  width: 4em;
  text-align: center;
  -webkit-user-select: none;
  -moz-user-select: none;
  -webkit-appearance: button;
  -moz-appearance: button;
}
<span class="cyclestate">
  <input type="radio" name="foo" value="one" id="one" checked>
  <label for="two">one</label>
  <input type="radio" name="foo" value="two" id="two">
  <label for="three">two</label>
  <input type="radio" name="foo" value="three" id="three">
  <label for="four">three</label>
  <input type="radio" name="foo" value="four" id="four">
  <label for="one">four</label>
</span>

Using this method allows for a compact visual representation of multiple states in one place, with clear values on the server side.

However, it should be noted that this usage of labels may exploit the feature of label targeting different input than described.

Answer №2

It is possible to give the appearance that a checkbox has three states, but in reality, it will always have only two options available.
Furthermore, achieving the "indeterminate" visual state is not inherent to the default user interface and requires programmatic activation:

var box = document.getElementById('box'),
    checked = document.getElementById('checked'),
    indet = document.getElementById('indet');
var update = function()
{
    checked.textContent = box.checked;
    indet.textContent = box.indeterminate;
};
box.addEventListener('click', update);
document.getElementById('a').addEventListener('click', function()
{
    box.checked = true;
    update();
});
document.getElementById('b').addEventListener('click', function()
{
    box.checked = false;
    update();
});
document.getElementById('c').addEventListener('click', function()
{
    box.indeterminate = true;
    update();
});
document.getElementById('d').addEventListener('click', function()
{
    box.indeterminate = false;
    update();
});
<input type="checkbox" id="box"><br>
<button id="a">On</button> <button id="b">Off</button><br>
<button id="c">Indeterminate</button> <button id="d">Clear indeterminate</button>
<div>box.checked: <span id="checked"></span></div>
<div>box.indeterminate: <span id="indet"></span></div>

In response to your inquiry:

There currently isn't a built-in method to introduce a fourth visual (or actual) state to a checkbox, although this doesn't mean resorting to using images is necessary.
It's feasible to style an element resembling a checkbox and utilize JavaScript to simulate a rotation of states:

var state = 0;
var toggle = document.getElementById('toggle');
toggle.addEventListener('click', function()
{
    state = (state + 1) % 4;
    toggle.className = 'state' + state;
});
#toggle
{
    border: solid 1px #666;
    border-radius: 3px;
    width: 14px;
    height: 14px;
}
.state0
{
    background: linear-gradient(#DDD, #FFF);
}
.state1
{
    background: linear-gradient(#F00, #C00);
}
.state2
{
    background: linear-gradient(#FF0, #CC0);
}
.state3
{
    background: linear-gradient(#0F0, #0A0);
}
<div id="toggle" class="state0"></div>

Ultimately, alternatives beyond traditional checkboxes will be required.

Moreover, implementing a checkbox-like entity with more than two states can be confusing, so I encourage exploring options designed for multiple selections like radio buttons or dropdown lists.

Answer №3

Unfortunately, it is not currently feasible. However, for those interested, there is a helpful resource that explains how to utilize three states, including the indeterminate state: https://css-tricks.com/indeterminate-checkboxes/

You will need to devise an alternative solution by incorporating your own icons and essentially creating a customized form control. One potential design approach that addresses the requirement for multiple states involves:

Utilizing a series of icons, reminiscent of Gmail's star system. In Gmail, clicking on the star changes its color, and after a certain number of clicks (around 10), other icons like exclamation points and checkmarks appear.

Link your various state specifications with the icon currently in use (or the position within the icon list).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

NavigateToTop/BackToTheBeginning

I'm facing a challenge with a page layout that involves two vertical div's - one for the menu on the left and another for loading content on the right. My goal is to utilize the .scrollintoview() function on the menu div so that when a link is cl ...

Close button located in the upper-right corner is partially cut off

My challenge involves placing a close button on the top right corner of a #main div that contains an image of varying or larger size. I need the close button to slightly protrude outside the div using negative margins. The issue is that when I use overflow ...

While continuing to input text, make sure to highlight a specific element from the search results list

Currently, I am using a customized search feature in my React.js application. I am looking for a way to focus on an element within the search results so that I can navigate using arrow keys. At the same time, I need to keep the input field focused to conti ...

CSS: Placing text within an icon - A simple guide

Hello, I am currently working on an Ionic application where I have rounded areas to display information. My challenge is to incorporate a number inside a heart icon within the second area. I want to ensure that the alignment of the number and the heart is ...

"Is there a way to align a span element on the same line as an h

I'm attempting to align a text-number (span) next to an entry-title (h2) on the same line, with the entry-meta block on the following line, including having the reading time float left. I could use some help with my CSS implementation. Thank you. Ex ...

Having trouble loading the linked CSS file in the Jade template

My directory structure is organized as follows: --votingApp app.js node_modules public css mystyle.css views test.jade mixins.jade In the file mixins.jade, I have created some general purpose blocks like 'bo ...

Problem with Bootstrap container-fluid overlapping with floated element

I am struggling with the layout of my card body, which includes a floating logo and rows enclosed in a container-fluid. While everything looks great in Chrome, I am facing alignment issues in Edge and Firefox. I have considered using absolute positioning ...

Adjusting HTML image sizes

How can I prevent large images from extending off the edge of the screen when using HTML img tags? Is there a way to scale them to fit within the browser window or specify a set percentage for their width and height? I've noticed that using the width ...

Tips for creating a functional Submit button in HTML

How can I ensure that the submit button sends the necessary information to my email address when clicked (e.g. [email protected])? If PHP is required, please provide the code so I can easily integrate it into my project. Thank you! <div id="forms ...

Issue with Bootstrap alignment on the right side

Just finished creating my 'navbar' in bootstrap, but I'm having trouble aligning my unordered list to the right. It's staying in the middle no matter what I try. Can someone please help? Feeling really confused... HTML: <div class= ...

unable to modify background color when mouse hovers in CSS

Recently, I implemented this code to style the navigation bar on my website. However, I encountered an issue where the color does not change when hovering over the links. .nav { list-style-type:none; margin:0; padding:0; overflow:hidden; } ...

When attempting to transfer data from the parent component to child components, the data is appearing as undefined in the display

I have been working on passing data from a parent component to child components, but I keep encountering an issue where the data is showing as undefined. Below is the code snippet: Parent Component In this section, I have declared the variable part_data ...

Delete any additional input forms

I have recently developed a function to dynamically add an input field to my form: function add_parameter(){ var d = document.getElementById("content"); d.innerHTML += "<br/><br><div class='custom_search col-md-5'><sp ...

Unveil concealed information within a freshly enlarged container

As I organize my content into an FAQ format, I want users to be able to click on a link and expand the section to reveal a list of items that can also be expanded individually. My goal is to have certain list items expand automatically when the FAQ section ...

What is the most efficient method for identifying and modifying an element's in-line style while performing a swipe gesture?

Recently, I've been developing a left swipe gesture handler for chat bubbles. Implementing touchMove and touchStart seems like the logical next step, but for now, I'm focusing on making it work seamlessly for PC/web users. I managed to make it f ...

Troubleshoot: OffCanvas feature in Bootstrap 5 not functioning properly within navbar on small screens

I'm having trouble implementing Bootstrap 5 OffCanvas within the Navbar on laptop/desktop screens. It seems to only work properly on mobile screens with a size of sm or lower, displaying the hamburger menu. Any suggestions on how to make it functional ...

analyzing information from a variety of HTML tables

I am currently working on extracting financial data from Income Statements tables within 8-K Forms retrieved from the Edgar Database (http://www.sec.gov/edgar/searchedgar/companysearch.html). Here are a couple of examples: Apple Alcoa The specific table ...

CSS guidelines for handling single line breaks with the white-space property set to pre-wrap

Is it considered acceptable to include solitary carriage return characters in an HTML block styled with white-space: pre-wrap? I am working with an application that receives SOAP messages and logs them to a file. The logging process involves removing new- ...

Arranging divs using the float property

I am currently working on a Django project where I have a large list of dictionaries in the view: 'description': [ { 'name': 'Parts', 'good': ['Engine', 'Transmission&a ...

I need to extract information from the source code of a different website - how can I do this

Is it possible to extract content from the source code of another website and display it on our own site? For example, imagine a scenario where a site contains the following source code: <table ...> <tr> <td class ...