Saltar al contenido

html – Cómo diseñar una casilla de verificación usando CSS

septiembre 23, 2021
apple touch icon@2

¡Ay! Todas estas soluciones me han llevado a la conclusión de que la casilla de verificación HTML apesta si quieres darle estilo.

Como advertencia, esta no es una implementación de CSS. Solo pensé en compartir la solución que se me ocurrió en caso de que alguien más pudiera encontrarla útil.


Usé el HTML5 canvas elemento.

La ventaja de esto es que no tiene que usar imágenes externas y probablemente pueda ahorrar algo de ancho de banda.

La desventaja es que si un navegador por alguna razón no puede representarlo correctamente, entonces no hay respaldo. Aunque es discutible si esto sigue siendo un problema en 2017.

Actualizar

Encontré el código antiguo bastante feo, así que decidí reescribirlo.

Object.prototype.create = function(args){
    var retobj = Object.create(this);

    retobj.constructor(args || null);

    return retobj;
}

var Checkbox = Object.seal({
    width: 0,
    height: 0,
    state: 0,
    document: null,
    parent: null,
    canvas: null,
    ctx: null,

    /*
     * args:
     * name      default             desc.
     *
     * width     15                  width
     * height    15                  height
     * document  window.document     explicit document reference
     * target    this.document.body  target element to insert checkbox into
     */
    constructor: function(args){
        if(args === null)
            args = {};

        this.width = args.width || 15;
        this.height = args.height || 15;
        this.document = args.document || window.document;
        this.parent = args.target || this.document.body;
        this.canvas = this.document.createElement("canvas");
        this.ctx = this.canvas.getContext('2d');

        this.canvas.width = this.width;
        this.canvas.height = this.height;
        this.canvas.addEventListener("click", this.ev_click(this), false);
        this.parent.appendChild(this.canvas);
        this.draw();
    },

    ev_click: function(self){
        return function(unused){
            self.state = !self.state;
            self.draw();
        }
    },

    draw_rect: function(color, offset){
        this.ctx.fillStyle = color;
        this.ctx.fillRect(offset, offset,
                this.width - offset * 2, this.height - offset * 2);
    },

    draw: function(){
        this.draw_rect("#CCCCCC", 0);
        this.draw_rect("#FFFFFF", 1);

        if(this.is_checked())
            this.draw_rect("#000000", 2);
    },

    is_checked: function(){
        return !!this.state;
    }
});

Aquí está un demostración de trabajo.

La nueva versión utiliza prototipos y herencia diferencial para crear un sistema eficiente para crear casillas de verificación. Para crear una casilla de verificación:

var my_checkbox = Checkbox.create();

Esto agregará inmediatamente la casilla de verificación al DOM y conectará los eventos. Para consultar si una casilla de verificación está marcada:

my_checkbox.is_checked(); // True if checked, else false

También es importante tener en cuenta que me deshice del bucle.

Actualización 2

Algo que olvidé mencionar en la última actualización es que usar el lienzo tiene más ventajas que simplemente hacer una casilla de verificación que se vea como usted quiere que se vea. También podrías crear multiestado casillas de verificación, si así lo desea.

Object.prototype.create = function(args){
    var retobj = Object.create(this);

    retobj.constructor(args || null);

    return retobj;
}

Object.prototype.extend = function(newobj){
    var oldobj = Object.create(this);

    for(prop in newobj)
        oldobj[prop] = newobj[prop];

    return Object.seal(oldobj);
}

var Checkbox = Object.seal({
    width: 0,
    height: 0,
    state: 0,
    document: null,
    parent: null,
    canvas: null,
    ctx: null,

    /*
     * args:
     * name      default             desc.
     *
     * width     15                  width
     * height    15                  height
     * document  window.document     explicit document reference
     * target    this.document.body  target element to insert checkbox into
     */
    constructor: function(args){
        if(args === null)
            args = {};

        this.width = args.width || 15;
        this.height = args.height || 15;
        this.document = args.document || window.document;
        this.parent = args.target || this.document.body;
        this.canvas = this.document.createElement("canvas");
        this.ctx = this.canvas.getContext('2d');

        this.canvas.width = this.width;
        this.canvas.height = this.height;
        this.canvas.addEventListener("click", this.ev_click(this), false);
        this.parent.appendChild(this.canvas);
        this.draw();
    },

    ev_click: function(self){
        return function(unused){
            self.state = !self.state;
            self.draw();
        }
    },

    draw_rect: function(color, offsetx, offsety){
        this.ctx.fillStyle = color;
        this.ctx.fillRect(offsetx, offsety,
                this.width - offsetx * 2, this.height - offsety * 2);
    },

    draw: function(){
        this.draw_rect("#CCCCCC", 0, 0);
        this.draw_rect("#FFFFFF", 1, 1);
        this.draw_state();
    },

    draw_state: function(){
        if(this.is_checked())
            this.draw_rect("#000000", 2, 2);
    },

    is_checked: function(){
        return this.state == 1;
    }
});

var Checkbox3 = Checkbox.extend({
    ev_click: function(self){
        return function(unused){
            self.state = (self.state + 1) % 3;
            self.draw();
        }
    },

    draw_state: function(){
        if(this.is_checked())
            this.draw_rect("#000000", 2, 2);

        if(this.is_partial())
            this.draw_rect("#000000", 2, (this.height - 2) / 2);
    },

    is_partial: function(){
        return this.state == 2;
    }
});

Modifiqué ligeramente el Checkbox utilizado en el último fragmento para que sea más genérico, lo que permite «extenderlo» con una casilla de verificación que tiene 3 estados. Aquí está una demostración. Como puede ver, ya tiene más funciones que la casilla de verificación incorporada.

Algo a tener en cuenta al elegir entre JavaScript y CSS.

Código antiguo y mal diseñado

Demo de trabajo

Primero, configure un lienzo

var canvas = document.createElement('canvas'),
    ctx = canvas.getContext('2d'),
    checked = 0; // The state of the checkbox
canvas.width = canvas.height = 15; // Set the width and height of the canvas
document.body.appendChild(canvas);
document.body.appendChild(document.createTextNode(' Togglable Option'));

A continuación, idee una forma de actualizar el lienzo.

(function loop(){
  // Draws a border
  ctx.fillStyle="#ccc";
  ctx.fillRect(0,0,15,15);
  ctx.fillStyle="#fff";
  ctx.fillRect(1, 1, 13, 13);
  // Fills in canvas if checked
  if(checked){
    ctx.fillStyle="#000";
    ctx.fillRect(2, 2, 11, 11);
  }
  setTimeout(loop, 1000/10); // Refresh 10 times per second
})();

La última parte es hacerlo interactivo. Afortunadamente, es bastante simple:

canvas.onclick = function(){
  checked = !checked;
}

Aquí es donde puede tener problemas en IE, debido a su extraño modelo de manejo de eventos en JavaScript.


Espero que esto ayude a alguien; definitivamente se adaptaba a mis necesidades.

close