I was trying to create a custom Select component using MUI.
I tried using MUI Base components, with the combination of SelectUnstyled, OptionUnstyled and PopperUnstyled.
I looked for the docs and got it working.
However, I need some animation on the PopperUnstyled component (the part that pops up after we click on the Select button).
Here's my current implementation:
const StyledButton = styled("button")(
({ theme }) => `
font-family: ${theme.typography.fontFamily};
position: relative;
font-size: 0.875rem;
box-sizing: border-box;
min-height: calc(1.5em + 22px);
min-width: 320px;
border: 1px solid #D8DAE5;
background-color: #fff;
outline: none;
padding: 8px 12px;
border-radius: 8px;
text-align: left;
line-height: 1.5;
transition-property: all;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 120ms;
&.${selectUnstyledClasses.focusVisible} {
border: 1px solid ${theme.palette.secondary.main}
}
&.${selectUnstyledClasses.expanded} {
&::after {
transform: rotate(180deg);
}
}
&::after {
content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='7' fill='none'%3E%3Cpath fill='%23808D9E' d='M10.673.303a1.042 1.042 0 0 0-1.469 0L5.464 3.99 1.777.303a1.042 1.042 0 1 0-1.469 1.48l4.417 4.416a1.042 1.042 0 0 0 1.479 0l4.469-4.417a1.042 1.042 0 0 0 0-1.48Z'/%3E%3C/svg%3E");
position: absolute;
right: .8rem;
}
`
);
const StyledListbox = styled("ul")(
({ theme }) => `
font-size: 0.875rem;
background-color: ${theme.palette.grey[50]};
box-sizing: border-box;
padding:8px;
margin: 8px 0;
min-width: 320px;
border-radius: 8px;
overflow: auto;
outline: 0px;
border: 1px solid ${alpha(theme.palette.primary.main, 0.25)};
box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px, rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;
animation: slideUp 100ms ease;
`
);
export const StyledOption = styled(OptionUnstyled)(
({ theme }) => `
list-style: none;
padding: 8px 16px;
border-radius: 8px;
cursor: default;
&:last-of-type {
border-bottom: none;
}
&.${optionUnstyledClasses.selected} {
background-color: ${theme.palette.grey[300]};
color: ${theme.palette.primary.main};
font-weight: 500;
}
&.${optionUnstyledClasses.disabled} {
color: ${theme.palette.grey[300]};
}
`
);
const StyledPopper = styled(PopperUnstyled)`
z-index: 1;
`;
export function StyledSelect(props) {
const slots = {
root: StyledButton,
listbox: StyledListbox,
popper: StyledPopper,
...props.slots,
};
return <SelectUnstyled {...props} slots={slots} />;
}
I did some research and found a way of defining keyframes using styled utility but I didn't get it working with tagged template literals that I am using to style my Select component
const StyledListbox = styled("ul")(
({ theme }) => `
"#keyframes slideUp": {
from: {
opacity: 0,
transform: translateY(1rem)
},
to: {
opacity: 1,
transform: none
}
},
font-size: 0.875rem;
background-color: ${theme.palette.grey[50]};
box-sizing: border-box;
padding:8px;
margin: 8px 0;
min-width: 320px;
border-radius: 8px;
overflow: auto;
outline: 0px;
border: 1px solid ${alpha(theme.palette.primary.main, 0.25)};
box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px, rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;
animation: slideUp 100ms ease;
`
);
I also found a utility called keyframes under #mui/system but did not find any documentation on that.
Related
In my project we needed to style the checkbox element. I have seen that a common aproach is to style the :before element of the associated label instead.
So far I have managed to implement most of it, but I am having an issue with the :before element pushing the first line of the label text to the right.
I am trying to align all the text in the label to the right of the :before element, but so far the second line always starts at the same place than the :before element.
I am not a frontend dev, but I have tried changing padding, margin, left, position, etc. But I am at a loss.
This is how it looks:
I want all the text of the label ot start at the red line.
You can see what I have so far in this Fiddle.
.container-box{
display:block;
max-width:200px;
}
.neat-checkbox {
display: inline;
width:40px;
}
.neat-checkbox input[type=checkbox] {
position: absolute;
top: 0;
left: 0;
margin-left: 0;
cursor: pointer;
opacity: 0;
z-index: 1;
font-size: 10px !important;
display: none;
}
.neat-checkbox label {
margin-left: 0px;
margin-top: 2px;
line-height: 17px !important;
}
.neat-checkbox label:before {
font-family: "FontAwesome";
content: "\f00c";
color: white;
position: relative;
left: -5px;
top: 0px;
outline: none;
cursor: pointer;
display: inline-block;
width: 17px;
height: 17px;
border: 1px solid #ced4da;
border-radius: 3px;
background-color: #fff;
transition: border 0.15s ease-in-out, color 0.15s ease-in-out;
box-sizing: border-box;
font-size: 11px;
padding-left: 2px;
line-height: 17px;
}
.neat-checkbox input[type=checkbox]:checked + label:before {
background-color: #2bb19e;
border-color: #2bb19e;
color: #fff;
font-family: "FontAwesome";
content: "\f00c";
font-size: 11px;
padding-left: 2px;
line-height: 17px;
}
.neat-checkbox input[type="checkbox"]:focus + label::before {
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
}
<div class="container-box">
<div>
<label>Some other stuff</label>
</div>
<div class="neat-checkbox">
<input type="checkbox" class="checkbox-list" id="checkboxId_25600" name="name_25600" value="25600">
<label for="checkboxId_25600">Label For Checkbox MOre more more</label>
</div>
</div>
Give the label some left padding and position the :before element absolutely within it. EG:
.container-box {
display: block;
max-width: 200px;
}
.neat-checkbox {
display: inline;
width: 40px;
}
.neat-checkbox input[type=checkbox] {
position: absolute;
top: 0;
left: 0;
margin-left: 0;
cursor: pointer;
opacity: 0;
z-index: 1;
font-size: 10px !important;
display: none;
}
.neat-checkbox label {
margin-left: 0px;
margin-top: 2px;
line-height: 17px !important;
display: inline-block; /* make it block-level */
position: relative; /* so that child elements can be positioned relative to it */
padding-left: 25px; /* allow some space for the pseudo checkbox */
}
.neat-checkbox label:before {
font-family: "FontAwesome";
content: "\f00c";
color: white;
left: 0px;
top: 0px;
outline: none;
cursor: pointer;
display: block; /* make it block-level */
position: absolute; /* give an absolute position (defaults to 0,0) */
width: 17px;
height: 17px;
border: 1px solid #ced4da;
border-radius: 3px;
background-color: #fff;
transition: border 0.15s ease-in-out, color 0.15s ease-in-out;
box-sizing: border-box;
font-size: 11px;
padding-left: 2px;
line-height: 17px;
}
.neat-checkbox input[type=checkbox]:checked+label:before {
background-color: #2bb19e;
border-color: #2bb19e;
color: #fff;
font-family: "FontAwesome";
content: "\f00c";
font-size: 11px;
padding-left: 2px;
line-height: 17px;
}
.neat-checkbox input[type="checkbox"]:focus+label::before {
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
}
<div class="container-box">
<div>
<label>Some other stuff</label>
</div>
<div class="neat-checkbox">
<input type="checkbox" class="checkbox-list" id="checkboxId_25600" name="name_25600" value="25600">
<label for="checkboxId_25600">Label For Checkbox MOre more more</label>
</div>
</div>
The problem is that you are moving the checkbox using position relative, so the original space is preserved but you just move the visual 5px to the left.
You can add a margin-right: -5px if you use left: -5px or remove the left property and just use margin-left: -5px instead.
How do I convert standard CSS with special attributes like "type" and "active", to Styled-Components consts?
.box {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
background: #fff;
padding: 40px;
border: 1px solid rgba(0, 0, 0, 0.1);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
}
input[type='submit'] {
background: #00aec9;
color: #fff;
cursor: pointer;
margin-bottom: 0;
text-transform: uppercase;
width: 100%;
border-radius: 5px;
height: 35px;
border-color: transparent;
box-shadow: 0px;
outline: none;
transition: 0.15s;
text-align: center;
}
input[type='submit']:active {
background-color: #f1ac15;
}
I managed to create the const for the .box CSS class but not sure how to achieve this with "input[type='submit']" and "input[type='submit']:active"
//---- .box class ------ //
const DivBox = styled.div`
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
background: #fff;
padding: 40px;
border: 1px solid rgba(0, 0, 0, 0.1);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
`
Any assistance would be greatly appreciated
PS, I am using React and Nextjs
What I currently have:
What I want:
My current Component Code:
import Layout from '../components/MyLayout.js'
import styled from 'styled-components'
const DivBox = styled.div`
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
background: #fff;
padding: 40px;
border: 1px solid rgba(0, 0, 0, 0.1);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
`
const Input = styled.input.attrs({ type: 'submit' })`
background: #00aec9;
color: #fff;
cursor: pointer;
margin-bottom: 0;
text-transform: uppercase;
width: 100%;
border-radius: 5px;
height: 35px;
border-color: transparent;
box-shadow: 0px;
outline: none;
transition: 0.15s;
text-align: center;
&:active {
background-color: #f1ac15;
}
`
export default function About() {
return (
<Layout>
<DivBox>
<p>This is the about page</p>
<h2>Sample Form</h2>
<div className="form-label-group">
<input
type="email"
id="inputEmail"
className="form-control"
placeholder="Email address"
required
autoFocus
/>
<label htmlFor="inputEmail">Email address</label>
</div>
<div className="form-label-group">
<input
type="password"
id="inputPassword"
className="form-control"
placeholder="Password"
required
/>
<label htmlFor="inputPassword">Password</label>
</div>
<div>
<input type="submit" value="Submit" />
</div>
</DivBox>
</Layout>
)
}
Additional CSS:
.form-control:focus {
border-color: #00aec9;
box-shadow: 0 0 0 0.2rem rgba(19, 162, 228, 0.25);
}
.form-label-group input:not(:placeholder-shown) ~ label {
color: #00aec9;
}
I guess you can achieve that by:
const Input = styled.input.attrs({
type: 'submit',
value: 'Submit'
})`
background: #00aec9;
color: #fff;
cursor: pointer;
margin-bottom: 0;
text-transform: uppercase;
width: 100%;
border-radius: 5px;
height: 35px;
border-color: transparent;
box-shadow: 0px;
outline: none;
transition: 0.15s;
text-align: center;
&:active {
background-color: #f1ac15;
}
`
And replace
<input type="submit" value="Submit" />
with
<Input />
More informations on attrs here
I'm styling my checkboxes to look like toggle switches which works beautifully in Chrome, UC Browser, Safari for Windows and is a bit choppy in Firefox but acceptable. Unfortunately in Edge it doesn't work at all.
I've looked through the CSS properties I'm using and it appears as though all are supported by Edge so I don't understand what I'm missing.
.toggle{
width:34px;
height:16px;
border-radius:40px;
position:relative;
-webkit-appearance: none;
margin:2px 0 0 0px;
box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.4);
background: -webkit-linear-gradient(#c6c6c6,#e3e3e3);
cursor:hand;cursor:pointer;pointer:hand;
outline: 0;
}
.toggle:checked{
background: -webkit-linear-gradient(#77178F,#AD73BB);
box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.4);
}
.toggle:before {
content:'';
letter-spacing:1px;
color: rgba(0,0,0,.15);
font-size:10px;
font-weight:100;
text-shadow:1px 1px 1px rgba(255,255,255,1);
width:7px;
height:7px;
padding:2px;
top:2px;
left:2px;
position:absolute;
border-radius:40px;
background: linear-gradient(#ebebeb,#f1f1f1);
box-shadow: -2px 2px 8px rgba(0, 0, 0, 0.2),
-1px 1px 2px rgba(0, 0, 0, 0.3),
inset 1px 1px 1px #ffffff;
transition: all 0.4s;
}
.toggle:checked:before {
left:20px;
background:#f1f1f1;
}
.toggle:checked:after {
background: linear-gradient(#d8eec4,#5fa718);
box-shadow: inset -1px -1px 4px #417f0b,
inset 1px 1px 2px #5b9f1a;
}
<input type=checkbox class=toggle>
It looks to me like -webkit-appearance:none is not doing what it's supposed to (hide the original checkbox) but that also is supposedly supported.
If anybody has any experience with this issue and can give me some insight it would be much appreciated.
It's better to hide a checkbox, wrap it with another element (e.g. label) and add a sibling to the checkbox. You can find an example of checkbox-switch here https://www.w3schools.com/howto/howto_css_switch.asp.
Or you can adjust code below:
.toggle {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.toggle input[type=checkbox] {
opacity: 0; /* or use display: none; to hide default checkbox */
width: 0;
height: 0;
}
.toggle .slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(#ebebeb, #f1f1f1);
box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.4);
-webkit-transition: .4s;
transition: .4s;
}
.toggle .slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background: #ffffff;
-webkit-transition: .4s;
transition: .4s;
}
.toggle input[type=checkbox]:checked + .slider {
background: linear-gradient(#77178F,#AD73BB);
box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.4);
}
.toggle input[type=checkbox]:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
.toggle .slider.round {
border-radius: 34px;
}
.toggle .slider.round:before {
border-radius: 50%;
}
<label class="toggle">
<input type="checkbox">
<span class="slider round"></span>
</label>
You could add a label to meet your requirements as a workaround. In this way you could connect a label with a checkbox and apply the styles to the label instead of the checkbox itself.
Here is my testing code.
CSS.
.toggle {
visibility: hidden;
opacity: 0;
}
.toggle + label {
width: 34px;
height: 16px;
border-radius: 40px;
position: relative;
box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.4);
background: linear-gradient(#c6c6c6,#e3e3e3);
cursor: pointer;
outline: 0;
display: inline-block;
}
.toggle + label:before {
content: '';
letter-spacing: 1px;
color: rgba(0,0,0,.15);
font-size: 10px;
font-weight: 100;
text-shadow: 1px 1px 1px rgba(255,255,255,1);
width: 7px;
height: 7px;
padding: 2px;
top: 2px;
left: 2px;
position: absolute;
border-radius: 40px;
background: linear-gradient(#ebebeb,#f1f1f1);
box-shadow: -2px 2px 8px rgba(0, 0, 0, 0.2), -1px 1px 2px rgba(0, 0, 0, 0.3), inset 1px 1px 1px #ffffff;
transition: all 0.4s;
}
.toggle:checked + label {
background: linear-gradient(#77178F,#AD73BB);
box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.4);
}
.toggle:checked + label:before {
left: 20px;
background: #f1f1f1;
}
.toggle:checked + label:after {
background: linear-gradient(#d8eec4,#5fa718);
box-shadow: inset -1px -1px 4px #417f0b, inset 1px 1px 2px #5b9f1a;
}
HTML
<input type="checkbox" class="toggle" id="mycheckbox">
<label for="mycheckbox" />
Adding another flexible variation of the selected answer to the mix: https://codepen.io/hawatt/pen/MWKyJJZ
HAML
.toggle-switch
%input{type: 'checkbox', id: 'away-from-desk' }
%span.toggle-handle
%label{'for' => 'away-from-desk'} Away from desk
SCSS
$toggle-width: 2.8rem;
$toggle-height: 1.5rem;
$toggle-handle-diameter: calc(#{$toggle-height} * 0.8);
.toggle-switch {
position: relative;
display: flex;
align-items: center;
input {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
width: $toggle-width;
height: $toggle-height;
display: inline-flex;
position: relative;
border-radius: $toggle-height;
overflow: hidden;
outline: none;
border: none;
cursor: pointer;
background-color: #c0c0c0;
transition: all ease 0.3s;
z-index: 0;
text-indent: -5000px;
}
.toggle-handle {
pointer-events: none;
display: flex;
position: absolute;
z-index: 2;
width: $toggle-handle-diameter;
height: $toggle-handle-diameter;
background: #fff;
border-radius: 50%;
left: 0;
margin: 0 0.35rem;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
transition: all ease 0.3s;
}
input:checked,
input.enabled {
background-color: dodgerblue;
& + .toggle-handle {
left: calc(#{$toggle-width} - #{$toggle-handle-diameter} - 0.25rem);
}
}
label {
cursor: pointer;
}
}
I am trying to work on the following example for a user profile.
I have a problem with the text on my various fields though. I would like them to be centered horizontally and vertically.
Using
vertical-align: middle;
Did not work for me, or I did something wrong.
How can I make it so each text snippet is perfectly centered on its respective container?
Here's the solution:
/* --------------------------------
Primary style
-------------------------------- */
#font-face {
font-family: 'Roboto';
src: url('../fonts/roboto/Roboto-Regular.ttf');
font-weight: normal;
font-style: normal;
}
*,
*:before,
*:after {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
div {
display: block;
}
html,
body {
background: #f1f1f1;
font-family: 'Roboto', sans-serif;
padding: 1em;
}
h1 {
text-align: center;
color: #a8a8a8;
font-size: 200%;
}
.user-data {
-webkit-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
position: relative;
overflow: hidden;
cursor: pointer;
display: table;
width: 100%;
height: 85px;
background: white;
margin: 0 auto;
margin-top: 1em;
margin-bottom: 20px;
border-radius: 8px;
-webkit-transition: all 250ms;
transition: all 250ms;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
}
.response-layer {
vertical-align: middle;
display: table-cell;
text-align: center;
font-size: 200%;
color: #a8a8a8;
}
#user-action-text {
color: #f1f1f1;
font-size: 400%;
}
#user-name {
border: 0;
outline: 0;
padding: 0;
margin: 0px;
margin-top: 10px;
width: 304px;
height: 55px;
color: white;
}
#user-action {
background: #e74c3c;
height: 134px;
}
#user-position {
height: 74px;
}
#user-uuid {
height: 54px;
}
section {
max-width: 650px;
text-align: center;
margin: 20px auto;
}
section img {
border: 0;
outline: 0;
padding: 0;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
display: block;
width: 100%;
margin-top: 1em;
-webkit-transition: all 250ms;
transition: all 250ms;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
resize: none;
}
.half {
float: left;
width: 48%;
margin-bottom: 1em;
}
.right {
width: 50%;
}
.left {
margin-right: 2%;
}
.user-data:hover {
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
-webkit-transform: translateY(-5px);
-ms-transform: translateY(-5px);
transform: translateY(-5px);
}
section img:hover {
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
-webkit-transform: translateY(-5px);
-ms-transform: translateY(-5px);
transform: translateY(-5px);
}
#-webkit-keyframes loading {
0%, 100% {
margin-top: -50px;
box-shadow: 0px 55px 40px 0px rgba(0, 0, 0, 0.3);
}
30%,
80% {
margin-top: 0px;
box-shadow: 0px 0px 0px 0px rgba(0, 0, 0, 0.5);
}
}
#keyframes loading {
0%, 100% {
margin-top: -50px;
box-shadow: 0px 55px 40px 0px rgba(0, 0, 0, 0.3);
}
30%,
80% {
margin-top: 0px;
box-shadow: 0px 0px 0px 0px rgba(0, 0, 0, 0.5);
}
}
#media (max-width: 690px) {
.half {
width: 304px;
float: none;
margin-bottom: 0;
}
}
/* Clearfix */
.activity-detail:before,
.activity-detail:after {
content: " ";
/* 1 */
display: table;
/* 2 */
}
.activity-detail:after {
clear: both;
}
<h1>New Activity Details</h1>
<section class="activity-detail">
<div class="half right" id="image-data">
<img src="img/default-avatar.png" alt="Profile Photo" style="width:304px;height:304px;" id="profile-photo">
<a class="user-data" id="user-name">
<div class="response-layer">Green Leaf</div>
</a>
</div>
<div class="half left" id="general-data">
<a class="user-data" id="user-action">
<div class="response-layer" id="user-action-text">Greetings</div>
</a>
<a class="user-data" id="user-position">
<div class="response-layer">Developer</div>
</a>
<a class="user-data" id="user-uuid">
<div class="response-layer">324124535345</div>
</a>
</div>
</section>
On the parent div .user-data I changed display to table.
On the child div .response-layer (the one containing "Greetings") I changed the display to table-cell. Now the vertical align works.
Here's the link to the codepen: Codepen
Replacing
vertical-align: middle;
with
position: relative;
top: 25%;
does the trick.
Edit: The answer above is much cleaner
https://jsfiddle.net/qd2o38fp/1/
I want the user to be able to hover over the circle, and then click the circle itself to be directed to another link. (not the text when hovered)
.ch-item {
width: 100%;
height: 100%;
border-radius: 50%;
overflow: hidden;
position: relative;
cursor: default;
box-shadow:
inset 0 0 0 16px rgba(255,255,255,0.6),
0 1px 2px rgba(0,0,0,0.1);
transition: all 0.4s ease-in-out;
content: url(www.yahoo.com);
}
I tried to put
content: url(www.yahoo.com);
but this makes the text disappear for some reason.
If you want to be able to click it, it must be a link:
<a href="//www.yahoo.com" class="ch-info">
<h3>See Portfolio</h3>
</a>
Just display it as a block, and your current code will work:
.ch-info {
display: block;
}
.ch-grid {
margin: 20px 0 0 0;
padding: 0;
list-style: none;
display: block;
text-align: center;
width: 100%;
}
.ch-grid::after {
clear: both;
}
.ch-grid li {
width: 220px;
height: 220px;
display: inline-block;
margin: 20px;
}
.ch-item {
width: 100%;
height: 100%;
border-radius: 50%;
overflow: hidden;
position: relative;
cursor: default;
box-shadow: inset 0 0 0 16px rgba(255, 255, 255, 0.6), 0 1px 2px rgba(0, 0, 0, 0.1);
transition: all 0.4s ease-in-out;
}
.ch-img-1 {
background-image: url(http://www.pulsarwallpapers.com/data/media/3/Alien%20Ink%202560X1600%20Abstract%20Background.jpg);
}
.ch-img-2 {
background-image: url(../images/2.jpg);
}
.ch-img-3 {
background-image: url(../images/3.jpg);
}
.ch-info {
position: absolute;
background: rgba(63, 147, 147, 0.8);
width: inherit;
height: inherit;
border-radius: 50%;
overflow: hidden;
opacity: 0;
transition: all 0.4s ease-in-out;
transform: scale(0);
display: block;
}
.ch-info h3 {
color: #fff;
text-transform: uppercase;
letter-spacing: 2px;
font-size: 22px;
margin: 0 30px;
padding: 45px 0 0 0;
height: 140px;
font-family: 'Open Sans', Arial, sans-serif;
text-shadow: 0 0 1px #fff, 0 1px 2px rgba(0, 0, 0, 0.3);
}
.ch-info p {
color: #fff;
padding: 10px 5px;
font-style: italic;
margin: 0 30px;
font-size: 12px;
border-top: 1px solid rgba(255, 255, 255, 0.5);
opacity: 0;
transition: all 1s ease-in-out 0.4s;
}
.ch-info p a {
display: block;
color: rgba(255, 255, 255, 0.7);
font-style: normal;
font-weight: 700;
text-transform: uppercase;
font-size: 9px;
letter-spacing: 1px;
padding-top: 4px;
font-family: 'Open Sans', Arial, sans-serif;
}
.ch-info p a:hover {
color: rgba(255, 242, 34, 0.8);
}
.ch-item:hover {
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1), 0 1px 2px rgba(0, 0, 0, 0.1);
}
.ch-item:hover .ch-info {
transform: scale(1);
opacity: 1;
}
.ch-item:hover .ch-info p {
opacity: 1;
}
.ch-item::before {
content: "P";
position: absolute;
font-size: 180px;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
}
<ul class="ch-grid">
<li>
<div class="ch-item ch-img-1">
<a href="//www.yahoo.com" class="ch-info">
<h3>See Portfolio</h3>
</a>
</div>
</li>
</ul>
extending Oriol's you could also use clip-path: circle(110px at center);
to limit :hover selection
.ch-grid {
margin: 20px 0 0 0;
padding: 0;
list-style: none;
display: block;
text-align: center;
width: 100%;
}
.ch-grid::after {
clear: both;
}
.ch-grid li {
width: 220px;
height: 220px;
display: inline-block;
margin: 20px;
}
.ch-item {
width: 100%;
height: 100%;
border-radius: 50%;
overflow: hidden;
position: relative;
cursor: default;
box-shadow: inset 0 0 0 16px rgba(255, 255, 255, 0.6), 0 1px 2px rgba(0, 0, 0, 0.1);
transition: all 0.4s ease-in-out;
}
.ch-img-1 {
background-image: url(http://www.pulsarwallpapers.com/data/media/3/Alien%20Ink%202560X1600%20Abstract%20Background.jpg);
}
.ch-img-2 {
background-image: url(../images/2.jpg);
}
.ch-img-3 {
background-image: url(../images/3.jpg);
}
.ch-info {
position: absolute;
background: rgba(63, 147, 147, 0.8);
width: inherit;
height: inherit;
border-radius: 50%;
overflow: hidden;
opacity: 0;
transition: all 0.4s ease-in-out;
transform: scale(0);
display: block;
}
.ch-info h3 {
color: #fff;
text-transform: uppercase;
letter-spacing: 2px;
font-size: 22px;
margin: 0 30px;
padding: 45px 0 0 0;
height: 140px;
font-family: 'Open Sans', Arial, sans-serif;
text-shadow: 0 0 1px #fff, 0 1px 2px rgba(0, 0, 0, 0.3);
}
.ch-info p {
color: #fff;
padding: 10px 5px;
font-style: italic;
margin: 0 30px;
font-size: 12px;
border-top: 1px solid rgba(255, 255, 255, 0.5);
opacity: 0;
transition: all 1s ease-in-out 0.4s;
}
.ch-info p a {
display: block;
color: rgba(255, 255, 255, 0.7);
font-style: normal;
font-weight: 700;
text-transform: uppercase;
font-size: 9px;
letter-spacing: 1px;
padding-top: 4px;
font-family: 'Open Sans', Arial, sans-serif;
clip-path: circle(110px at center);
}
.ch-info p a:hover {
color: rgba(255, 242, 34, 0.8);
clip-path: circle(110px at center);
}
.ch-item:hover {
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1), 0 1px 2px rgba(0, 0, 0, 0.1);
clip-path: circle(110px at center);
}
.ch-item:hover .ch-info {
transform: scale(1);
opacity: 1;
}
.ch-item:hover .ch-info p {
opacity: 1;
}
.ch-item::before {
content: "P";
position: absolute;
font-size: 180px;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
}
<ul class="ch-grid">
<li>
<div class="ch-item ch-img-1">
<a href="//www.yahoo.com" class="ch-info">
<h3>See Portfolio</h3>
</a>
</div>
</li>
</ul>