I'm creating custom button that is similar to the default button from bootstrap, but I'm doing it manually and set its properties myself.
The button gets activated when function returns true. In button css I have used such events like .menuEnter , .menuEnter:disabled, .menuEnter:hover, .menuEnter:active.
But the problem is that :hover and :active events work even when the button is disabled. How to do that these events wouldn't work and style wouldn't change while the button is disabled? See the txt file:
#What to do that custom button stylings events wouldn't work while the button is disabled?
1 messages · Page 1 of 1 (latest)
The good thing is that JavaScript button submit function is not starting while the button is disabled. The bad thing is that events styling still work.
What to do that custom button stylings events wouldn't work while the button is disabled?
You can use the :disabled pseudo-selector to achieve higher specificity and override things from the :hover and :active states, like ```css
button:disabled {
color: black;
}
button:hover {
color: red;
}
button:disabled:hover {
color: black;
}
Or you can use the `:not()` pseudo-selector to only apply those styles when not disabled: ```css
button:disabled {
color: black;
}
button:not(:disabled):hover {
color: red;
}
Looks like we can add more specific events in chain. Nice.
I did it a bit differently and it works as I want. Hover and active events now work only when the button is not disabled:
.menuEnter:hover:enabled {
background-color: black;
color:white;
}
.menuEnter:active:enabled{
background-color:green;
}
Just as an FYI, they're called pseudo-selectors. CSS has no concept of events. 🙂
@crimson scaffold How to use pseudo-selectors inline?
Inline? Like, in a style attribute?
yea
.menuEnter:active:enabled{
background-color:green;
}
this to this:
<button
className="menuEnter"
onClick={handleMenuSubmit}
style={ buttonChangeColorOnMenuSend !== 0 ? buttonChangeColorOnMenuSend === 201 ?
{ backgroundColor: "green" } :
{ backgroundColor: "red" } :
{ backgroundColor: "white" }
}
id="btnCheckCanteenField"
disabled={!checkAllFields()}
>
Įvesti
</button>
because now the white background overwrites the App.css hovering style
And I need to also set button background style depeding on the received state buttonChangeColorOnMenuSend
which come from axios call and can be 0, 200, 201 404 409 etc
but after a short period of time it is always set to 0
In other words when we press the button then if response is good the button shortly flases in green
then is set to white
if response is 404 then the button flases to red
and then becomes white
I'm using React.js for frontend UI + Java Spring boot for backend.
JSX is similar to javascript but also includes xml.
You can't select with a pseudo-selector in style, since using style foregoes selectors entirely and puts the rules directly on the element. You should instead bind your reactive data to one of several classes and use that for your styling instead.
I created three different styles and then chosen it depending on the state:
<button
className={
buttonChangeColorOnMenuSend !== 0 ? buttonChangeColorOnMenuSend === 201 ?
"menuEnter--green" :
"menuEnter--red" :
"menuEnter"
}
onClick={handleMenuSubmit}
id="btnCheckCanteenField"
disabled={!checkAllFields()}
>
Submit
</button>
.menuEnter {
background-color: white;
border: black;
color: black;
margin: -5px 10px;
padding: 0px 10px 3px;
border-width: 1px;
border-style: solid;
border-radius: 5px;
text-align: center;
text-decoration: none;
display: grid;
float: right;
font-size: 16px;
cursor: pointer;
}
.menuEnter:disabled{
background-color: white;
border: gray;
color: grey;
margin: -5px 10px;
padding: 0px 10px 3px;
border-width: 1px;
border-style: solid;
border-radius: 5px;
text-align: center;
text-decoration: none;
display: grid;
float: right;
font-size: 16px;
}
.menuEnter:hover:enabled {
background-color: black !important;
color:white;
}
.menuEnter--green {
background-color:green;
border: black;
color: black;
margin: -5px 10px;
padding: 0px 10px 3px;
border-width: 1px;
border-style: solid;
border-radius: 5px;
text-align: center;
text-decoration: none;
display: grid;
float: right;
font-size: 16px;
cursor: pointer;
}
.menuEnter--red {
background-color:red;
border: black;
color: black;
margin: -5px 10px;
padding: 0px 10px 3px;
border-width: 1px;
border-style: solid;
border-radius: 5px;
text-align: center;
text-decoration: none;
display: grid;
float: right;
font-size: 16px;
cursor: pointer;
}
And now it works as it should.
Hover event style background had to be !important or React would still choose white background. The button is by default white. When we hover it becomes black. In these complicated circumstances the !important ensures which background is chosen in .menuEnter className.
You have a lot of repeated styles... You know you can have multiple classes on an element, right? So you can define base styles and only override the ones you need to. Also, I'd try and find an alternative approach to !important. It's a footgun.
This should work as is, unless I'm not understanding the problem.
.menu-enter {
background-color: white;
color: black;
margin: -5px 10px;
padding: 0 10px 3px;
border: 1px solid black;
border-radius: 5px;
font-size: 16px;
text-align: center;
text-decoration: none;
display: grid;
cursor: pointer;
float: right;
}
.menu-enter:disabled {
border-color: gray;
color: gray;
}
.menu-enter:enabled:hover {
background-color: black;
color: white;
}
/* Style both other ones at once, but don't override
* the :disabled styles */
.menu-enter.menu-enter-red:not(:disabled),
.menu-enter.menu-enter-green:not(:disabled) {
border-color: black;
color: white;
}
.menu-enter.menu-enter-green {
background-color: green;
}
.menu-enter.menu-enter-red {
background-color: red;
}
And then set className to class="menu-enter menu-enter-red" to get both sets of styles at once.
@crimson scaffold Thank you very much for this. Now I know that I don't need to rewrite the same class again to create a new class with some changed properties. I can override the main class and change some properties of the main class in a subclass. I just have to extend the main class writing a subclass that is separated by a comma: .menu-enter.menu-enter-green. However in my particular situation this still didn't worked. I had to add:
.menu-enter.menu-enter-green:enabled {
background-color: green;
}
.menu-enter.menu-enter-red:enabled {
background-color: red;
}
:enabled pseudo-selectors.
But a proper use of the :hover pseudo-selector on the enabled element really eliminated the need to use !important rule for the background property.
.menu-enter:enabled:hover {
background-color: black;
color: white;
}
It is also important not to override disabled element styles using the :not(:disabled) part.
And the actual use for the button styles is this:
<button
className={
buttonChangeColorOnMenuSend !== 0 ? buttonChangeColorOnMenuSend === 201 ?
"menu-enter menu-enter-green" :
"menu-enter menu-enter-red" :
"menu-enter"
}
onClick={handleMenuSubmit}
id="btnCheckCanteenField"
disabled={!checkAllFields()}
>
Submit
</button>