Home > database >  How to restructure this html label/article and avoid validator "errors"?
How to restructure this html label/article and avoid validator "errors"?

Time:09-03

Related to this previous question of mine, I come to you today with a HTML structure problem.

HTML CODE

       <label>  
          <article >
            <input type="checkbox"  value="1">
            <div >
              <div >
                <h3 >Velouté de légumes d'antan</h3>
                <p >Carotte, panais, topinambour</p>
              </div>
              <p > 35€</p>
            </div>
            <div >
              <span >check_circle</span>
            </div>
          </article>
        </label>  

Problem to solve

The W3C html validator tells me this :

Error: Element article not allowed as child of element label in this context. (Suppressing further errors from this subtree.)

What did I try so far to solve this issue ?

Not much, I wasted a lot of time turning the problem upside down and eventually I came to exchange label and article tags but then further error messages show up in the validator such as the one quoted above but with "div" not being allowed as child element of "label", etc.

Important things regarding this code

If you checked the link provided at the beginning of this post, you'll see that the container has an animation triggered by clicking on a hidden check-box with the help of the label that help the whole container to be clickable.

And that's what matters here the most, that the whole capsule remains clickable whatever the changes that must be done in order to pass the validator without error.

Thank you for reading me so far and for any help you may provide to me,

I'm of course at your disposal for any further information that may be needed to solve this small issue.

Regards,

Elrad

CodePudding user response:

A <label> Element is normally used alongside <input> elements, in order to explain what the input is for. But not for wrapping entire parts to just make them clickable.

My guess is, you only need the label in order to trigger the state of the input field? Then you can try it like this:

  1. remove the label entirely (or replace it with a <div>
  2. make your field position absolute and full height/width, so it's the same size as your article element. Also opacity to zero so you don't see it
  3. article element needs to be position relative

This way, the input field is as big as the whole article element and doesn't matter where you click, you always trigger the select field.

Stylings for each element: input

    display: block;
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    opacity: 0;

.m__item (your article)
position: relative;

.m__plats {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.m__plats .m__item {
  background: white;
  border-radius: 15px;
  box-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;
  display: flex;
  position: relative;
}
.m__plats .m__info {
  padding: 10px;
  max-width: 100%;
  overflow: hidden;
  flex: 1;
  display: flex;
  justify-content: space-between;
  gap: 16px;
}
.m__plats .m__info .m__texte {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: hidden;
  white-space: nowrap;
}
.m__plats .m__info .m__texte .m__titre {
  font-size: 16px;
  font-weight: bold;
  margin: 0;
  text-overflow: ellipsis;
  overflow: hidden;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
}
.m__plats .m__info .m__texte .m__details {
  font-weight: 200;
  font-size: 14px;
  margin: 3px 0;
  text-overflow: ellipsis;
  line-clamp: 1;
  text-overflow: ellipsis;
  overflow: hidden;
  -webkit-line-clamp: 1;
}
.m__plats .m__info .m__prix {
  display: flex;
  align-items: flex-end;
  margin-bottom: 0;
  font-weight: bold;
}
label {
  cursor: pointer;
}
.m__selection {
  cursor: pointer;
  background: #99e2d0;
  height: auto;
  width: 0;
  max-width: 15%;
  opacity: 0;
  border-radius: 0 15px 15px 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.4s ease-in-out, width 0.4s ease-in-out, opacity 0.4s ease-in-out;
}
.m__selection .material-icons {
  font-family: 'Material Icons';
  font-weight: normal;
  font-style: normal;
  font-size: 30px;
  line-height: 1;
  letter-spacing: normal;
  text-transform: none;
  display: inline-block;
  white-space: nowrap;
  word-wrap: normal;
  direction: ltr;
}
.m__selection .check__icon {
  font-size: 30px;
  color: white;
  transform: rotate(0deg);
  transition: 0.4s ease-in-out;
}
#m__switch {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  opacity: 0;
}
#m__switch:checked ~ .m__selection {
  opacity: 100%;
  width: 7rem;
  transition: transform 0.4s ease-in-out, width 0.4s ease-in-out, opacity 0.4s ease-in-out;
}
.check__icon {
  animation: m__rotate 2s linear 1;
}
@keyframes m__rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
  <body>
    <div >
      <div  id="entrées">
        <div>
          <article >
            <input type="checkbox" id="m__switch" value="1">
            <div >
              <div >
                <h3 >Ravioles de foie gras</h3>
                <p >Accompagnés de leur crème à la truffe</p>
              </div>
              <p > 25€</p>
            </div>
            <div >
              <span >V</span>
            </div>       
          </article>
      </div>
      </div>  
    </div>  
  </body>

Note: There's a drawback!
The problem with this solution is, that the user can't select and copy any text inside your <article> element, because the input field is overlapping all the text. If that's not a problem, go with it. If it's a problem, you may should consider adding a small javascript click event which is adding a class to trigger your animation.

  •  Tags:  
  • html
  • Related