Search code examples
htmlcssdialogprogress-barloading

How can i achieve this design with CSS?


I'm a newbie in CSS and a new user of stack overflow. I want to design a message-box (speech-bubble), as in the [Design I was given] (https://i.sstatic.net/moRgV.jpg):

So I copied a code from the internet that draw something similar, here is the resulting output of my code:

This is my code:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  min-height: 100vh;
  position: relative;
  background-image: url('images/bg-mobile.png');
  background-repeat: no-repeat;
  background-size: cover;
  font-family: 'Raleway', sans-serif;
}

.container {
  position: absolute;
  top: 40%;
  left: 40%;
  transform: translate(-40%, -40%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.fylo {
  display: flex;
  flex-direction: column;
  gap: 1.7em;
  width: 320px;
  background: hsl(228, 56%, 26%);
  padding: 2em 3.6em 2.6em 2em;
  margin: 0.5em;
  border-radius: 0.7em;
  border-top-right-radius: 7em;
}

.fylo .second-layer {
  display: flex;
  flex-direction: row;
  gap: 0.9em;
}

.second-layer div {
  width: 30px;
  height: 30px;
  padding: 1.36em;
  background-color: hsl(229, 57%, 11%);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
}

.flex-container {
  width: 320px;
  background: hsl(228, 56%, 26%);
  padding: 2em 1.5em 3em;
  border-radius: 0.7em;
  display: flex;
  flex-direction: column;
  color: hsl(0, 0%, 100%, .7)
}

.flex-container p {
  margin-bottom: 0.1em;
  text-align: center
}

.inner-flex {
  display: flex;
  margin-top: 0.65em;
  font-size: 0.77rem;
  font-weight: 600;
}

.inner-flex span:nth-child(2) {
  margin-left: auto;
}

progress {
  -webkit-appearance: none;
  -moz-appeareance: none;
  appearance: none;
  width: 100%;
  margin-top: 1em;
}


/*For webkit browsers like chrome I have to include the following  pseudoelements.The third one is not useful here*/


/*The indicator*/

::-webkit-progress-value {
  background: linear-gradient(hsl(6, 100%, 80%), hsl(335, 100%, 65%));
  border-radius: 20px;
  position: relative;
  overflow: hidden;
}

::-webkit-progress-value::after {
  content: "";
  position: absolute;
  width: 20px;
  height: 20px;
  background: yellow;
  border-radius: 50%;
  top: 50px;
  right: 20px;
  transform: translateX(50%, -50%);
  z-index: -1;
}


/*The Bar*/

::-webkit-progress-bar {
  background: hsla(229, 57%, 11%, 0.5);
  border-radius: 20px;
  height: 17px;
  border: 2px solid hsla(229, 57%, 11%, 0.5);
}


/*for moz browsers like Firefox,I have to  use the only existing pseudoelement(one) for appearance property for it and style it the sam as i styled ::-webkit-progress-value,I could have used comma to separate the selectors but we are dealing with experimental properties and we have non-stadard behaviour */

::-moz-progress-bar {
  background: linear-gradient(hsl(6, 100%, 80%), hsl(335, 100%, 65%));
  border-radius: 20px;
}


/*End of experimental declarations*/

.left-storage {
  width: 175px;
  height: 75px;
  background: hsl(0, 0%, 100%);
  border-radius: 0.6em;
  margin-top: -2.35em;
}

.left-storage {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

.left-storage>span:nth-child(1) {
  font-weight: 700;
  font-size: 2.5rem;
  opacity: 0.9;
}

.left-storage>span:nth-child(2) {
  text-transform: uppercase;
  font-weight: 600;
  font-size: 0.8rem;
  color: hsla(229, 7%, 55%, .8);
}

@media (min-width: 955px) {
  .container {
    flex-direction: row;
  }
  .flex-container {
    margin-top: calc(188.333px - 125.6px);
    margin-left: 0.5em;
    width: 400px;
    padding: 1.5em;
  }
  .left-storage {
    width: 120px;
    height: 80px;
    background: hsl(0, 0%, 100%);
    position: relative;
    -moz-border-radius: 10px;
    -webkit-border-radius: 10px;
    border-radius: 10px;
  }
  .left-storage::before {
    content: "";
    position: absolute;
    right: 100%;
    top: 26px;
    width: 0;
    height: 0;
    border-top: 13px solid transparent;
    border-right: 26px solid white;
    border-bottom: 13px solid transparent;
  }
}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Raleway:wght@400;700&display=swap" rel="stylesheet">
<!--End of google fonts-->

<main class="container">
  <div class="fylo">
    <div class="top-layer">
      <image src="images/logo.svg" alt="fylo logo" />
    </div>
    <div class="second-layer">
      <div>
        <image src="images/icon-document.svg">
      </div>
      <div>
        <image src="images/icon-folder.svg">
      </div>
      <div>
        <image src="images/icon-upload.svg">
      </div>
    </div>
  </div>
  <div class="flex-container">
    <p>You've used <span>815GB</span> of your storage</p>
    <progress value="70" max="100"></progress>
    <div class="inner-flex">
      <span>0 GB</span>
      <span>1000 GB</span>
    </div>
  </div>
  <div class="left-storage"><span>185</span><span>GB left</span></div>
</main>

What I want to achieve is that the tail of the message-box (i.e .left-storage in the css) to be positioned as it is in the design. I want to understand how to do this.

I also want know how to make the small white circle appear at the end of progress-value (that loading thing) with css.


Solution

  • I have solved the problem, please use the below CSS code:

    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }
    
    body {
        min-height: 100vh;
        position: relative;
        background-image: url('images/bg-mobile.png');
        background-repeat: no-repeat;
        background-size: cover;
        font-family: 'Raleway', sans-serif;
    }
    
    .container {
        position: absolute;
        top: 40%;
        left: 40%;
        transform: translate(-40%,-40%);
        display: flex;  
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }
    
    .fylo {
        
        display: flex;
        flex-direction: column;
        gap: 1.7em;
        width: 320px;
        background:  hsl(228, 56%, 26%);
        padding: 2em 3.6em 2.6em 2em;
        margin: 0.5em;
        border-radius: 0.7em;
        border-top-right-radius: 7em;
    }
    
    .fylo .second-layer{
        display: flex;
        flex-direction: row;
        gap: 0.9em;
    }
    
    .second-layer  div {
        width: 30px;
        height: 30px;
        padding: 1.36em;
        background-color:  hsl(229, 57%, 11%);
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 6px;
    }
    
    .flex-container {
        width: 320px; 
        background: hsl(228, 56%, 26%);  
        padding: 2em 1.5em 3em;
        border-radius: 0.7em;
        display: flex;
        flex-direction: column;
        color:hsl(0,0%, 100%,.7)
    }
    .flex-container p {
        margin-bottom: 0.1em;
        text-align: center
    }
    .inner-flex {
        display: flex;
        margin-top: 0.65em;
        font-size: 0.77rem;
        font-weight: 600;
    }
    .inner-flex span:nth-child(2) {
        margin-left: auto;
    }
    progress {
        -webkit-appearance: none;
        -moz-appeareance: none;
        appearance: none;
        width: 100%;
        margin-top: 1em;
    }
    
    /*For webkit browsers like chrome I have to include the following  pseudoelements.The third one is not useful here*/
    
    /*The indicator*/
    ::-webkit-progress-value  {
        background: linear-gradient(hsl(6, 100%, 80%),hsl(335, 100%, 65%));
        border-radius: 20px;
        position: relative;
        overflow: hidden;
    }
    ::-webkit-progress-value::after  {
        content: "";
        position: absolute;
        width: 20px;
        height: 20px;
        background: yellow;
        border-radius: 50%;
        top: 50px;
        right: 20px;
        transform: translateX(50%, -50%);
        z-index: -1;
    }
    /*The Bar*/
    ::-webkit-progress-bar {
        background: hsla(229, 57%, 11%,0.5);
        border-radius: 20px;
        height: 17px;
        border: 2px solid hsla(229, 57%, 11%,0.5);
    }
    
    /*for moz browsers like Firefox,I have to  use the only existing pseudoelement(one) for appearance property for it and style it the sam as i styled ::-webkit-progress-value,I could have used comma to separate the selectors but we are dealing with experimental properties and we have non-stadard behaviour */
    
    ::-moz-progress-bar { 
        background: linear-gradient(hsl(6, 100%, 80%),hsl(335, 100%, 65%));
        border-radius: 20px;
    }
    /*End of experimental declarations*/
    
    
    .left-storage {
        width: auto;
        height: 72px;
        background: hsl(0,0%, 100%);
        border-radius: 0.6em;
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: center;
        gap: 12px;
    }
    .left-storage > span:nth-child(1) {
        font-weight: 700;
        font-size: 2.5rem;
        opacity: 0.9;
    } 
    .left-storage > span:nth-child(2) { 
        text-transform: uppercase;
        font-weight: 600;
        font-size: 0.8rem;
        color: hsla(229, 7%, 55%, .8);
        white-space: nowrap;
    }
    
    @media (min-width: 955px) {
        .container {
            flex-direction: row;
        }
        .flex-container {
            margin-top: calc(188.333px - 125.6px);  
            margin-left: 0.5em;
            width: 400px;
            padding: 1.5em;
        }
        .left-storage {
            width: auto;
            height: 72px;
            background: hsl(0,0%, 100%);
            position: absolute;
            border-radius: 10px;
            top: 0;
            right: 20px;
            padding: 0 25px;
          }
          .left-storage::before {
            content: "";
            position: absolute;
            right: 0;
            top: 58px;
            width: 0;
            height: 0;
            border-top: 0 solid transparent;
            border-right: 35px solid white;
            border-bottom: 36px solid transparent;
          }
        
    }