javascripthtmlcssmousehover

Background image of button disappears when I add text?


I'm trying to make a button that has an image background and text. The text should be invisible and the bg image should be opaque. When you hover the button, the background should go black and the text appear at the same time, with a fading transition, but I cant get only one to display at a time.

I tried adding the text inside the tablet div, seperate to the code_block div but it just displays beside the image. Then I tried adding the text inside the code_block div and it made the image disappear completely. I know I need to have the text display set as none until I hover over it, but I'm not sure how to set the display to block when I want it to display.

Here's the HTML:

    <div class="content_container">
        <div class="tablet"><p id="text">Text</p><div id="code_block"></div></div>
        <div class="tablet"></div>
        <div class="tablet"></div>
        <div class="tablet"></div>
    </div>

And here's the css:

.content_container {
    display: flex;
    justify-content: space-evenly;
}
.tablet {
    display: inline-flex;
    margin-top: 5vh;

    /*Height restraints*/
    height: var(--medium);
    max-height: var(--med-ub);
    min-height: var(--med-small-lb);

    /*Width restraints*/
    width: var(--med-large);
    max-width: var(--med-large-ub);
    min-width: var(--med-large-lb);

    /*Margins*/
    margin-right: 1vw;
    margin-left: 1vw;

    background-color: var(--primary_colour);
    border: solid 1px var(--tirtiary_colour);
    border-radius: 1vw;

    transition: 1s;
}
#code_block {
    opacity: 1;
    background-image: url("img/code_pic.png");
    background-color: rgba(0,0,0,0.5);
    background-size: cover;
    background-repeat: no-repeat;
    transition: opacity 1s ease;
}
#code_block:hover {
    opacity: 0;
    transition: opacity 1s ease;
}
.tablet:hover {
    width: var(--large);
    height: var(--medium);
    transition: 1s;
}
#text {
    display: none;
}
#text:hover {
    display: block;
}

Solution

  • Going with the code you provided (and with defining the CSS variables which were not defined in your code), you can do it like this. The comments are within the code (CSS), an they begin with this is new.

    /* this is new - I'm guessing you have your CSS variables defined, just not posted in your
    example code. I've added them here for testing purposes
    */
    :root {
      --medium: 75px;
      --med-ub: 150px;
      --med-small-lb: 37px;
      --med-large: 90px;
      --med-large-ub: 120px;
      --med-large-lb: 25px;
      --large: 80px;
      --primary_colour: rgba(37,168,219,1);
      --tirtiary_colour: rgba(37,100,219,1);
    }
    
    .content_container {
        display: flex;
        justify-content: space-evenly;
    }
    .tablet {
        display: inline-flex;
        margin-top: 5vh;
    
        /*Height restraints*/
        height: var(--medium);
        max-height: var(--med-ub);
        min-height: var(--med-small-lb);
    
        /*Width restraints*/
        width: var(--med-large);
        max-width: var(--med-large-ub);
        min-width: var(--med-large-lb);
    
        /*Margins*/
        margin-right: 1vw;
        margin-left: 1vw;
    
        background-color: var(--primary_colour);
        border: solid 1px var(--tirtiary_colour);
        border-radius: 1vw;
    
        transition: 1s;
        /* this is new - needed for centering the #text */
        position:relative;
        text-align: center;
    }
    #code_block {
        opacity: 1;
        /* this is new - provided an image link for testing purposes, you will use your own */
        background-image: url("https://placehold.co/600x400/F23/99FFAC");
        /* this is new - provided to prevent the bg img from spilling out due to .tablet border radius */
        border-radius: 1vw;
        /* this is not needed */
        /*background-color: rgba(0,0,0,0.5);*/
        background-size: cover;
        background-repeat: no-repeat;
        /* this is new - just a personal preference */
        background-position: center;
        transition: opacity 1s ease;
        /* this is new - added because your #code_block will not be showing, as it has no content */
        height: 100%;
        width: 100%;
    }
    
    /* this is new - you are hovering over the .tablet, and that should trigger 0 opacity for #code_block */
    .tablet:hover #code_block {
        opacity: 0;
        transition: all 1s ease;
    }
    
    .tablet:hover {
        width: var(--large);
        height: var(--medium);
        transition: 1s;
        /* this is new - background color is added to fit with your requirements,
        the cursor was my addition - simply to indicate clickability */
        background-color: black;
        cursor: pointer;
    }
    /* this is new - I went with 0 opacity instead of display block. Also, additional CSS was added:
    • transition
    • centering horizontally and vertically (left, right, margin, top, translate)
    */
    #text {
      position: absolute;
      color: white;
      opacity: 0;
      transition: all 1s ease;
      left: 0;
      right: 0;
      margin: auto;
      top: 50%;
      transform: translateY(-50%);
    }
    /* this is new - instead of hovering exactly on #text, the effect is triggered when you hover
    over .tablet, and that effect is applied to #text
    */
    .tablet:hover #text {
        opacity: 1;
        transition: all 1s ease;
    }
    <div class="content_container">
      <div class="tablet">
        <p id="text">Text</p>
        <div id="code_block"></div>
      </div>
      <div class="tablet"></div>
      <div class="tablet"></div>
      <div class="tablet"></div>
    </div>