going grey
going grey

Reputation: 13

CSS circle with inner circle and image

I'm trying to achieve the following:

I'm trying to do this with the minimum amount of code. I want to avoid duplication as much as possible. I believe that all of this can be achieved using before and after selectors, but I'm not sure how to get this done

Here's what I have so far:

CSS:

    .grid-container {
        display: grid;
        grid: 100px / 100px;
    }

    .circle {
        border-radius: 50%;
        width: 100%;
        height: 100%;
        background-color: #e4e4e7;
    }

     .circle:before {
        content: "";
        border-radius: 50%;
        width: 80%;
        height: 80%;
        top: 10%;
        left: 10%;
        background-color: blue;
        display: block;
        position: relative; 
    }

    .image-one:before {
        content: url("https://stackoverflow.com/favicon.ico");
    }

    .circle-01 {
        grid-column: 1 / 2;
        grid-row: 1 / 2;
    }

HTML:

<div class="grid-container">
    <div class="circle-01 circle image-one"></div>
</div>

I need a structure whereby I can easily change the color of the inner circle and/or image

Example

<div class="grid-container">
    <div class="circle-01 circle image-one yellow"></div>
    <div class="circle-01 circle image-two blue"></div>
    <div class="circle-01 circle image-three green"></div>
</div>

Upvotes: 1

Views: 3907

Answers (3)

Johannes
Johannes

Reputation: 67798

You can do it with a pseudo element like this, putting the pseudo element on top of the main element and using borders and a background-image. You can even use a background color behind the image if it doesn't fill the whole pseudo element (note the no-repeat, the size and position settings for the background):

.x1 {
  width: 300px;
  height: 300px;
  position: relative;
  border-radius: 50%;
  border: 10px solid #22f;
  margin: 30px;
  background: yellow;
}

.x1:after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 220px;
  height: 220px;
  border-radius: 50%;
  border: 6px solid #f22;
  background: #3d3 url(http://placehold.it/200x200/fa0/?text=this_is_an_image) center center no-repeat;
  background-size: 100px 100px;
}
<div class="x1"></div>

Note: the orange square is an image, the green color around it is the background color, the red circle is the border of the pseudo element, the yellow area is the background color of the main element and the blue circle is the border of the main element. Each of these could as well be white or transparent.

ADDITION after additional question in comment:

You can also change the background-colors by adding seperate classes. In the following snippet I added two classes to the div, one that affects the background in the main element and one that affects the background-color of the pseudo element. In the latter case you have to make sure to use the background-color property, not background in the CSS rule - otherwise the background-image would disappear:

.x1 {
  width: 300px;
  height: 300px;
  position: relative;
  border-radius: 50%;
  border: 10px solid #22f;
  margin: 30px;
  background: yellow;
}

.x1:after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 220px;
  height: 220px;
  border-radius: 50%;
  border: 6px solid #f22;
  background: #3d3 url(http://placehold.it/200x200/fa0/?text=this_is_an_image) center center no-repeat;
  background-size: 100px 100px;
}
.aqua-outer-bg {
background: aqua;
}
.pink-inner-bg:after {
background-color: pink;
}
<div class="x1 aqua-outer-bg pink-inner-bg"></div>

Note: The original CSS rules remained unchanged, their background colors are overwritten by the additional classes.


ONE MORE ADDITION after additional question in comment from OP on September 18th:

Yes, you can also split that in two classes as I did below (.x1a and .x1b). I simply added both classes to the HTML tag and split up the CSS from x1:after into two rules, one for .x1a:after and one for .x2a:after

.x1a {
  width: 300px;
  height: 300px;
  position: relative;
  border-radius: 50%;
  border: 10px solid #22f;
  margin: 30px;
  background: yellow;
}

