Border-radius not working during CSS transform - css

Trying to make a rounded menu background. But the border-radius is not working while closing
var menuButton = document.querySelector('.btn-menu');
menuButton.addEventListener('click', function(e){
e.preventDefault();
document.body.classList.toggle('menu-open');
});
.btn-menu{
width: 30px;
height: 30px;
border: 2px solid red;
position: relative;
z-index: 5;
float: right;
}
.menu-bg {
position: fixed;
left: 0;
top: 0;
bottom: 0;
width: 100%;
z-index: 40;
pointer-events: none;
z-index: 1;
}
.menu-bg:before {
content: '';
height: 1px;
width: 1px;
background: #000;
position: fixed;
right: 30px;
top: 30px;
transition: all ease .8s;
border-radius: 50%;
transform: scale(1);
overflow:hidden;
}
.menu-open .menu-bg:before {
transform: scale(500);
}
<div class="btn-menu"><span>Menu</span></div>
<div class="menu-bg"></div>
JSFiddle - https://jsfiddle.net/afelixj/ew7b065h/

1px as width/height is not a good idea, I would do it differently and start at scale(0):
var menuButton = document.querySelector('.btn-menu');
menuButton.addEventListener('click', function(e) {
e.preventDefault();
document.body.classList.toggle('menu-open');
});
.btn-menu {
width: 30px;
height: 30px;
border: 2px solid red;
position: relative;
z-index: 5;
float: right;
}
.menu-bg {
position: fixed;
left: 0;
top: 0;
bottom: 0;
width: 100%;
z-index: 40;
pointer-events: none;
z-index: 1;
}
.menu-bg:before {
content: '';
height: 100px;
width: 100px;
background: #000;
position: fixed;
right: -20px;
top: -20px;
transition: all ease .8s;
border-radius: 50%;
transform: scale(0);
overflow: hidden;
}
.menu-open .menu-bg:before {
transform: scale(5);
}
<div class="btn-menu"><span>Menu</span></div>
<div class="menu-bg"></div>

It's a browser bug. Sometimes it works fine and then, if you change window width, it will start messing up (I saw the problem sometimes opening the menu up).
There's a known problem using transform on fixed elements: link You should try to avoid it.
In your case, insteed of transform you could just change your width, height and position to make it work as you may desire.
As an example:
var menuButton = document.querySelector('.btn-menu');
menuButton.addEventListener('click', function(e){
e.preventDefault();
document.body.classList.toggle('menu-open');
});
.btn-menu{
width: 30px;
height: 30px;
border: 2px solid red;
position: relative;
z-index: 5;
float: right;
}
.menu-bg {
position: fixed;
left: 0;
top: 0;
bottom: 0;
width: 100%;
z-index: 40;
pointer-events: none;
z-index: 1;
}
.menu-bg:before {
content: '';
height: 1px;
width: 1px;
background: #000;
position: fixed;
right: 30px;
top: 30px;
transition: all ease .3s;
transform: scale(1);
border-radius: 50%;
}
.menu-open .menu-bg:before {
transition: all ease .6s;
height: 400px;
width: 400px;
right: -90px;
top: -90px;
border-radius: 50%;
}
<div class="btn-menu"><span></span></div>
<div class="menu-bg"></div>

Related

How to place line underneath the circle? without z-index

