pseudo elementos clases html5 validation usability

html5 - clases - pseudo elementos css



Demora HTML5: pseudo-clase inválida hasta el primer evento (9)

Al usar la validación de formularios HTML5, intente usar el navegador para detectar envíos / campos no válidos, en lugar de reinventar la rueda.

Escuche si el evento invalid agrega una clase de "no válido" a su formulario. Con la clase ''no válida'' agregada, puede ir a la ciudad con el estilo de su formulario usando CSS3 :pseudo selectores.

Por ejemplo:

// where myformid is the ID of your form var myForm = document.forms.myformid; var checkCustomValidity = function(field, msg) { if(''setCustomValidity'' in field) { field.setCustomValidity(msg); } else { field.validationMessage = msg; } }; var validateForm = function() { // here, we''re testing the field with an ID of ''name'' checkCustomValidity(myForm.name, ''''); if(myForm.name.value.length < 4) { checkCustomValidity( // alerts fields error message response myForm.name, ''Please enter a valid Full Name, here.'' ); } }; /* here, we are handling your question above, by adding an invalid class to the form if it returns invalid. Below, you''ll notice our attached listener for a form state of invalid */ var styleInvalidForm = function() { myForm.className = myForm.className += '' invalid''; } myForm.addEventListener(''input'', validateForm, false); myForm.addEventListener(''keyup'', validateForm, false); myForm.addEventListener(''invalid'', styleInvalidForm, true);

Ahora, simplemente diseñe su formulario como mejor le parezca según la clase ''no válida'' que hayamos adjuntado.

Por ejemplo:

form.invalid input:invalid, form.invalid textarea:invalid { background: rgba(255, 0, 0, .05); border-color: #ff6d6d; -webkit-box-shadow: 0 0 6px rgba(255, 0, 0, .35); box-shadow: 0 0 6px rgba(255, 0, 0, .35); }

Recientemente descubrí que la pseudoclase :invalid aplica a required elementos de formulario required tan pronto como se carga la página. Por ejemplo, si tienes este código:

<style> input:invalid { background-color: pink; color: white; } input:valid { background-color: white; color: black; } </style> … <input name="foo" required />

Luego, su página se cargará con un elemento de entrada rosa vacío. Tener la validación incorporada en HTML5 es excelente, pero no creo que la mayoría de los usuarios esperen que el formulario valide antes de que hayan tenido la oportunidad de ingresar ningún valor. ¿Hay alguna manera de retrasar la aplicación de la pseudoclase hasta que el primer evento afecte a ese elemento (envío de formulario, desenfoque, cambio, lo que sea apropiado)? ¿Es posible hacer esto sin JavaScript?


Creé una pequeña cuña para tratar esto en mi código base. Solo empiezo con mi elemento <form/> que tiene la propiedad novalidate junto con un atributo data-validate-on="blur" . Esto mira para el primer evento de ese tipo. De esta forma, aún puede usar los selectores nativos :invalid CSS :invalid para el diseño del formulario.

$(function () { $(''[data-validate-on]'').each(function () { var $form = $(this); var event_name = $form.data(''validate-on''); $form.one(event_name, '':input'', function (event) { $form.removeAttr(''novalidate''); }); }); });


Estas respuestas están desactualizadas. Ahora puede hacer esto al buscar una pseudoclase de marcador de posición con CSS.

input:not(:placeholder-shown):invalid { background-color: salmon; }

<form> <input type="email" placeholder="[email protected]" required> </form>

Comienza con un fondo normal y se vuelve rosa al ingresar tu dirección de correo electrónico incompleta.


Esto no es posible en CSS puro, pero se puede hacer con JavaScript. Este es un ejemplo de jQuery :

// use $.fn.one here to fire the event only once. $('':required'').one(''blur keydown'', function() { console.log(''touched'', this); $(this).addClass(''touched''); });

/** * All required inputs initially are yellow. */ :required { background-color: lightyellow; } /** * If a required input has been touched and is valid, it should be white. */ .touched:required:valid { background-color: white; } /** * If a required input has been touched and is invalid, it should be pink. */ .touched:required:invalid { background-color: pink; }

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <p> <label> Name: <input type="text" required> *required </label> </p> <p> <label>Age: <input type="text"> </label> </p>


Hay un evento invalid html5 que se activa en los elementos del formulario antes de que se produzca el evento submit para cada elemento que no pasa checkValidity. Puede usar este evento para aplicar una clase, por ejemplo, a la forma y visualización circundantes: estilos inválidos solo después de que ocurra este evento.

$("form input, form select, form textarea").on("invalid", function() { $(this).closest(''form'').addClass(''invalid''); });

Su CSS se vería así:

:invalid { box-shadow: none; } .invalid input:invalid, .invalid textarea:invalid, .invalid select:invalid { border: 1px solid #A90909 !important; background-color: #EEC2C2; }

La primera línea elimina el estilo predeterminado, por lo que los elementos del formulario se ven neutros en la carga de la página. Tan pronto como se activa el evento no válido (cuando un usuario intenta enviar el formulario), los elementos se vuelven visiblemente inválidos.


Mozilla se ocupa de esto con su propia pseudoclass :-moz-ui-invalid que solo se aplica a los formularios después de que han sido interactuados. MDN no recomienda usar esto debido a la falta de soporte. Sin embargo, puedes modificarlo para Firefox.

Existe una especificación de nivel 4 para una especificación de :user-invalid en el horizonte que ofrecerá un comportamiento similar.

Lo siento si esto no ayuda, pero espero que ofrezca algún contexto.


Podrías hacer que solo los elementos que tienen una determinada clase en ellos y son obligatorios, sean de color rosa. Agregue un controlador de eventos a cada elemento requerido que agregue esa clase cuando abandone el elemento.

Algo como:

<style> input.touched:invalid { background-color: pink; color: white; } input.touched:valid { background-color: white; color: black; } </style> <script> document.addEventListener(''DOMContentLoaded'', function() { var required = document.querySelectorAll(''input:required''); for (var i = 0; i < required.length; ++i) { (function(elem) { function removeClass(name) { if (elem.classList) elem.classList.remove(name); else elem.className = elem.className.replace( RegExp(''(^|//s)//s*'' + name + ''(?://s+|$)''), function (match, leading) {return leading;} ); } function addClass(name) { removeClass(name); if (elem.classList) elem.classList.add(name); else elem.className += '' '' + name; } // If you require a class, and you use JS to add it, you end up // not showing pink at all if JS is disabled. // One workaround is to have the class on all your elements anyway, // and remove it when you set up proper validation. // The main problem with that is that without JS, you see what you''re // already seeing, and stuff looks hideous. // Unfortunately, you kinda have to pick one or the other. // Let non-blank elements stay "touched", if they are already, // so other stuff can make the element :invalid if need be if (elem.value == '''') addClass(''touched''); elem.addEventListener(''blur'', function() { addClass(''touched''); }); // Oh, and when the form submits, they need to know about everything if (elem.form) { elem.form.addEventListener(''submit'', function() { addClass(''touched''); }); }; })(required[i]); } }); </script>

Y, por supuesto, no funcionará como en IE8 o inferior, ya que (a) DOMContentLoaded es relativamente nuevo y no era estándar cuando salió IE8, (b) IE8 usa attachEvent lugar de DOM-standard addEventListener , y ( c) IE8 no va a importar :required todos modos, ya que técnicamente no es compatible con HTML 5.


Una buena forma es abstraer :invalid, :valid con clases de CSS y luego algo de JavaScript para verificar si el campo de entrada fue enfocado o no.

CSS:

input.dirty:invalid{ color: red; } input.dirty:valid{ color: green; }

JS:

// Function to add class to target element function makeDirty(e){ e.target.classList.toggle(''dirty''); } // get form inputs var inputs = document.forms[0].elements; // bind events to all inputs for(let input of inputs){ input.addEventListener(''invalid'', makeDirty); input.addEventListener(''blur'', makeDirty); input.addEventListener(''valid'', makeDirty); }

DEMO


http://www.alistapart.com/articles/forward-thinking-form-validation/

Como solo queremos indicar que un campo no es válido una vez que tiene el foco, usamos la pseudoclase de enfoque para activar el estilo no válido. (Naturalmente, marcar todos los campos requeridos como no válidos desde el principio sería una opción de diseño deficiente).

Siguiendo esta lógica, su código se vería algo como esto ...

<style> input:focus:required:invalid {background-color: pink; color: white;} input:required:valid {background-color: white; color: black; } <style>

Creado un violín aquí: http://jsfiddle.net/tbERP/

Como supondrás, y como verás en el violín, esta técnica solo muestra el estilo de validación cuando el elemento tiene foco. Tan pronto como alejas el foco, el estilo se elimina, independientemente de si es válido o no. No es ideal de ninguna manera.