.x1a:after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 220px;
  height: 220px;
  background: #3d3 url(http://placehold.it/200x200/fa0/?text=this_is_an_image) center center no-repeat;
  background-size: 100px 100px;
}
.x1b:after {
  border-radius: 50%;
  border: 6px solid #f22;
}
.aqua-outer-bg {
background: aqua;
}
.pink-inner-bg:after {
background-color: pink;
}
<div class="x1a x1b aqua-outer-bg pink-inner-bg"></div>

Upvotes: 2

Ronnie Smith
Ronnie Smith

Reputation: 18585

Abracadabra

    div {
      border-radius: 50%
    }

    #a {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 64px;
      width: 64px;
      border: 2px solid green;
    }

    img {
      align-self: auto;
      border: 2px solid blue;
      border-radius: 50%;
      padding:5%;
    }
    <div id="a">
      <img src="https://rack.pub/media/janus.png" height="48">
    </div>

Upvotes: 0

Dan Kreiger
Dan Kreiger

Reputation: 5516

Try running this snippet:

$(document).ready(function() {
  var sourceIndex = 1;
  var colorIndex = 1;
  var colors = [
    "rgb(0, 132, 203)",
    "rgb(255, 192, 203)",
    "rgb(50, 192, 103)",
    "rgb(255, 165, 0)"
  ];
  var sources = [
    "https://www.linkedin.com/favicon.ico",
    "https://www.google.com/favicon.ico",
    "http://jsfiddle.net/favicon.ico",
    "https://getbootstrap.com/favicon.ico",
    "https://www.facebook.com/favicon.ico"
  ];
  $("button").click(function() {
    changeStuff($(this).hasClass("changeImage") ? sources : colors, $(this));

    function changeStuff(list, selector) {
      counter(list, selector);
      if (list == sources) {
        selector
          .prev()
          .prev(".outer-circle")
          .find(".inner-circle")
          .find("img")
          .attr("src", list[sourceIndex]);
      } else {
        if (
          selector
          .prev(".outer-circle")
          .find(".inner-circle")
          .css("background-color") == colors[colorIndex]
        ) {
          selector
            .prev(".outer-circle")
            .find(".inner-circle")
            .css("background-color", "tan");
        } else {
          selector
            .prev(".outer-circle")
            .find(".inner-circle")
            .css("background-color", colors[colorIndex]);
        }
      }
    }
  });

  function counter(list, selector) {
    if (list == sources) {
      sourceIndex == list.length - 1 ? (sourceIndex = 0) : sourceIndex++;
    } else {
      colorIndex == list.length - 1 ? (colorIndex = 0) : colorIndex++;
    }
  }
});
.container {
  display: flex;
  align-items: center;
  flex-direction: column;
}

.box {
  display: flex;
}

.inner-circle {
  border-radius: 50%;
  width: 80%;
  height: 80%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.box:first-child .inner-circle {
  background-color: blue;
}

.box:nth-child(2) .inner-circle {
  background-color: black;
}

.box:nth-child(3) .inner-circle {
  background-color: maroon;
}

.outer-circle {
  border-radius: 50%;
  width: 100px;
  height: 100px;
  background-color: #e4e4e7;
  display: flex;
  justify-content: center;
  align-items: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="container">
  <div class="box">
    <div class="outer-circle">
      <div class="inner-circle">
        <img src="https://stackoverflow.com/favicon.ico" alt="">

      </div>
    </div>

    <button class='changeColor'>Change Color</button>
    <button class='changeImage'>Change Image</button>
  </div>

  <div class="box">
    <div class="outer-circle">
      <div class="inner-circle">
        <img src="https://stackoverflow.com/favicon.ico" alt="">

      </div>
    </div>

    <button class='changeColor'>Change Color</button>
    <button class='changeImage'>Change Image</button>
  </div>

  <div class="box">
    <div class="outer-circle">
      <div class="inner-circle">
        <img src="https://stackoverflow.com/favicon.ico" alt="">

      </div>
    </div>

    <button class='changeColor'>Change Color</button>
    <button class='changeImage'>Change Image</button>
  </div>
</div>

Upvotes: 0

Related Questions