Absolute positioning an element on the circumference of a circle - html

I have been working on to place an icon to the bottom right of an image having the property of border-radius: 50%.
Here's what I want to achieve(Icon to be on the circumference),
By absolute and relative positioning, I can place the icon as expected but on smaller screens, the icon goes out of place due to image resizing (with img-fluid class of bootstrap 4).
How can I make the icon to be at the same place across all screens even after image resizes?
.wrapper{
position: relative;
display: inline-block;
margin: 30px;
}
.image{
border-radius: 50%;
}
.icon{
height: 50px;
width: 50px;
background: #008080;
position: absolute;
border-radius: 50%;
right: 22px;
bottom: 42px;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class='wrapper'>
<img src='https://via.placeholder.com/350x350' class='image img-fluid'/>
<span class='icon'></span>
</div>

In order to get the desired result you need to position the center of the small circle (with a dimension of 0px × 0px) at the desired height/width of the bigger one and draw the small circle around this center.
Do note that if you want your positioning done responsively you need to do it in percentage, not in px.
Since functionality required from the child is purely visual, you can safely use a pseudo element:
.icon {
width: 0px;
height: 0px;
position: absolute;
}
.icon:after {
width: 50px;
height: 50px;
}
In terms of centering, you have a couple of options:
a) transform:translate(-50%,-50%)
.wrapper {
position: relative;
display: inline-block;
margin: 30px;
}
.image {
border-radius: 50%;
}
.icon {
height: 0;
width: 0;
position: absolute;
right: 16%;
bottom: 13.5%;
overflow: visible;
}
.icon:before {
height: 50px;
width: 50px;
position: absolute;
border-radius: 50%;
content: '';
transform: translate(-50%, -50%);
background-color: #008080;
display: block;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<div class='wrapper'>
<img src='https://via.placeholder.com/350x350' class='image img-fluid' />
<span class='icon'></span>
</div>
b) flexbox on parent:
.wrapper {
position: relative;
display: inline-block;
margin: 30px;
}
.image {
border-radius: 50%;
}
.icon {
height: 0;
width: 0;
position: absolute;
right: 16%;
bottom: 13.5%;
display: flex;
overflow: visible;
align-items: center;
justify-content: center;
}
.icon:before {
height: 50px;
width: 50px;
border-radius: 50%;
position: absolute;
content: '';
background-color: #008080;
display: block;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<div class='wrapper'>
<img src='https://via.placeholder.com/350x350' class='image img-fluid' />
<span class='icon'></span>
</div>
To rotate the small circle on the bigger one you can do it mathematically or you could do as I did: I made the :after 3px × 3px, changed % of any combo of top|bottom + left|right to the desired location on the bigger center circumference and increase the size of the small center back to 50px * 50px.
Also, to size the smaller circle down responsively, you could express the width and height in vw under a particular viewport width, making sure at the point where it starts shrinking the size in px with the one in vw translate to the same actual size. Example:
.wrapper {
position: relative;
display: inline-block;
margin: 30px;
}
.image {
border-radius: 50%;
}
.icon {
height: 0;
width: 0;
position: absolute;
right: 16%;
bottom: 13.5%;
display: flex;
overflow: visible;
align-items: center;
justify-content: center;
}
.icon:before {
height: 35px;
width: 35px;
border-radius: 50%;
position: absolute;
content: '';
background-color: #008080;
display: block;
}
#media (max-width: 350px) {
.icon:before {
width: calc(10vw - 6px);
height: calc(10vw - 6px);
min-width: 5px;
min-height: 5px;
/* 60px making up for the padding on .wrapper */
}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<div class='wrapper'>
<img src='https://via.placeholder.com/350x350' class='image img-fluid' />
<span class='icon'></span>
</div>

Define right and bottom as % not px
Do the same for height and width if you want size to adapt. See my snippet
.wrapper{
position: relative;
display: inline-block;
margin: 30px;
}
.image{
border-radius: 50%;
}
.icon{
height: 15%;
width: 15%;
background: #008080;
position: absolute;
border-radius: 50%;
right: 10%;
bottom: 5%;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class='wrapper'>
<img src='https://via.placeholder.com/350x350' class='image img-fluid'/>
<span class='icon'></span>
</div>

Related

How to place sibling img/div on top of each other with identical size if parent has padding

I'd like to have an image with a div that covers the image exactly. I can get the div to overlay the image by using position: relative in the parent and position: absolute for the div, but background-color fills out the padding in the parent so they aren't overlayed properly.
Here's a snippet that demonstrates the problem.
.parent {
position: relative;
padding: 10px;
width: 40%;
}
.image {
width: 100%;
height: 100%;
border-radius: 13px;
}
.overlay {
position: absolute;
background-color: red;
width: 100%;
height: 100%;
border-radius: 13px;
left: 0;
top: 0;
opacity: 0.2;
}
<div class="parent">
<img class="image" src="https://cards.scryfall.io/normal/front/4/f/4f3deefe-28bc-4e45-a0a0-ab03167e2e81.jpg?1561942156">
<div class="overlay"></div>
</div>
I'm able to get it pretty close with some calc()'s to subtract the padding. This almost works, but the div fills out a little too much at the bottom. I'd like to not have a bunch of hardcoded values for padding anyway, so I wouldn't really like this solution even if it did work entirely.
Here's a snippet that shows the calc() approach.
.parent {
position: relative;
padding: 10px;
width: 40%;
}
.image {
width: 100%;
height: 100%;
border-radius: 13px;
}
.overlay {
position: absolute;
background-color: red;
width: calc(100% - 2 * 10px);
height: calc(100% - 2 * 10px);
border-radius: 13px;
left: 10px;
top: 10px;
opacity: 0.2;
}
<div class="parent">
<img class="image" src="https://cards.scryfall.io/normal/front/4/f/4f3deefe-28bc-4e45-a0a0-ab03167e2e81.jpg?1561942156">
<div class="overlay"></div>
</div>
This snippet does things a slightly different way, putting the img inside the overlay div and putting the actual green, lower opacity overlay as the overlay div's after pseudo element.
This way you don't have to build in any knowledge of the parent's padding.
.parent {
position: relative;
padding: 10px;
width: 40%;
background: red;
height: fit-content;
}
.image {
width: 100%;
border-radius: 13px;
top: 0;
left: 0;
}
.overlay {
position: relative;
padding: 0;
width: fit-content;
height: fit-content;
}
.overlay::after {
content: '';
position: absolute;
background-color: green;
width: 100%;
height: 100%;
border-radius: 13px;
left: 0;
top: 0;
opacity: 0.2;
padding: 0px;
}
<div class="parent">
<div class="overlay"> <img class="image" src="https://cards.scryfall.io/normal/front/4/f/4f3deefe-28bc-4e45-a0a0-ab03167e2e81.jpg?1561942156"></div>
</div>
When using HTML5, browser adds some padding to the bottom of the img tag. This can be avoided by making the image a block element. So just adding display: block to class .image and then it good.
And btw, to define witdh/height of an absolute element, beside calc() you can also define 4 values top, right, bottom, left of it.
:root {
--custom-padding: 10px;
}
.parent {
position: relative;
padding: var(--custom-padding);
width: 40%;
}
.image {
width: 100%;
height: 100%;
border-radius: 13px;
display: block;
}
.overlay {
position: absolute;
background-color: red;
border-radius: 13px;
bottom: var(--custom-padding);
right: var(--custom-padding);
left: var(--custom-padding);
top: var(--custom-padding);
opacity: 0.2;
}
<div class="parent">
<img class="image" src="https://cards.scryfall.io/normal/front/4/f/4f3deefe-28bc-4e45-a0a0-ab03167e2e81.jpg?1561942156">
<div class="overlay"></div>
</div>

Layer images on narrow DIV

I want to make vertical line in DIV.
then I want to layer img on vertical line.
(the pic shows the result I want)
For my source code is like this .
<div style="background-color:gray;width:1px;height:100%;"></div>
<img src="circle.png">
<img src="triangle.png">
How can I layer these elements???
You will need to do some math to adjust it in the center.
.outer-flex {
display: flex;
width: 40px;
align-items: center;
position: absolute;
}
.line {
background-color: gray;
width: 1px;
height: 100vh;
margin-left: auto;
margin-right: auto;
}
.circle {
position: absolute;
left: calc(50% - 15px);
top: 20px;
border: 5px solid white;
border-radius: 20px;
}
.arrow {
position: absolute;
top: 70vh;
left: calc(50% - 15px)
}
<div class="outer-flex">
<div class="line"></div>
<img src="https://www.marylandeyeassociates.com/wp-content/uploads/2015/03/red-dot-hi.png" width="21px" class="circle">
<img src="https://image.flaticon.com/icons/png/512/60/60995.png" width="31px" class="arrow">
</div>
The images are inside the div this way:
div {
background-color: gray;
width: 1px;
height: 200px;
}
img:first-of-type {
margin-left: -10px;
top: 30px;
position: relative;
}
img:last-of-type {
margin-left: -10px;
top: 85px;
position: relative;
}
<div>
<img src="https://picsum.photos/20/20" />
<img src="https://picsum.photos/20/20" />
</div>
If you know the width of the images, move them to the left with a negative margin of half their width.

Display 'SALE' tag before an image

I am looking to display a 'SALE' tag just before an image, I have tried to do this using the 'before' pseudo element however nothing seems to be displaying on the screen.
I am trying to create the 'SALE' tag inside a circle with black background.
Below is the code that I have used
<span class"bag-image">
<img src="https://images-na.ssl-images-
amazon.com/images/I/71lDa7EbWSL._UY395_.jpg" class="image">
</span>
.bag-image::before{
background-color: #red;
content: 'SALE';
border-radius: 500px;
display: inline-block;
width: 100px;
height: 100px;
}
For visual reference:
LIKE THIS
https://codepen.io/anon/pen/rgLPdp
Make the bag-image class position: relative;
Make the bag-image:before position: absolute; and position it with top/left or margins and set the line-height to vertically center the SALE text.
You can give the pseudo-class a lower z-index so that only the top half is visible, e.g. z-index: -1;
You can use margin-top: -2.5em; margin-left: 175px; in the pseudo-code to position it.
div.bag-image {
display: inline-block;
/* just so that we can see in the example */
margin-top: 3em;
}
div.bag-image:before {
position: absolute;
background-color: #ff0000;
content: 'SALE';
text-align: center;
color: #ffffff;
margin-top: -2.5em;
margin-left: 175px;
/* optionally make it a circle */
border-radius: 9999px;
height: 3em;
padding: 1em;
line-height: 3em;
}
/* just for clarity */
img.image {
border: 1px solid #ccc;
}
<div class="bag-image">
<img src="https://images-na.ssl-images-amazon.com/images/I/71lDa7EbWSL._UY395_.jpg" class="image">
</div>
I think you want this. Also check the codepen.Codepen
<style>
.bag-image{
text-align:center;
}
.bag-image::before{
content: 'SALE';
border-radius: 50px;
background: red;
display: inline-block;
width: 100px;
height: 100px;
position: absolute;
line-height: 100px;
color: #fff;
}
</style>
In summary, you need to add the position: relative property to the span, and the position: absolute property to the ::after element. Something like this:
.bag-image {
position: relative;
display: block;
}
.bag-image::after {
background-color: red;
content: 'SALE';
border-radius: 500px;
display: block;
width: 100px;
height: 100px;
position: absolute;
top: 0px;
text-align: center;
left: 100px;
}
<span class="bag-image">
<img src="https://images-na.ssl-images-amazon.com/images/I/71lDa7EbWSL._UY395_.jpg" class="image">
</span>
Play with the left (and maybe the top) property to place the text in the desired position.
You can try this code:
your code background-color: #red; is the wrong to declared #red it's instant of only red.
the sale is a position by my self parent relatively, you can learn about more position https://www.w3schools.com/css/css_positioning.asp .
here also write a shadow element related to some code for needed your answer.
maybe it solves your problem.
=== Thanks ===
.bag-image {
margin-top: 50px;
position: relative;
border: 1px solid red;
}
.bag-image img {
display: block;
max-width: 100%;
height: auto;
margin: 0 auto;
}
.bag-image::before{
background-color: red;
content: 'SALE';
border-radius: 500px;
display: inline-block;
width: 100px;
height: 100px;
text-align: center;
line-height: 100px;
color: #fff;
position:absolute;
top: 0;
left: 50%;
transform: translate(-50%, -50%);
}
<div class="bag-image">
<img src="https://images-na.ssl-images-amazon.com/images/I/71lDa7EbWSL._UY395_.jpg" class="image">
</div>

How to arrange correctly?

I'm trying to create two banners with cropped corners, but I'm having problems with my code:
https://codepen.io/Jeerjmin/pen/VdBVKL
.container {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
background-color: white;
}
.banner-1 {
min-width: 200px;
max-width: 200px;
height: 300px;
margin: 70px;
background-color: white;
border: solid #01579B 4px;
border-radius: 15px;
overflow: hidden;
}
.banner-1:before {
position: absolute;
content: '';
min-width: 38px;
height: 60px;
top: 39px;
left: 303px;
background-color: white;
border-bottom: solid #01579B 4px;
transform: rotate(-45deg);
}
.banner-2 {
min-width: 200px;
max-width: 200px;
height: 300px;
margin: 70px;
background-color: white;
border: solid #01579B 4px;
border-radius: 15px;
overflow: hidden;
}
.banner-2:before {
position: absolute;
content: '';
min-width: 38px;
height: 60px;
top: 39px;
left: 652px;
background-color: white;
border-bottom: solid #01579B 4px;
transform: rotate(-45deg);
}
img {
position: relative;
top:100px;
left: 25px;
width: 200px;
height: 150px;
}
.dot {
height: 50px;
width: 50px;
background-color: deepskyblue;
border-radius: 50%;
position: relative;
left: -50px;
bottom: 100px;
text-align:center;
}
p {
text-align:center;
}
<div class="container">
<div class="banner-1">
<p>Card-1</p>
<img src="https://img2.goodfon.ru/original/1366x768/6/5e/koshka-kot-meyn-kun-belyy-fon-5567.jpg"></img>
<span class="dot dot-1">
<h1>0,5</h1>
<h5>кг</h5>
</span>
</div>
<div class="banner-2">
<p>Card-2</p>
<img src="https://img2.goodfon.ru/original/1366x768/6/5e/koshka-kot-meyn-kun-belyy-fon-5567.jpg"></img>
<span class="dot dot-2">
<h1>0,5</h1>
<h5>кг</h5>
</span>
</div>
</div>
Problem 1:
I'm trying to crop the top left corners of the banners, but the cards move around while the crops stay where they are.
Problem 2:
The span with class="dot" should form a colored circle, but does not.
Not sure what you meant in Problem 1. As for problem 2, you need to add display: block to your .dot class and you also can remove left property form it.
I had to make several changes to your code to get this working, so see the code snippet below for all the changes. However, here are a few key points:
To position your ::before pseudo-elements in correct relation to the banners, add relative positioning to the banners.
To make your blue dot work, and to align its contents correctly, Flexbox layout is a good solution.
To simplify your code, it's preferable to style similar items together. For that reason, I've given your banners shared styles.
<img> elements should not have a corresponding closing tag (the technical term for this kind of element is "self-closing"). That said, I changed your image to be a background image. The reason is that you can't both have overflow: hidden on your banners and put the clipped corner over its borders.
.container {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
background-color: white;
}
/* Target both banners together,
since they share styles */
.banner-1,
.banner-2 {
min-width: 200px;
max-width: 200px;
height: 300px;
margin: 70px;
border: 4px solid #01579B;
border-radius: 15px;
/* Relatively position the banner,
so that the clipped corners,
can be properly placed */
position: relative;
/* To have the image clip to
the banner, make it a
background image */
background: white no-repeat 10px bottom / auto 150px
url("https://img2.goodfon.ru/original/1366x768/6/5e/koshka-kot-meyn-kun-belyy-fon-5567.jpg");
}
.banner-1::before,
.banner-2::before {
content: "";
width: 22px;
height: 38px;
position: absolute;
left: 0;
top: -1px;
background-color: white;
border-right: 4px solid #01579B;
/* Adjust your transform origin,
to make the rotation easier */
transform-origin: top right;
transform: rotate(45deg);
}
.dot {
/* Use Flexbox to align the
content in your dot */
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 80px;
width: 80px;
background-color: deepskyblue;
border-radius: 50%;
position: absolute;
left: 20px;
bottom: 100px;
}
h1, h5 {
/* Remove margins on
dot content */
margin: 0;
}
p {
text-align: center;
}
<div class="container">
<div class="banner-1">
<p>Card-1</p>
<span class="dot dot-1">
<h1>0,5</h1>
<h5>кг</h5>
</span>
</div>
<div class="banner-2">
<p>Card-2</p>
<span class="dot dot-2">
<h1>0,5</h1>
<h5>кг</h5>
</span>
</div>
</div>

text-align and margin CSS properties are not responsive

.scss
div.playlist {
position: relative;
display: inline-block;
}
div.playlist {
span {
position: absolute;
text-align: center;
height: 100%;
width: 100%;
color: white;
font-size: 20px;
}
.span-icon {
padding-bottom: 50px !important;
}
}
div.playlist span:before {
display: inline-block;
vertical-align: middle;
height: 100%;
content: '';
}
.html
<div class="playlist">
<span class="span-icon"><ion-icon [name]="data.icon"></ion-icon></span>
<span>{{data.text}}</span>
<img [src]="data.imageUrl" [alt]="data.text" />
</div>
Out Put
Now I need as shown below.Please don't consider about the different icon type and the text.I just need this.I need a responsive top right and the bottom right appearance of the icon and text.I have tried with text-align: right and the margin properties.But you know that approach is not responsive on different view ports.So can you help me to solve this issue?
Position your both icons and span text as absolute and then if needed you could use CSS calc() function to align them at top-right and bottom-right above the image.
.playlist {
position: relative;
display: inline-block;
width: 240px;
height: 200px;
overflow: hidden;
}
.playlist img {
width: 100%;
height: 100%;
}
.playlist .span-icon {
position: absolute;
top: 5px;
right: calc(100% - 98%);
color: #fff;
}
.playlist .tm {
position: absolute;
bottom: 5px;
right: calc(100% - 98%);
color: #fff;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<div class="playlist">
<span class="span-icon"><i class="fa fa-film"></i></span>
<span class="tm">2:10</span>
<img src="http://lorempixel.com/output/city-q-c-640-480-6.jpg">
</div>
<div class="playlist">
<span class="span-icon"><ion-icon [name]="data.icon"></ion-icon></span>
<span class="span-text">{{data.text}}</span>
<img [src]="data.imageUrl" [alt]="data.text" />
</div>
CSS
.span-icon {
position: absolute;
top: 0;
right: 0;
}
.span-icon {
position: absolute;
bottom: 0;
right: 0;
}
You simply set the icons absolute and position it with top, right. ...