How to style a checkbox using CSS

前端 未结 30 3512
日久生厌
日久生厌 2020-11-21 04:26

I am trying to style a checkbox using the following:

30条回答
  •  花落未央
    2020-11-21 05:11

    Here is an example, with theme support. It is a modern approach with CSS transitions. There is absolutely no JavaScript required.

    I derived the following code linked in this comment; on a related question.

    Edit: I added radio buttons, as maxshuty suggests.

    const selector = '.grid-container > .grid-row > .grid-col[data-theme="retro"]';
    const main = () => {
      new CheckboxStyler().run(selector);
      new RadioStyler().run(selector);
    };
    
    /*
     * This is only used to add the wrapper class and checkmark span to an existing DOM,
     * to make this CSS work.
     */
    class AbstractInputStyler {
      constructor(options) {
        this.opts = options;
      }
      run(parentSelector) {
        let wrapperClass = this.opts.wrapperClass;
        let parent = document.querySelector(parentSelector) || document.getElementsByTagName('body')[0];
        let labels = parent.querySelectorAll('label');
        if (labels.length) labels.forEach(label => {
          if (label.querySelector(`input[type="${this.opts._inputType}"]`)) {
            if (!label.classList.contains(wrapperClass)) {
              label.classList.add(wrapperClass);
              label.appendChild(this.__createDefaultNode());
            }
          }
        });
        return this;
      }
      /* @protected */
      __createDefaultNode() {
        let checkmark = document.createElement('span');
        checkmark.className = this.opts._activeClass;
        return checkmark;
      }
    }
    
    class CheckboxStyler extends AbstractInputStyler {
      constructor(options) {
        super(Object.assign({
          _inputType: 'checkbox',
          _activeClass: 'checkmark'
        }, CheckboxStyler.defaultOptions, options));
      }
    }
    CheckboxStyler.defaultOptions = {
      wrapperClass: 'checkbox-wrapper'
    };
    
    class RadioStyler extends AbstractInputStyler {
      constructor(options) {
        super(Object.assign({
          _inputType: 'radio',
          _activeClass: 'pip'
        }, RadioStyler.defaultOptions, options));
      }
    }
    RadioStyler.defaultOptions = {
      wrapperClass: 'radio-wrapper'
    };
    
    main();
    /* Theming */
    
    :root {
      --background-color: #FFF;
      --font-color: #000;
      --checkbox-default-background: #EEE;
      --checkbox-hover-background: #CCC;
      --checkbox-disabled-background: #AAA;
      --checkbox-selected-background: #1A74BA;
      --checkbox-selected-disabled-background: #6694B7;
      --checkbox-checkmark-color: #FFF;
      --checkbox-checkmark-disabled-color: #DDD;
    }
    
    [data-theme="dark"] {
      --background-color: #111;
      --font-color: #EEE;
      --checkbox-default-background: #222;
      --checkbox-hover-background: #444;
      --checkbox-disabled-background: #555;
      --checkbox-selected-background: #2196F3;
      --checkbox-selected-disabled-background: #125487;
      --checkbox-checkmark-color: #EEE;
      --checkbox-checkmark-disabled-color: #999;
    }
    
    [data-theme="retro"] {
      --background-color: #FFA;
      --font-color: #000;
      --checkbox-default-background: #EEE;
      --checkbox-hover-background: #FFF;
      --checkbox-disabled-background: #BBB;
      --checkbox-selected-background: #EEE;
      --checkbox-selected-disabled-background: #BBB;
      --checkbox-checkmark-color: #F44;
      --checkbox-checkmark-disabled-color: #D00;
    }
    
    
    /* General styles */
    
    html {
      width: 100%;
      height: 100%;
    }
    
    body {
      /*background: var(--background-color); -- For demo, moved to column. */
      /*color:      var(--font-color);       -- For demo, moved to column. */
      background: #777;
      width: calc(100% - 0.5em);
      height: calc(100% - 0.5em);
      padding: 0.25em;
    }
    
    h1 {
      font-size: 1.33em !important;
    }
    
    h2 {
      font-size: 1.15em !important;
      margin-top: 1em;
    }
    
    
    /* Grid style - using flex */
    
    .grid-container {
      display: flex;
      height: 100%;
      flex-direction: column;
      flex: 1;
    }
    
    .grid-row {
      display: flex;
      flex-direction: row;
      flex: 1;
      margin: 0.25em 0;
    }
    
    .grid-col {
      display: flex;
      flex-direction: column;
      height: 100%;
      padding: 0 1em;
      flex: 1;
      margin: 0 0.25em;
      /* If not demo, remove and uncomment the body color rules */
      background: var(--background-color);
      color: var(--font-color);
    }
    
    .grid-cell {
      width: 100%;
      height: 100%;
    }
    
    
    /* The checkbox wrapper */
    
    .checkbox-wrapper,
    .radio-wrapper {
      display: block;
      position: relative;
      padding-left: 1.5em;
      margin-bottom: 0.5em;
      cursor: pointer;
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
    }
    
    
    /* Hide the browser's default checkbox and radio buttons */
    
    .checkbox-wrapper input[type="checkbox"] {
      position: absolute;
      opacity: 0;
      cursor: pointer;
      height: 0;
      width: 0;
    }
    
    .radio-wrapper input[type="radio"] {
      position: absolute;
      opacity: 0;
      cursor: pointer;
      height: 0;
      width: 0;
    }
    
    
    /* Create a custom checkbox */
    
    .checkbox-wrapper .checkmark {
      position: absolute;
      top: 0;
      left: 0;
      height: 1em;
      width: 1em;
      background-color: var(--checkbox-default-background);
      transition: all 0.2s ease-in;
    }
    
    .radio-wrapper .pip {
      position: absolute;
      top: 0;
      left: 0;
      height: 1em;
      width: 1em;
      border-radius: 50%;
      background-color: var(--checkbox-default-background);
      transition: all 0.2s ease-in;
    }
    
    
    /* Disabled style */
    
    .checkbox-wrapper input[type="checkbox"]:disabled~.checkmark,
    .radio-wrapper input[type="radio"]:disabled~.pip {
      cursor: not-allowed;
      background-color: var(--checkbox-disabled-background);
      color: var(--checkbox-checkmark-disabled-color);
    }
    
    .checkbox-wrapper input[type="checkbox"]:disabled~.checkmark:after,
    .radio-wrapper input[type="radio"]:disabled~.pip:after {
      color: var(--checkbox-checkmark-disabled-color);
    }
    
    .checkbox-wrapper input[type="checkbox"]:disabled:checked~.checkmark,
    .radio-wrapper input[type="radio"]:disabled:checked~.pip {
      background-color: var(--checkbox-selected-disabled-background);
    }
    
    
    /* On mouse-over, add a grey background color */
    
    .checkbox-wrapper:hover input[type="checkbox"]:not(:disabled):not(:checked)~.checkmark,
    .radio-wrapper:hover input[type="radio"]:not(:disabled):not(:checked)~.pip {
      background-color: var(--checkbox-hover-background);
    }
    
    
    /* When the checkbox is checked, add a blue background */
    
    .checkbox-wrapper input[type="checkbox"]:checked~.checkmark,
    .radio-wrapper input[type="radio"]:checked~.pip {
      background-color: var(--checkbox-selected-background);
    }
    
    
    /* Create the checkmark/indicator (hidden when not checked) */
    
    .checkbox-wrapper .checkmark:after {
      display: none;
      width: 100%;
      position: absolute;
      text-align: center;
      content: "\2713";
      color: var(--checkbox-checkmark-color);
      line-height: 1.1em;
    }
    
    .radio-wrapper .pip:after {
      display: none;
      width: 100%;
      position: absolute;
      text-align: center;
      content: "\2022";
      color: var(--checkbox-checkmark-color);
      font-size: 1.5em;
      top: -0.2em;
    }
    
    
    /* Show the checkmark when checked */
    
    .checkbox-wrapper input[type="checkbox"]:checked~.checkmark:after {
      display: block;
      line-height: 1.1em;
    }
    
    .radio-wrapper input[type="radio"]:checked~.pip:after {
      display: block;
      line-height: 1.1em;
    }
    
    

    Pure CSS

    Checkbox

    Radio

    Pure CSS

    Checkbox

    Radio

    JS + CSS

    Checkbox

    Radio

提交回复
热议问题