How to make a label use my button layout

I am using a pre-made modal window component that uses a label to be clicked on to activate a checkbox input.

The component is called modal here, it has the source js and css.

It works Now I would like my label to look like all my other buttons. However, int the HTML specification, for label, it says that if a label contains an interactive element like a button, the button should not activate the label.

I cannot just put the css class on the label since clicking on a button has some animations included in the itself.

WHat is the most element solution? To break the HTML spec with a button inside the label?
TO make a button outside the label with a onlick handler that forwards the click?
To refactor the premade component? BEcause the ckecked is iused as a data-attribute and can be replaced?

Maybe elctro bear or PaulOB knows? We talked abouty lbels recently…

I’d like to see a demo of your page but it sounds like a non issue to me as you can style most html elements to look like what you want. You can style a span inside a label to look like a button. You don’t need to add the button itself.

The example of a modal on the page you linked to is invalid anyway as you can’t put a div inside a label element.

Hi there tvilmart,

does this example help…

<!DOCTYPE HTML>
<html lang="en">
<head>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">

<title>untitled document</title>

<link rel="stylesheet" href="screen.css" media="screen">

<style media="screen">

body {
    background-color: #f0f0f0;
    font: 100% / 162% verdana, arial, helvetica, sans-serif;
 }

.modal-label{
    display: inline-block;
    line-height: 2.2em;
    padding: 0 0.62em;
    border: 1px solid #666;
    border-radius: 0.25em;
    background-image: linear-gradient( to bottom, #fff, #ccc );
    box-shadow: inset 0 0 0.1em #fff, 0.2em 0.2em 0.2em rgba( 0, 0, 0, 0.3 );
    font-family: arial, sans-serif;
    font-size: 0.8em;
 }

.modal-label:hover {
    border-color: #3c7fb1;
    background-image: linear-gradient( to bottom, #fff, #a9dbf6 );
 }

.modal-label:focus {
    padding: 0  0.56em 0 0.68em;
 }

</style>

</head>
<body> 

 <label for="modal-1" class="modal-label" tabindex="1">Click for Modal</label>

 <input class="modal-state" id="modal-1" type="checkbox">

</body>
</html>

coothead

If I understand your solution, you are making the label look like a button.

I see 2 problems:

  • Perhaps label and button have differences that may have an impact. For example, label in the general case is used for accessibility as fallback. The button layout might have effects that disabled people cannot read.
  • there is no animation when one clicks on the button. THe animation of a button is enclosed in the element and not managed by padding in css. THe animatoin makes the button move to the right during the click. With you CSS solution adding padding, the global width is increased temporarily. I think the HTML button uses negative padding when being clicked.

Why is it preferable to use this solution compared to another like having a separate button that forwards the clicks to the input?

Can any HTML element suddenly be made look like a button using CSS without unexpected side effects?

Hi there tvilmart,

Unfortunately, you did not indicate how your “other buttons” were actually styled. :wonky:

Consequently, I just coded a “label element” to look like a basic “button element”. :winky:

Your vision, is obviously much better than mine. :sunglasses:

I am unable to see any problems. :unhappy:

coothead

ANd what about the HTML spec that says a span or button inside a label (an interactive element) cannot affect the label actions?

https://w3c.github.io/html/sec-forms.html#ref-for-interactive-content-2â‘ â‘ 
I quote:
“If a label element has interactive content other than its labeled control, the activation behavior of the label element for events targeted at those interactive content descendants and any descendants of those must be to do nothing.”

Is it in the HTML spec that one cannot put a div inside a label? I could not find.

I’m confused. Looking like a button and having the usual action of a button seem to be different things.

For me, other than “identifying” an input, a label has the “action” of giving focus to its input.

So sure, you could style the label, but you can’t have it do other than give focus to its input.

As I believe most people would expect a button to do other than that, it doesn’t make sense to me to have them look like buttons. A “matching look” or whatever it would be called could make sense though.

coothead,

2 “potential” problems:

I mean I want to use a generic css class. I am not sure I can use it on any element. For example, for accessiblity issues.

There is a problem if you click and it increases the padding. It means that the things to the right of the label will be shifted to the right.

Validate the page and you will see something like this…

coothead

2 Likes

Why do the original component uses a checkbox?

Then they can use the :checked pseudo-class attribute. But the same can be achieved by using a data attribute. Is it more portable? Why do they chose to use a checkbox and not a data attribute? There must be a reason.

It seems to me the simplest solution is to have a button that changes a data attribute “data-model-opened” on the div <div class="modal-fade-screen">.

EDit: I think I found the reason they use a checkbox. SO when we click on the background, the focus is lost, and triggers a layout change.

No you don’t :eek:

https://www.w3.org/QA/Tips/goodclassnames

No there isn’t :rolleyes:

coothead

IF code is the same, it must be reused.

I have a placeholder not a class for buttons. Something with a %. Then IF I want different buttons, I use both the placeholder and custom button.

My concern was can the placeholder originally used for a button be used on another element type like a label. IT is like with images for disabled people. IF people cannot see colors, the browser has a mode to only show text with something like a label as attribute of the image. Maybe the button layout on the label puts lots of colots that affect this accessibility issue.

padding will move the label and everything to the right of it. Well it seems to me. ANd if it is so then there is a problem.

AS I explain in previous post, the label and input I used to use the :focus to show or not the modal.

You obviously missed lesson one on html where inline elements cannot contain block elements. Just paste it into the validator to see for yourself.

Unfortunately the rest of your comments are largely mis-informed and show a lack of in depth knowledge on the subject.

As I am out today and on a mobile only I will reply in depth tomorrow as you have a lot of incorrect assumptions that need to be corrected :slight_smile:

Nice. That will be interesting. I do admit a certain confusion as regards the appropriate solution.

Why do you suggest to use a span inside the label instead of using the label itself with a button-like layout?
WHat about the click animation? SHould it be designed in css using padding? ANd will it not shift the element to the right?

Can we see a demo of your page as we are guessing what you mean most of the time? (It’s no good linking to someone else’s demo.)

It seems like you are using the checked:: pseudo class method to open a modal. It will make no difference if the label is styled like a button or whatever.

No that site is using the css :checked pseudo class on the checkbox to enable the modal to be opened without js.

.refills-components .modal .modal-state:checked + .modal-fade-screen {
  opacity: 1;
  visibility: visible; }

However they are using JS to switch the modal off so the technique is pointless to a degree (and also invalid because of the div inside the label that I already mentioned).

Because you said you couldn’t add the class to a label for some strange reason?

What click animation?

You need to start showing us what you are working on otherwise this all makes no sense :slight_smile:

1 Like

The label is activating the checkbox exactly like it should and the fact that the checkbox is checked enables the modal to be opened . There is no conflict here. The label can look however you want it to look.

OK thanks for the clarifications. I learnt a lot in this thread.

As you requested, here is a codepen with the solution.

And the original copy paste from bourbon refills is here:

I don’t have issues now.

I could see the “other button” I added with a reset/normalize has no padding animation. So there is no padding as part of button itself as I thought or wrongly remembered.

If you have suggestion on how to improve this solution, I am interested.

Mittineague had a good point that a button would be more relevant than a label with a checkbox. I just found it good enough with the checkbox. Perhaps there are some corner cases they thought about that are better solved with a checkbox and label.

THen I have another issue. Would it be better to havea button inside the label since a button is more semantically correct for clicking on a button with a button-like layout? IF we assume, we want a button inside the label, would it not contradiction the HTML spec that I quoted above? a button inside a label cannot trigger an action on the label itself.

If I have a label, and a button inside the label, can I use the onclick js event of the button to trigger a click on the label?

I quote again the potential conflict I found:

first reported here:

HTML spec:

https://w3c.github.io/html/sec-forms.html#ref-for-interactive-content-2â‘ â‘ 3
I quote:
“If a label element has interactive content other than its labeled control, the activation behavior of the label element for events targeted at those interactive content descendants and any descendants of those must be to do nothing.”

You have an error in your html as you have this:

<div class="modal-close" for="<modal-></modal->1"></div>

That line is supposed to be a modal close method for use when js is not present and needs to be a label that refers to the original checkbox to toggle its state back off so that the css removes the modal. The js you have is an enhancement if js is disabled (or the browser doesn’t understand the checkbox hack) and then the js takes over.

The code you should have used is this:

<label class="modal-close" for="modal-1"></label>

You can test this by removing the js and then seeing that the modal still works and then toggles off only when the close icon is clicked.

There is no conflict with having the label look like a button and you don’t want a real button because that is invalid and confusing. The html needs to make sense for assisted users (screenreaders and keyboard users etc) and having a button inside a label would be a nightmare. Sighted users can see what looks like a button and click it without problem so all are satisfied. Do not confuse what an element looks like with its html function. The html structure must always be correct firstly.

You misunderstand the context of the example you are using as I have mentioned a few times. The checkbox hack is being used so that users without js enabled can still have a modal experience. The checkbox hack is a little hacky and has problems in older android which is obviously why the js has been added to cater for them. However it does work well in modern browsers. I would have instead preferred to use :target instead of :checked which does not abuse form elements but comes with its own set of issues to cater for.

Note also that your fixed positioned modal is inaccessible on smaller windows as it goes below the fold and cannot be scrolled.

We’ve already addressed that point and you don’t need a button at all. If you weren’t using the checkbox hack then you could simply have used a button without a label to complete the action. Of course that means that it has to be js enabled only.