I'm looking to allow visitors to my website the ability to rotate the webpage upside (180º) with the click of a button.
I know I can go into the CSS and add the following code to completely flip it:
body{
-moz-transform: rotate(180deg);
-webkit-transform: rotate(180deg);
-o-transform: rotate(180deg);
}
But I want to be able to give the user the ability to essentially turn this on/off. Is there a way to do this?
BONUS POINTS if the rotation can be CSS animated to do a smooth transition. But not required.
You can assign an event to a button or link, and on click, the page will flip.
const button = document.querySelector('.button');
const changeClass = (e) => {
const body = document.querySelector('.main');
body.classList.toggle('rotate');
};
button.addEventListener('click', (e) => {
changeClass(e);
});
body {
margin: 0;
}
.main {
background: url(https://japan-forward.com/wp-content/uploads/2022/02/Mt-Fuji-Eruption-Volcano-006-scaled.jpg);
background-size: cover;
height: 100vh;
}
.rotate {
transform: rotate(180deg);
-moz-transform: rotate(180deg);
-webkit-transform: rotate(180deg);
-o-transform: rotate(180deg);
}
.container {
display: flex;
flex-direction: column;
align-items: center;
text-decoration: none;
width: 100vw;
}
.text {
color: #ffffff;
margin-bottom: 5px;
}
.button {
width: 140px;
height: 100px;
border-radius: 20px;
border-width: 0;
font-family: 'Roboto', sans-serif;
font-size: 20px;
background-size: 100%;
background-color: blue;
color: #ffffff;
}
.footer {
background: #ff0000;
width: 100%;
height: 40px;
position: absolute;
bottom: 0;
text-align: center;
font-size: 20px;
}
<div class="main">
<div class="container">
<button class="button">Click to rotate 180</button>
<footer class="footer">Footer</footer>
</div>
</div>
Related
This question already has an answer here:
How to keep origin in center of image in scale animation?
(1 answer)
Closed 1 year ago.
I tried to put a button in the center of my div but I couldn't though all my other contents are centered.
My code:
.middle {
width: 100%;
height: auto;
text-align: center;
position: relative;
}
.middle section {
padding: 18vh 6%;
line-height: 0.5;
color: #EE6352;
font-weight: 400;
font-size: calc(16px + 3vw);
}
.middle ul {
text-align: left;
}
.middle li {
font-size: calc(12px + 2vw);
line-height: 1.25;
color: #2A2D34;
}
.middle p {
font-size: calc(14px + 2.4vw);
font-weight: 400;
color: #2A2D34;
}
.upbutton {
padding: 10px;
background: #1ac6ff;
border-radius: 50%;
border-style: none;
cursor: pointer;
position: absolute;
top: 0px;
transition: background 0.3s;
box-shadow: 2px 2px 5px rgba(102, 102, 102, 0.5);
}
.upbutton img {
width: 25px;
height: 25px;
}
.upbutton:hover {
background: #00ace6;
-webkit-transform: scale(0.94);
-ms-transform: scale(0.94);
transform: scale(0.94);
}
.upbutton:active {
background: #0086b3;
}
<a id="middle">
<div class="middle">
</a>
<section>
<button class="upbutton"><img src="img/arrow.png"></button>
<h1>content</h1>
<ul>
<li>content</li>
<li>content</li>
<li>content</li>
</ul>
<p>...and more</p>
</section>
</div>
I also searched on this problem and tried to put this into the .upbutton class:
margin:0;
-ms-transform: translateX(-50%);
transform: translateX(-50%);
and it centered my button. But when I hover, it didn't center anymore.
I don't know why I'm kinda new to this. Can anyone explain and help me, tks a lot!
Remember to add a transform: translateX(-50%); on the :hover selector for the button, this way it wont go back. If you change the transform property on hover it overides the existing one, so it goes back to translateX(0)
.upbutton:hover {
background: #00ace6;
-webkit-transform: translateX(-50%) scale(0.94);
-ms-transform: translateX(-50%) scale(0.94);
transform: translateX(-50%) scale(0.94);
}
<head>
<style>
.middle
{
width: 100%;
height: auto;
text-align: center;
position: relative;
}
.middle section
{
padding: 18vh 6%;
line-height: 0.5;
color: #EE6352;
font-weight: 400;
font-size:calc(16px + 3vw);
}
.middle ul
{
text-align: left;
}
.middle li
{
font-size: calc(12px + 2vw);
line-height: 1.25;
color: #2A2D34;
}
.middle p
{
font-size: calc(14px + 2.4vw);
font-weight: 400;
color: #2A2D34;
}
.upbutton
{
padding: 10px;
background: #1ac6ff;
border-radius: 50%;
border-style: none;
cursor: pointer;
position: absolute;
top:50%;
left:50%;
transition: background 0.3s;
box-shadow: 2px 2px 5px rgba(102, 102, 102, 0.5);
}
.upbutton img{width: 25px;height: 25px;}
.upbutton:hover{ background: #00ace6;
-webkit-transform: scale(0.94);
-ms-transform: scale(0.94);
transform: scale(0.94); }
.upbutton:active{background: #0086b3;}
</style>
</head>
<a id="middle"><div class="middle"></a>
<section>
<button class="upbutton"><img src="https://png.pngtree.com/png-vector/20190419/ourmid/pngtree-vector-up-arrow-icon-png-image_956434.jpg"></button>
<h1>content</h1>
<ul>
<li>content</li>
<li>content</li>
<li>content</li>
</ul>
<p>...and more</p>
</section>
</div>
In this example you can just use 'position': absolute and top:50%,left:50%
If you're trying to center it just add
top: 50%; property to the .upbutton class
Try doing it directly in the HTML. EDIT: Try using JS.
<center><button onclick = "goToTop()" id = "buttonId"><img src="img/arrow.png"></img></button></center>
<script>
function goToTop(){
var currentLink = window.location.href;
window.location = currentLink+'#top';
}
</script>
Tell me if this doesn't work for you and I'll try to fix it. Also, please accept if this did work for you. It works for me in Chrome.
document.querySelector( 'style' ).innerHTML += `
div {
width: 40rem;
height: 1rem;
background-color: #444;
}
.earth_orbit, .moon {
width: 15rem;
margin-left: 100%;
background-color: #222;;
}
.earth_orbit::before {
width: 5rem;
height: 5rem;
background-color: #08f;
}
.moon {
width: 2.5rem;
height: 2.5rem;
background-color: #ddd;
}
section {
right: 5%;
width: 37.5%;
height: 50%;
font-size: 5rem;
font-weight: bold;
text-align: center;
backdrop-filter: blur( 2rem );
-webkit-backdrop-filter: blur( 2rem );
/* filter: blur( 1rem ); */ /* Only blur inside element, ignoring the paremter */
}
`;
*, * ::before, * ::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body, main {
overflow: hidden;
height: 100%;
background-color: #111;
color: #eee;
}
html {
font-family: Arial;
font-size: 1.5vmin;
}
main, div, section {
display: flex;
justify-content: center;
align-items: center;
}
div, div::before, section {
position: absolute;
z-index: auto;
width: 10rem;
height: 10rem;
background-color: #f90;
border-radius: 5rem;
content: '';
}
.moon::before {
display: none;
}
<style>
.sun_orbit, .earth_orbit, section {
background-color: transparent;
}
span {
color: #ccc;
font-size: 4rem;
}
.rotate {
animation-name: rotate;
animation-duration: 4s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
#keyframes rotate {
0% { transform: rotate( 0deg ); }
100% { transform: rotate( 360deg ); }
}
.offset {
animation-duration: 1s;
}
</style>
<main>
<div class='sun_orbit rotate'>
<div class='earth_orbit rotate offset'>
<div class='moon'></div>
</div>
</div>
<section>
<p>blurred overlay<br><span>( backdrop-filter )</span></p>
</section>
</main>
Where the CSS property backdrop-filter is used there are always sharp edges along the elements border. However to blur the edges themselves along with all content underneath is the desired result. setting filter: blur( *value* ) on the target element doesn't seem to do the trick in any browser i've tested.
There's this question asked over a year ago with no answer and perhaps not as clear an example of what is trying to be accomplished here. Every time the 'planets' go behind the blurred div you can see a clear edge of where the div begins and ends - like crisp glass. I'd like to find a way to maintain all the effects here but blur that edge or border along the 'glass' or backdropped overlay.
The only work-around I found was faking backdrop-filter blur by duplicating all elements to be affected then creating a "window" overlapping the background positioned to it's exact location with a regular filter: blur( n ) applied.
document.querySelector( 'style' ).innerHTML += `
.earth_orbit, .moon {
width: 15rem;
margin-left: 100%;
background-color: #222;;
}
.earth_orbit::before {
width: 5rem;
height: 5rem;
background-color: #08f;
}
.moon::before {
display: none;
}
.moon {
width: 2.5rem;
height: 2.5rem;
background-color: #ddd;
}
.sun_orbit, .earth_orbit {
background-color: transparent;
}
footer {
right: 5%;
width: 20rem;
height: 20rem;
background-color: transparent;
}
.rotate {
animation-name: rotate; animation-duration: 4s;
animation-timing-function: linear; animation-iteration-count: infinite;
}
`;
*, * ::before, * ::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body, main {
overflow: hidden;
height: 100%;
background-color: #111;
color: #eee;
}
html {
font-family: Arial;
font-size: 1.5vmin;
}
main, div, footer {
display: flex;
justify-content: center;
align-items: center;
}
div, div::before, footer {
position: absolute;
z-index: auto;
width: 10rem;
height: 10rem;
background-color: #f90;
border-radius: 5rem;
content: '';
}
div {
width: 40rem; height: 1rem;
background-color: #444;
}
<style>
footer .sun_orbit { top: 9.5rem; left: -13.25vmax; }
section { width: 70%; height: 70%; }
p {
position: relative; z-index: 10; font-size: 2rem; left: 30vh;
}
footer {
overflow: hidden; background-color: #111;
z-index: 10; filter: blur( 1rem ); left: 54.5vmax;
}
#keyframes rotate {
0% { transform: rotate( 0deg ); }
100% { transform: rotate( 360deg ); }
}
.offset { animation-duration: 1s; }
</style>
<main>
<div class='sun_orbit rotate'>
<div class='earth_orbit rotate offset'>
<div class='moon'></div>
</div>
</div>
<footer>
<section>
<div class='sun_orbit rotate'>
<div class='earth_orbit rotate offset'>
<div class='moon'></div>
</div>
</div>
</section>
</footer>
<p>backdrop overlay<br>with faded edges</p>
</main>
Added benefit is this whole effect now works in Firefox when at first it didn't. Also: This could be made responsive if so desired.
A note: The original post were deleted with its user, and as I found it could be useful, I reposted it.
The rectangle should be rotated -90deg and be centered vertical in the left side of the screen. As you can see in the picture below.
If possible, only HTML and CSS should be used.
The problem is, to first rotate the element, which makes it more difficult to center it.
Stack snippet
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
font-size: 16px;
font-family: Arial, sans-serif;
}
* {
box-sizing: border-box;
}
body>div {
position: fixed;
top: 50%;
left: 0;
background-color: #FF0000;
color: white;
font-weight: bold;
padding: 10px;
-webkit-transform: rotate(-90.0deg);
-moz-transform: rotate(-90.0deg);
-ms-transform: rotate(-90.0deg);
-o-transform: rotate(-90.0deg);
transform: rotate(-90.0deg);
}
<div>Lorem Ipsum</div>
To better control the rotation, and more easily both left align and center it vertically, use both the transform-origin and transform.
First make its left/top corner as the center of the rotation by adding transform-origin: left top; to the div.
Second, by combine rotate and translate, move it half of its own width to the left (translateX(-50%)), and then rotate it 90 degrees counterclockwise rotate(-90.0deg).
Note 1; When using more than one <transform-function> value, they execute from right to left, which in below sample mean it starts with translateX.
Note 2; I temporary removed the prefixed properties, so you need to add them back.
Stack snippet
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
font-size: 16px;
font-family: Arial, sans-serif;
background-color: #ccc;
}
* {
box-sizing: border-box;
}
body>div {
position: fixed;
top: 50%;
left: 0;
background-color: #FF0000;
color: white;
font-weight: bold;
padding: 10px;
transform-origin: left top;
transform: rotate(-90.0deg) translateX(-50%);
}
<div>Lorem Ipsum</div>
Update after a comment.
Here is 4 fiddles, showing 4 steps, that hopefully make it more clear how this works:
Step 1 - Step 2 - Step 3 - Step 4
Here is an animation, showing how it moves, and hopefully make it more clear how this works:
html, body {
margin: 0;
font-size: 16px;
font-family: Arial, sans-serif;
}
.faked-body div {
position: absolute;
top: 50%;
left: 0;
background-color: #FF0000;
color: white;
font-weight: bold;
padding: 10px;
transform-origin: left top; /* the rotation center is moved to black circle */
transform: rotate(0)
translateX(0);
animation: the-div 3s 1s forwards;
}
#keyframes the-div {
0% { transform: rotate(0)
translateX(0);
}
50% { transform: rotate(0)
translateX(-50%); /* move to left */
}
100% { transform: rotate(-90deg) /* rotate 90 degree */
translateX(-50%);
}
}
/* styling/info for this demo */
.faked-body div::before {
content: '';
position: absolute;
top: -10px;
left: 0;
transform: translateX(-50%);
width: 20px;
height: 20px;
border-radius: 50%;
background-color: black;
animation: the-spot 1.5s 1s forwards;
}
.faked-body {
position: relative;
margin: 10px 60px;
width: 440px;
height: 200px;
background-color: #ccc;
font-size: 14px;
}
.faked-body::before {
content: 'The gray area represents the body so we can see how the "Lorem Ipsum" element moves';
color: #666;
}
.faked-body::after {
content: 'The black spot show where the rotation center is';
color: #222;
position: absolute;
bottom: 0; left: 0;
}
#keyframes the-spot {
0% { left: 0;
}
100% { left: 50%;
}
}
<div class="faked-body">
<div>Lorem Ipsum</div>
</div>
We can use the 'text-orientation' property instead of 'rotate'.
I tried the below code and it worked for me.
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
font-size: 16px;
font-family: Arial, sans-serif;
display: flex;
align-items: center;
align-content: center;
}
body > div {
background-color: #ff0000;
color: white;
font-weight: bold;
padding: 10px;
width: auto;
height: auto;
writing-mode: vertical-rl;
text-orientation: upright;
}
Create another parent div to 'Lorem Ipsum' and apply "display: flex;
align-items: center;
align-content: center;" properties to the parent div to avoid giving flex to 'body' tag.
Hope it helps.
Understood. Please try the below css, it may solve your issue.
body, html {
height: 100%;
display: grid;
font-size: 16px;
font-family: Arial, sans-serif;
}
div {
margin: auto auto auto 10;
background-color: #FF0000;
-webkit-transform: rotate(-90.0deg);
-moz-transform: rotate(-90.0deg);
-ms-transform: rotate(-90.0deg);
-o-transform: rotate(-90.0deg);
transform: rotate(-90.0deg);
padding: 10px;
}
FYI: I tested this on chrome and safari and working.
This might be a dumb question, but I have a background that has high contrasting colors and I want my <ul>'s <li>s to change color depending on what the background color is for each individual <li>. I really don't want to bloat my CSS by adding the color property to each one. Please can someone tell me if there is any way to do this.
I'm working an a CodePen project. It's a personal portfolio page. Just for reference I'll share it with you but it's not finished yet. I want the list under My Skills to be "color responsive" (if that even exists) so that the items at the bottom are easier to read.
Here is the pen.
Much appreciated!
Just using CSS, you can use mix-blend-mode to ul.
Chcek with css to ul element as mix-blend-mode: difference;
The mix-blend-mode property defines how an element’s content should blend with its background. This means that any images or text, borders or headings will be influenced by this property.
See here. Ref: Pen
var modeList = [
"normal",
"multiply",
"screen",
"overlay",
"darken",
"lighten",
"color-dodge",
"color-burn",
"hard-light",
"soft-light",
"difference",
"exclusion",
"hue",
"saturation",
"color",
"luminosity"
],
elem = document.querySelector(".box"),
propertyName = "mix-blend-mode",
modeElem = document.querySelector(".mode-name"),
duration = 2500;
var i = 0;
var activate = setInterval(function() {
if (i == modeList.length) i = 0;
var mode = modeList[i];
elem.style.mixBlendMode = mode;
modeElem.innerText = mode;
i++;
}, duration);
#charset "UTF-8";
* {
box-sizing: border-box;
}
body, html {
margin: 0;
height: 100%;
padding: 0;
-webkit-font-smoothing: antialiased;
}
.wrapper {
background: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/14179/washington.jpg") no-repeat center center fixed;
background-size: cover;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-family: "Nocturno Display Medium 4", Georgia;
font-style: normal;
font-weight: normal;
font-stretch: normal;
height: 100%;
width: 100%;
}
.box {
justify-content: center;
align-items: center;
display: flex;
flex-direction: column;
font-size: 8vw;
border-top: 10px solid #BF0A30;
border-bottom: 10px solid #BF0A30;
line-height: 1;
background-color: #002B65;
color: white;
background-size: cover;
mix-blend-mode: hard-light;
height: 400px;
height: 50vh;
width: 100%;
text-align: center;
text-transform: uppercase;
}
.box p {
text-rendering: optimizeLegibility;
word-spacing: 5px;
margin: 0;
}
.mode-name-wrapper {
position: absolute;
bottom: 12vh;
left: 0;
right: 0;
color: #002B65;
text-align: center;
text-transform: uppercase;
font-size: 17px;
margin: 0 auto;
padding: 0;
width: 135px;
height: 135px;
border: 5px solid white;
background-color: #ddd;
border-radius: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.mode-name-wrapper:before {
content: "★";
display: block;
line-height: 1;
font-size: 20px;
margin-top: -20px;
margin-bottom: 10px;
color: #ef0d3c;
animation: spin 2.5s ease;
animation-iteration-count: infinite;
transform-origin: center center;
}
.mode-name {
position: relative;
left: 0;
right: 0;
animation: nudge 2.5s ease;
animation-iteration-count: infinite;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#keyframes nudge {
0% {
transform: translate(0, 0);
}
80% {
transform: translate(0, 0);
}
90% {
transform: translate(-10px, 0);
}
93% {
transform: translate(12px, 0);
}
95% {
transform: translate(-8px, 0);
}
100% {
transform: translate(0, 0);
}
}
<link rel="stylesheet" href="https://fonts.typonine.com/WF-003562-001299.css" type="text/css" />
<div class="wrapper">
<div class="box">
<p>Washington D.C.</p>
</div>
<small class="mode-name-wrapper">
<span class="mode-name">hard-light</span>
</small>
</div>
I'm facing a small design problem with CSS Adjustments. I skewed the backgrounds of all the sections and elements but near the footer, I want to join the article and footer it is not adjusting according to the design can any one please help how to fix it. Here is my plunker link.
<https://plnkr.co/edit/iCgonAiCoBUfSaAF851P?p=preview>
Change CSS as the following
section {
background: #191919;
color: white;
}
section, article {
transform: skew(0deg, -10deg);
padding: 20px;
}
section>div, article >div{
transform: skew(0deg, 10deg);
}
article {
background: white;
color: black;
}
Plunker Link
As suggested in comments, add background color to your body and add some margin-top to the footer, and use the following CSS:
body, html {
height: 100%;
margin: 0;
background:#191919;
}
.hero-image {
background-color: #6c7cd0;
padding: 200px 0;
transform: skew(0deg, -10deg);
margin-top: -150px
}
.hero-text {
transform: skew(0deg, 10deg);
text-align: center;
}
.wrapper {
transform: skew(0deg, -10deg);
background: #191919;
color: white;
}
section, article {
transform: skew(0deg, 10deg);
padding: 20px;
}
.wrapper::after{
transform: skew(0deg, -10deg);
}
div > h1 {
margin-top: 50px;
}
footer {
text-align: center;
background: #6c7cd0;
color: white;
margin-top:50px;
padding: 20px;
}
Note: Your layout needs considerable work in larger viewports specific to the skewing problem.
Hope this helps.