Luiz Alves
Luiz Alves

Reputation: 2645

Put spinner on center of image container with CSS

Id like to put a spinner into center of the image container if no image 'foo.jpg' is present.

I have tried the next but no success

Here is the fiddle: https://jsfiddle.net/pubqdzca/

@import url('//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css');
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css');
body {
  margin: 10px;
}

.drop-box-filled-totem {
  background: #F8F8F8;
  border: 5px dashed #219;
  width: 100%;
  height: 100px;
  text-align: center;
  /*padding: 50px 10px;*/
  padding: 5px;
  margin-left: 10px;
}
<link rel="stylesheet" type="text/css" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">

<div class="container">
  <div class="col-md-3 col-lg-3" align="center">
    <div class="image-upload">
      <label for="file-input">
         <span> <img class="drop-box-filled-totem" 
            src="foo.jpg" 
             onerror="if (this.src != 'error.jpg') this.src='//ssl.gstatic.com/accounts/ui/avatar_2x.png'">
            <i class="fa fa-spinner fa-spin fa-fw"></i>
            <span class="sr-only">Carregando...</span>
         </span>
      </label>
    </div>
  </div>
</div>

Upvotes: 0

Views: 1750

Answers (3)

connexo
connexo

Reputation: 56754

No need for an extra item container when all you need on that container is some css generated content. Create a surrounding container, and position the icon on the pseudo element ::after using left: 50%; top: 50%; (here 50% corresponds to 50% of the surrounding container), then fix the mispositioning by issueing transform(-50%, -50%) (here the percentage refers to the icon, not the surrounding container).

@import url('//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css');
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css');
body {
  margin: 10px;
}

.drop-box-filled-totem {
  background: #F8F8F8;
  border: 5px dashed #219;
  width: 100%;
  height: 100px;
  text-align: center;
  padding: 5px;
}

.drop-box-filled-totem-container {
  position: relative;
}

.drop-box-filled-totem-container::after {
  font-family: FontAwesome;
  content: "\f110";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: ;
  -webkit-animation: fa-spin-center 2s infinite linear;
  animation: fa-spin-center 2s infinite linear;
  transform-origin: top left;
}

@-webkit-keyframes fa-spin-center {
  0% {
    -webkit-transform: rotate(0deg) translate(-50%, -50%);
    transform: rotate(0deg) translate(-50%, -50%);
  }
  100% {
    -webkit-transform: rotate(359deg) translate(-50%, -50%);
    transform: rotate(359deg)translate(-50%, -50%);
  }
}
@keyframes fa-spin-center {
  0% {
    -webkit-transform: rotate(0deg) translate(-50%, -50%);
    transform: rotate(0deg) translate(-50%, -50%);
  }
  100% {
    -webkit-transform: rotate(359deg) translate(-50%, -50%);
    transform: rotate(359deg) translate(-50%, -50%);
  }
}
<link rel="stylesheet" type="text/css" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">

<div class="container">
  <div class="col-md-3 col-lg-3" align="center">
    <div class="image-upload">
      <label for="file-input" style="border: 1px solid red">
         <span class="drop-box-filled-totem-container"> <img class="drop-box-filled-totem" 
            src="foo.jpg" 
             onerror="if (this.src != 'error.jpg') this.src='//ssl.gstatic.com/accounts/ui/avatar_2x.png'">
            <span class="sr-only">Carregando...</span>
         </span>
      </label>
    </div>
  </div>
</div>

Upvotes: 2

Temani Afif
Temani Afif

Reputation: 272842

You can simply use position relative and set negative value to top. This is not a generic solution to center everything whatever the height/width is but it can be enough in your case.

@import url('//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css');
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css');
body {
  margin: 10px;
}

.drop-box-filled-totem {
  background: #F8F8F8;
  border: 5px dashed #219;
  width: 100%;
  height: 100px;
  text-align: center;
  padding: 5px;
}

i.fa-spin {
  position:relative;
  top:-55px;
}
<link rel="stylesheet" type="text/css" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">

<div class="container">
  <div class="col-md-3 col-lg-3" align="center">
    <div class="image-upload">
      <label for="file-input">
         <span> <img class="drop-box-filled-totem" 
            src="foo.jpg" 
             onerror="if (this.src != 'error.jpg') this.src='//ssl.gstatic.com/accounts/ui/avatar_2x.png'">
            <i class="fa fa-spinner fa-spin fa-fw"></i>
            <span class="sr-only">Carregando...</span>
         </span>
      </label>
    </div>
  </div>
</div>

Upvotes: 1

UncaughtTypeError
UncaughtTypeError

Reputation: 8722

  1. Declare relative positioning on a containing element of the icon in question, .image-upload should do fine.
  2. Declare absolute positioning on the nested icon element then offset the position accordingly with left, right, top and bottom property values.
  3. Declare a max-height equivalent to the font-size property value of the icon as well to negate the undesirable rotation of a full height element.

Example:

.image-upload {
  position: relative;
}

.image-upload .fa-spinner {
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    position: absolute;
    margin: auto;
    max-height: 14px;
}

Code Snippet Demonstration:

@import url('//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css');
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css');
body {
  margin: 10px;
}

.drop-box-filled-totem {
  background: #F8F8F8;
  border: 5px dashed #219;
  width: 100%;
  height: 100px;
  text-align: center;
  padding: 5px;
  margin: auto;
  box-sizing: border-box;
}

/* Additional */

.image-upload {
  position: relative;
}

.image-upload .fa-spinner {
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    position: absolute;
    margin: auto;
    max-height: 14px;
}
<link rel="stylesheet" type="text/css" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">

<div class="container">
  <div class="col-md-3 col-lg-3" align="center">
    <div class="image-upload">
      <label for="file-input">
         <span> <img class="drop-box-filled-totem" 
            src="foo.jpg" 
             onerror="if (this.src != 'error.jpg') this.src='//ssl.gstatic.com/accounts/ui/avatar_2x.png'">
            <i class="fa fa-spinner fa-spin fa-fw"></i>
            <span class="sr-only">Carregando...</span>
         </span>
      </label>
    </div>
  </div>
</div>

Updated JSFiddle

Upvotes: 3

Related Questions