<div id="app"></div>
html,
body {
height: 100%;
overflow: hidden;
}
body {
color: #6699CC;
font-size: 22px;
font-weight: bold;
text-align: center;
font-smoothing: antialiased;
display: flex;
align-items: center;
justify-content: center;
background-color: #C594C5;
background-size: cover;
background-position: center;
background-image: linear-gradient(rgba(lightblue, 0.4), rgba(plum, 0.4)),
url('https://i.imgsafe.org/1fee5c9.jpg');
}
.fancy-button {
position: relative;
display: block;
cursor: pointer;
perspective: 1800px;
.fancy-flipper {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
transform-style: preserve-3d;
transform: rotateX(-90deg);
transition: transform 0.3s ease;
}
.fancy-front,
.fancy-back {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
backface-visibility: hidden;
svg {
display: block;
}
}
&:hover {
.fancy-flipper {
transform: rotateX(0deg);
}
}
&:active {
.fancy-flipper {
transform: rotateX(0deg) scale(0.95);
transition: transform 0.05s ease;
}
}
.button-text {
letter-spacing: 0.01em;
font-family: Futura, "Helvetica Neue", Helvetica, sans-serif;
}
}
View Compiled
class FancyButton extends React.Component {
render() {
// Mask id and styling
// need unique id's for multiple buttons
const maskId = 'mask_1';
const maskStyle = '#fancy-masked-element_' + maskId + ' { mask: url(#' + maskId + '); -webkit-mask: url(#' + maskId + ')}';
const buttonStyle = {
width: this.props.width,
height: this.props.height
};
const fancyFrontStyle = {
transform: 'rotateX(0deg) translateZ(' + this.props.height / 2 + 'px )'
};
const fancyBackStyle = {
transform: 'rotateX(90deg) translateZ( ' + this.props.height / 2 + 'px )'
};
// SVG attributes
const textTransform = 'matrix(1 0 0 1 ' + this.props.width / 2 + ' ' + this.props.height / 1.6 + ')';
const viewBox = '0 0 ' + this.props.width + ' ' + this.props.height;
return (
<div className="fancy-button"
style={buttonStyle}
ref="fancyButton">
<div className="fancy-flipper">
<div className="fancy-front" style={fancyFrontStyle}>
<svg
height={this.props.height}
width={this.props.width}
viewBox={viewBox}>
<defs>
<mask id={maskId}>
<rect width="100%" height="100%" fill="#FFFFFF"/>
<text className="mask-text button-text" fill="#000000" transform={textTransform} fontFamily="'intro_regular'" fontSize={this.props.fontSize} width="100%" textAnchor="middle" letterSpacing="1">{this.props.buttonText}</text>
</mask>
</defs>
<style>
{maskStyle}
</style>
<rect id={'fancy-masked-element_' + maskId} fill={this.props.color} width="100%" height="100%"/>
</svg>
</div>
<div className="fancy-back" style={fancyBackStyle}>
<svg
height={this.props.height}
width={this.props.width}
viewBox={viewBox}>
<rect stroke={this.props.color}
strokeWidth={this.props.borderWidth}
fill="transparent"
width="100%"
height="100%"/>
<text className="button-text" transform={textTransform} fill={this.props.color} fontFamily="'intro_regular'" fontSize={this.props.fontSize} textAnchor="middle" letterSpacing="1">{this.props.buttonText}</text>
</svg>
</div>
</div>
</div>
);
}
}
FancyButton.defaultProps = {
color: '#FFFFFF',
width: 410,
height: 100,
fontSize: 40,
borderWidth: 15,
buttonText: 'FANCY BUTTON',
};
React.render(<FancyButton />, document.getElementById('app'));
View Compiled
This Pen doesn't use any external CSS resources.