I made an X with a circle using css.
There is a green line that is sticking out on top of the circle, how do I place it under the circle?
How would this be done?
code: https://jsfiddle.net/6wod3pLm/
That is all I am doing in the code.
.exitnew {
-webkit-appearance: none;
appearance: none;
position: relative;
box-sizing: border-box;
margin: auto;
padding: 0;
width: 48px;
height: 48px;
cursor: pointer;
background: blue;
border: none;
border-radius: 50%;
clip-path: circle(50%);
transition: all 1s ease;
overflow: hidden;
}
.exitnew:before,
.exitnew:after {
content: "";
position: absolute;
height: 5px;
top: 22px;
left: -1px;
right: -1px;
background: green;
transform: rotate(45deg);
transition: all 1s ease;
}
.exitnew:after {
transform: rotate(-45deg);
}
.exitnew:hover {
background: transparent;
}
.exitnew:hover:before,
.exitnew:hover:after {
background: green;
}
.exitnew b {
box-sizing: border-box;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border: 5px solid red;
border-radius: 50%;
}
<button class="exitnew" type="button" aria-label="Close"><b></b></button>
You don't need all these code. Here is an easier idea:
.exitnew {
-webkit-appearance: none;
appearance: none;
box-sizing: border-box;
margin: 0;
padding: 0;
width: 48px;
height: 48px;
cursor: pointer;
--b:7px; /* the thickness*/
--c:blue 90deg,green 0; /* the coloration */
background:
conic-gradient(from 90deg at var(--b) var(--b),var(--c))
calc(100% + var(--b)/2) calc(100% + var(--b)/2)/
calc(50% + var(--b)) calc(50% + var(--b));
border: 5px solid red;;
border-radius: 50%;
transform:rotate(45deg);
}
<button class="exitnew" type="button" aria-label="Close"></button>
You just need to use z-index property on the :after CSS selector:
.exitnew {
-webkit-appearance: none;
appearance: none;
position: relative;
box-sizing: border-box;
margin: auto;
padding: 0;
width: 48px;
height: 48px;
cursor: pointer;
background: blue;
border: none;
border-radius: 50%;
clip-path: circle(50%);
transition: all 1s ease;
overflow: hidden;
}
.exitnew:before,
.exitnew:after {
content: "";
position: absolute;
height: 5px;
top: 22px;
left: -1px;
right: -1px;
background: green;
transform: rotate(45deg);
transition: all 1s ease;
z-index: -1
}
.exitnew:after {
transform: rotate(-45deg);
}
.exitnew:hover {
background: transparent;
}
.exitnew:hover:before,
.exitnew:hover:after {
background: green;
}
.exitnew b {
box-sizing: border-box;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border: 5px solid red;
border-radius: 50%;
}
<button class="exitnew" type="button" aria-label="Close"><b></b></button>
:before and :after are like html bread on you element sandwich. :before is the bottom slice, and :after is the top slice.
Add a negative z-index to the :before, :after styles and that will position your :after behind the button the same as the :before.
.exitnew:before,
.exitnew:after {
content: "";
position: absolute;
height: 5px;
top: 22px;
left: -1px;
right: -1px;
background: green;
transform: rotate(45deg);
transition: all 1s ease;
z-index: -1;
}
EDIT WITHOUT Z-INDEX
.exitnew {
-webkit-appearance: none;
appearance: none;
position: relative;
box-sizing: border-box;
margin: auto;
padding: 0;
width: 48px;
height: 48px;
cursor: pointer;
background: blue;
border: none;
border-radius: 50%;
clip-path: circle(50%);
transition: all 1s ease;
overflow: hidden;
}
.exitnew:before,
.exitnew:after {
content: "";
position: absolute;
height: 5px;
width: 38px;
top: 22px;
left: 5px;
right: 5px;
background: green;
transform: rotate(45deg);
transition: all 1s ease;
}
.exitnew:after {
transform: rotate(-45deg);
}
.exitnew:hover {
background: transparent;
}
.exitnew:hover:before,
.exitnew:hover:after {
background: green;
}
.exitnew b {
box-sizing: border-box;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border: 5px solid red;
border-radius: 50%;
}
<button class="exitnew" type="button" aria-label="Close"><b></b></button>
You can set the z-index property to send the green line(s) backward, "behind" the circle:
.exitnew:before,
.exitnew:after {
content: "";
position: absolute;
height: 5px;
top: 22px;
left: -1px;
right: -1px;
background: green;
transform: rotate(45deg);
transition: all 1s ease;
z-index: -1;
}
here's an example: https://jsfiddle.net/q7zprh4w/
This is a solution without b and z-index:
.exitnew {
position: relative;
width: 48px;
height: 48px;
border: 5px solid red;
border-radius: 50%;
background-color: blue;
}
.exitnew::before {
content: "";
display: block;
position: absolute;
width: 10.416%;
height: 100%;
top: 0;
left: 44.792%;
background-color: green;
transform: rotate(45deg);
}
.exitnew::after {
content: "";
display: block;
position: absolute;
width: 10.416%;
height: 100%;
top: 0;
left: 44.792%;
background-color: green;
transform: rotate(-45deg);
}
I put the red border to the button itself. So the two pseudo element ::before and ::after aren't overlapping the red border.
Note: I don't use box-sizing: border-box

Why is that the before content doesnt contain within the button. i always have this issue designing buttons

The below code makes the before content flow outside the button itself. what should I do to contain it within the button
I need a parameter that fits the before content inside the button itself........................................................................................................................................................................
===================================================
button {
padding: 0.9em 2em;
border: 2px solid #17C3B2;
position: absolute;
background-color: transparent;
text-align: center;
text-transform: uppercase;
font-size: 16px;
color: #ddd;
transition: .3s;
display: block;
font-family: inherit;
color: #17C3B2;
z-index: 1;
}
button::before {
overflow: hidden;
content: '';
width: 0;
height: 100%;
position: absolute;
top: 50%;
left: 50%;
background: #17C3B2;
transition: .5s ease;
display: block;
z-index: ;
}
button span {
position: absolute;
left: 0;
top: 0;
width: 10%;
height: 10%;
background: transparent;
z-index: 1;
}
button span::before {
content: "";
display: block;
position: absolute;
width: 8%;
height: 500%;
background: var(--lightgray);
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(-60deg);
transition: all 0.3s;
}
button:hover::before {
position: absolute;
transform: translate(-50%, -50%) rotate(44deg);
width: 100%;
}
button:hover {
color: #111;
}
<button>hover me
<span></span>
</button>
i have added overflow: hidden; to the button and z-index: -1; to button:hover::before
button {
padding: 0.9em 2em;
border: 2px solid #17C3B2;
position: absolute;
background-color: transparent;
text-align: center;
text-transform: uppercase;
font-size: 16px;
color: #ddd;
transition: .3s;
display: block;
font-family: inherit;
color: #17C3B2;
z-index: 1;
overflow: hidden;
}
button::before {
overflow: hidden;
content: '';
width: 0;
height: 100%;
position: absolute;
top: 50%;
left: 50%;
background: #17C3B2;
transition: .5s ease;
display: block;
z-index: ;
}
button span {
position: absolute;
left: 0;
top: 0;
width: 10%;
height: 10%;
background: transparent;
z-index: 1;
}
button span::before {
content: "";
display: block;
position: absolute;
width: 8%;
height: 500%;
background: var(--lightgray);
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(-60deg);
transition: all 0.3s;
}
button:hover::before {
position: absolute;
transform: translate(-50%, -50%) rotate(44deg);
width: 100%;
z-index: -1;
}
button:hover {
color: #111;
}
<button>hover me
<span></span>
</button>

CSS transition not smooth for one element on hover, but is smooth when mouse moved away

I've got the following CSS and HTML. The problem is, that when the mouse is moved over the button, the red rectangle flashes to the center instead of smoothly moving to the center. It is strange because when the mouse is moved away from the button, it moves back slowly. How can I make the red rectangle move to the center smooth?
.btn {
position: relative;
display: inline-block;
padding: 30px 45px;
margin: 80px;
cursor: pointer;
}
.btn .rect {
transition: all 0.5s linear;
height: 100%;
width: 100%;
opacity: 0.3;
position: absolute;
}
.btn .top-left {
top: -10px;
left: -10px;
}
.btn .bottom-right {
bottom: -10px;
right: -10px;
}
.red-translucent {
background-color: red;
}
.blue-translucent {
background-color: blue;
}
.btn-text {
z-index: 99999;
position: relative;
font-family: Arial;
}
.btn:hover .rect {
top: 0;
bottom: 0;
left: 0;
right: 0;
}
<div class='btn'>
<span class='btn-text'>button</span>
<div class='rect top-left blue-translucent'></div>
<div class='rect bottom-right red-translucent'></div>
</div>
For some reason, it didn't work with bottom: -10px and right: -10px. I'm not sure if this has to do with my code or if this is a browser problem, but the easy fix is to use the top and left properties instead:
.btn {
position: relative;
display: inline-block;
padding: 30px 45px;
margin: 80px;
cursor: pointer;
}
.btn .rect {
transition: all 0.5s linear;
height: 100%;
width: 100%;
opacity: 0.3;
position: absolute;
}
.btn .top-left {
top: -10px;
left: -10px;
}
.btn .bottom-right {
top: 10px;
left: 10px;
}
.red-translucent {
background-color: red;
}
.blue-translucent {
background-color: blue;
}
.btn-text {
z-index: 99999;
position: relative;
font-family: Arial;
}
.btn:hover .rect {
top: 0;
bottom: 0;
left: 0;
right: 0;
}
<div class='btn'>
<span class='btn-text'>button</span>
<div class='rect top-left blue-translucent'></div>
<div class='rect bottom-right red-translucent'></div>
</div>
.red-translucent {
background-color: red;
top: 10px;
left: 10px;
}
Use transform instead of top, left, bottom, right like this:
.btn {
position: relative;
display: flex;
padding: 30px 45px;
margin: 80px;
cursor: pointer;
justify-content: center;
align-items: center;
width: 50px;
height: 50px;
}
.btn .rect {
transition: all 0.5s linear;
height: 100%;
width: 100%;
opacity: 0.3;
position: absolute;
}
.btn .top-left {
transform: translate(-10px, -10px);
}
.btn .bottom-right {
transform: translate(10px, 10px);
}
.red-translucent {
background-color: red;
}
.blue-translucent {
background-color: blue;
}
.btn-text {
z-index: 99999;
position: relative;
font-family: Arial;
}
.btn:hover .rect {
transform: translate(0px, 0px);
}
This will work smoothly on either the move-in or move-out of the pointer.

z-index and position relative

I have a modal, that is show/hide using JavaScript.
In the modal an image will be inserted using JavaScript. Also over the image a div element will exist that will simulate cropping (get the coordinates of the image).
I have a problem making the image to stay below the modal-crop.
modal-crop and the image need to be in the center of modal-area.
I can't use grid or flex because I need to support IE9.
.modal {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1050;
display: none;
overflow: hidden;
outline: 0;
}
.modal-area {
position: absolute;
top: 50%;
left: 50%;
width: 50%;
height: 50%;
transform: translate(-50%, -50%);
margin: 0 auto;
padding: 30px;
background-color: blueviolet;
border-radius: 4px;
box-shadow: 0 0 50px black;
overflow: hidden;
}
.modal-area img {
margin-left: auto;
margin-right: auto;
}
.modal-crop {
position: relative;
background-color: aliceblue;
left: 0;
right: 0;
top: 0;
margin-left: auto;
margin-right: auto;
width: 200px;
height: 200px;
opacity: 0.2;
z-index: 2;
}
<div class="modal">
<div class="modal-area">
<div class="modal-crop"></div>
#img will be inserted here using Javascript#
</div>
</div>
Your image need to be positionned absolutely like this :
.modal {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1050;
overflow: hidden;
outline: 0;
min-height: 300px;
}
.modal-area {
position: absolute;
top: 50%;
left: 50%;
width: 50%;
height: 50%;
transform: translate(-50%, -50%);
margin: 0 auto;
padding: 30px;
background-color: blueviolet;
border-radius: 4px;
box-shadow: 0 0 50px black;
overflow: hidden;
}
.modal-area img {
margin-left: auto;
margin-right: auto;
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
}
.modal-crop {
position: relative;
background-color: aliceblue;
left: 0;
right: 0;
top: 0;
margin-left: auto;
margin-right: auto;
height: 100%;
opacity: 0.2;
z-index: 2;
}
<div class="modal">
<div class="modal-area">
<div class="modal-crop"></div>
<img src="https://lorempixel.com/500/500/">
</div>
</div>
I think I got an understanding of what you want to achieve. And I also know that it can be a pain to overlap elements with absolute positioning in multiple layers (even more so when it comes to different browsers).
I recommend you to use a grid layout, which is quite easy to set up:
HTML
<div class="modal">
<div class="modal-area">
<img src="http://via.placeholder.com/200x200">
<div class="modal-crop"></div>
</div>
</div>
CSS
.modal {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1050;
display: block;
overflow: hidden;
outline: 0;
}
.modal-area {
display:grid;
grid-template-rows: auto;
grid-template-columns: auto;
justify-items:center;
position: absolute;
top: 50%;
left: 50%;
width: 50%;
height: 50%;
transform: translate(-50%, -50%);
margin: 0 auto;
padding: 30px;
background-color: blueviolet;
border-radius: 4px;
box-shadow: 0 0 50px black;
overflow: hidden;
}
.modal-area img {
grid-row: 1/span 1;
grid-column: 1/span 1;
z-index:1;
}
.modal-crop {
width: 200px;
height: 200px;
grid-row: 1/span 1;
grid-column: 1/span 1;
background-color: red;
opacity: 0.2;
z-index:2;
}
Be aware though, that in this solution the "modal crop" needs to be set to width and and height of the image. But I used similar solutions in other situations and will not be hard to adjust it so that it works for any image sizes.
Have a fiddle: https://jsfiddle.net/9odLnh7r/
The question is note very clear, but as far as I understand you need to add this css ruleset to your image:
.modal {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1050;
/* display: none; */
overflow: hidden;
outline: 0;
}
.modal-area {
position: absolute;
top: 50%;
left: 50%;
width: 50%;
height: 50%;
transform: translate(-50%, -50%);
margin: 0 auto;
padding: 30px;
background-color: blueviolet;
border-radius: 4px;
box-shadow: 0 0 50px black;
overflow: hidden;
}
.modal-area img {
margin-left: auto;
margin-right: auto;
}
.modal-crop {
position: relative;
background-color: aliceblue;
left: 0;
right: 0;
top: 0;
margin-left: auto;
margin-right: auto;
width: 200px;
height: 200px;
opacity: 0.2;
z-index: 2;
}
.centerMe {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div class="modal">
<div class="modal-area">
<div class="modal-crop"></div>
<img class="centerMe" src="http://www.budgetstockphoto.com/bamers/stock_photo_spectrum.jpg">
</div>
</div>

How to centre text as CSS content attribute vertically and horizontally?

I would like to center text as CSS3 content attr vertically and horizontally. Centering should have no issues on screen resize.
Please inspect the code at: http://jsfiddle.net/epomschar/3pb3swwe/
<div class="container"></div>
.container {
position: relative;
height: 200px;
width: 200px;
}
.container:after {
position: absolute;
content: 'Center me!';
top: 50%;
right: 0;
bottom: 0;
left: 0;
text-align: center;
transform: translateY(-50%);
}
.container:before {
position: absolute;
content: '';
top: 0;
right: 0;
bottom: 0;
left: 0;
color: white;
background-color: yellow;
border-radius: 50%;
width: 100%;
height: 100%;
}
Solution: http://jsfiddle.net/epomschar/3pb3swwe/7/
Just remove bottom: 0; and you already got the solution.
.container {
position: relative;
height: 200px;
width: 200px;
}
.container:after {
position: absolute;
content: 'Center me!';
top: 50%;
right: 0;
/* bottom: 0; REMOVE THIS LINE */
left: 0;
text-align: center;
transform: translateY(-50%);
}
.container:before {
position: absolute;
content: '';
top: 0;
right: 0;
bottom: 0;
left: 0;
color: white;
background-color: yellow;
border-radius: 50%;
width: 100%;
height: 100%;
}
<div class="container"></div>
Just add a padding to &:after.If you want to change more, you simply add padding-left,padding-right and change the position as you want.This one padding attribute make changes to all over your circle,you can specify changes like what i said you before by using padding-left etc.
.container {
position: relative;
height: 200px;
width: 200px;
&:after {
position: absolute;
content: 'Center me!';
top: 50%;
right: 0;
bottom: 0;
left: 0;
text-align: center;
transform: translateY(-50%);
padding:30px; //MODIFICATION
}
&:before {
position: absolute;
content: '';
top: 0;
right: 0;
bottom: 0;
left: 0;
color: white;
background-color: yellow;
border-radius: 50%;
width: 100%;
height: 100%;
}
}
Else you can add transform: translateY(-30%); and margin:5%; instead of padding:30%;
Do you mean like this? The plus is right in the centre.
.container {
position: relative;
height: 200px;
width: 200px;
}
.container:after {
position: absolute;
content: '+';
color: white;
width: 100%;
font-size: 34px;
top: 50%;
text-align: center;
transform: translateY(-50%);
}
.container:before {
position: absolute;
content: '';
background-color: black;
border-radius: 50%;
width: 100%;
height: 100%;
}
<div class="container"></div>

Resources