I'm trying to accomplish the following in CSS:
So you start with 2 halves, each of them showing half a picture of someones face (these images have their face in the exact center). By some mean of interaction the sides pan out. This is what I tried first:
.container {
display: flex;
align-items: stretch;
width: 414px;
height: 736px;
}
.container__section {
display: flex;
flex-direction: column;
justify-content: center;
width: 50%;
padding: 1rem;
}
.container__section:before {
content: "";
position: absolute;
top: 0;
bottom: 0;
overflow: hidden;
}
.container__section--left {
background-color: #83b1be;
}
.container__section--left:before {
background: url('http://i68.tinypic.com/2mwzddh.jpg') no-repeat;
background-position: left 50% center;
transform: translateX(0%);
left: 0;
right: 50%;
}
.container__section--right {
background-color: #80bb94;
}
.container__section--right:before {
background: url('http://i68.tinypic.com/2s7gcav.jpg') no-repeat;
background-position: right 50% center;
transform: translateX(0%);
right: 0;
left: 50%;
}
<div class="container">
<div class="container__section container__section--left">
<p class="homepage__section-detail">
lorem ipsum
</p>
</div>
<div class="container__section container__section--right">
<p class="container__section-detail">
lorem ipsum
</p>
</div>
</div>
It also seems that the images aren't loaded/blocked within the code snippet here above. If someone knows how to use images?
I'd probably layer the images in a single div (in this case using CSS-Grid) but you could use positioning...
Then use a clip-path to clip one in half. This property is animatable too.
.image-wrap {
width: 300px;
margin: 1em auto;
border: 1px solid grey;
display: grid;
overflow: hidden;
}
.image-wrap div {
grid-row: 1/2;
grid-column: 1/2;
}
img {
display: block;
max-width: auto;
height: 100%;
}
.one {
transition: -webkit-clip-path .5s ease;
transition: clip-path .5s ease;
transition: clip-path .5s ease, -webkit-clip-path .5s ease;
-webkit-clip-path: polygon(0% 0%, 50% 0%, 50% 100%, 0% 100%);
clip-path: polygon(0% 0%, 50% 0%, 50% 100%, 0% 100%);
}
.image-wrap:hover .one {
-webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
}
<div class="image-wrap">
<div class="one"><img src="https://www.placecage.com/300/200" alt=""></div>
<div class="two">
<img src="http://www.fillmurray.com/300/200" alt="">
</div>
</div>
Related
This question already has answers here:
How to center an element horizontally and vertically
(27 answers)
Closed 6 months ago.
I'm trying to make a responsive hexagon image frame, but I'm stuck on aligning the inner hexagon. Does anyone know how to center the inner hexagon? Here's my code:
.inner {
background-color: red;
width: 95%;
height: 0%;
padding-bottom: 98%;
margin-top: auto;
margin-bottom: auto;
}
.outer {
background-color: mediumspringgreen;
width: 12%;
height: 0%;
padding-bottom: 13%;
}
.hexagon {
display: flex;
justify-content: center;
align-items: center;
position: relative;
-webkit-clip-path: polygon( 50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
}
<div class="hexagon outer">
<div class="hexagon inner">
<img src="https://placekitten.com/400/400" class="absolute inset-0 h-full w-full" alt="" />
</div>
</div>
My result:
Expected result:
It seems as you use the padding only for your inner div, the outer div only gets that height. I would have a container that you put the width on, then you can add padding to your outer hexagon and absolutely position your inner hexagon:
.container {
width: 12%;
}
.inner {
background-color: red;
width: calc(100% - 10px);
/* can change this to be a percentage if you want a variable width border. with calc, the border will always be half of what you subtract */
height: calc(100% - 10px);
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.outer {
background-color: blue;
width: 100%;
padding-top: 100%;
position: relative;
}
.hexagon {
clip-path: polygon(0% 25%, 0% 75%, 50% 100%, 100% 75%, 100% 25%, 50% 0%);
}
.img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="container">
<div class="hexagon outer">
<div class="hexagon inner">
<img src="https://placekitten.com/400/400" class="img">
</div>
</div>
</div>
From comments solution using aspect ratio instead of padding and inset instead of calc on the width of inner:
.container {
width: 12%;
}
.inner {
background-color: red;
/* insets the element 5px from the edges of
the element against which its positioned: */
inset: 5px;
position: absolute;
}
.outer {
/* allows one dimension to be set (here 'inline-size'/'width'),
and the other dimension ('block-size'/'height') will be
an equal width: */
aspect-ratio: 1;
background-color: blue;
/* logical property, equivalent to 'width' in the English -
left-to-right - language: */
inline-size: 100%;
position: relative;
}
.hexagon {
clip-path: polygon(0% 25%, 0% 75%, 50% 100%, 100% 75%, 100% 25%, 50% 0%);
}
.img {
width: 100%;
object-fit: cover;
}
<div class="container">
<div class="hexagon outer">
<div class="hexagon inner">
<img src="https://placekitten.com/400/400" class="img">
</div>
</div>
</div>
Try it:
.inner {
background-color: red;
width: 95%;
height: 0%;
padding-bottom: 98%;
margin-top: auto;
margin-bottom: auto;
}
.outer {
background-color: mediumspringgreen;
width: 12%;
height: 0%;
padding-bottom: 13%;
}
.hexagon {
display: flex;
justify-content: center;
align-items: center;
-webkit-clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
position: absolute;
top: 50%;
left: 50%;
-moz-transform: translateX(-50%) translateY(-50%);
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
}
<div class="hexagon outer">
<div class="hexagon inner">
<img src="https://placekitten.com/400/400" class="absolute inset-0 h-full w-full" alt="" />
</div>
</div>
I have a banner image loading on my site with this code:
#keyframes animatedBanner {
from {
background-position-y: bottom;
}
to {
background-position-y: top;
}
}
.page-hero {
background-image: url(https://via.placeholder.com/428x100);
background-repeat: no-repeat;
padding-top: 214px;
padding-bottom: 214px;
text-align: center;
animation: 2s ease-out 0s 1 animatedBanner;
background-size: auto;
}
<div class="page-hero">
<div class="inside-page-hero grid-container grid-parent">
<h2>this is an image</h2>
</div>
</div>
This does what I hoped it would (slide the image up when the page loads). But the problem is that I was hoping to have the image span the entire width of the screen regardless of width. I tried using cover, but then the image doesn't scroll at all.
Is there a way to make this design responsive on the image?
background are a bit tricky when it comes to animate the position. You need some specific sizes. I have a detailed answer (Using percentage values with background-position on a linear-gradient) explaining the logic behind the values I am using:
#keyframes animatedBanner {
from {
background-position: 50% 200%;
}
to {
background-position: 50% 50%;
}
}
.page-hero {
background-image: url(https://picsum.photos/id/1068/800/400);
background-repeat: no-repeat;
padding:100px 0;
text-align: center;
animation: 2s ease-out animatedBanner both .5s;
background-size: auto 200%;
}
<div class="page-hero">
<div class="inside-page-hero grid-container grid-parent">
<h2>this is an image</h2>
</div>
</div>
To get the opposite direction
#keyframes animatedBanner {
from {
background-position: 50% -100%;
}
to {
background-position: 50% 50%;
}
}
.page-hero {
background-image: url(https://picsum.photos/id/1068/800/400);
background-repeat: no-repeat;
padding:100px 0;
text-align: center;
animation: 2s ease-out animatedBanner both .5s;
background-size: auto 200%;
}
<div class="page-hero">
<div class="inside-page-hero grid-container grid-parent">
<h2>this is an image</h2>
</div>
</div>
And if you want to avoid the complexity of background-position and background-size, use pseudo-element
#keyframes animatedBanner {
from {
transform: translateY(100%); /* or -100% */
}
}
.page-hero {
padding: 100px 0;
text-align: center;
position: relative;
z-index: 0;
overflow: hidden;
}
.page-hero:before {
content: "";
position: absolute;
z-index: -1;
inset: 0;
background: url(https://picsum.photos/id/1068/800/400) center/cover;
animation: 2s ease-out animatedBanner both .5s;
}
<div class="page-hero">
<div class="inside-page-hero grid-container grid-parent">
<h2>this is an image</h2>
</div>
</div>
How would I be able to improve this animated static noise effect using a css gradient?
CSS only, no javascript, no svg, no image, using only a gradient, and adjusting that.
A tv no signal noise effect is what I am looking for using a css gradient.
Does anyone know how this effect can be improved, made better?
Is there a better way it can be written?
I am looking for something that is more accurate to a tv noise effect.
I think the way this effect is written can be improved.
Are there any tweaks or adjustments that can be made to it to so that it better depicts a tv noise effect?
The gradient can be anything, as long as it is a gradient, it doesn't matter what kind.
This one uses radial gradient:
https://jsfiddle.net/xhdkza5w/
html,
body {
width: 100%;
height: 100%;
display: flex;
}
.tv-static {
width: 500px;
height: 300px;
margin: auto;
background-image: repeating-radial-gradient(circle at 17% 32%, white, black 0.00085px);
animation: back 5s linear infinite;
}
#keyframes back {
from {
background-size: 100% 100%;
}
to {
background-size: 200% 200%;
}
}
<div class="tv-static"></div>
This one uses a conic-gradient: https://jsfiddle.net/bkx50apm/
html,
body {
width: 100%;
height: 100%;
display: flex;
}
.tv-static {
width: 500px;
height: 300px;
margin: auto;
background-image: repeating-conic-gradient(white, black 0.00085%);
animation: back 25s linear infinite;
}
#keyframes back {
from {
background-size: 100% 100%;
}
to {
background-size: 200% 200%;
}
}
<div class="tv-static"></div>
Do you mean this effect?
html,
body {
width: 100%;
height: 100%;
display: flex;
}
.animation {
width: 240px;
height: 240px;
margin: auto;
background-image: repeating-radial-gradient(circle at 17% 32%, white, black 0.00085px);
animation: animation 5s linear infinite;
}
#keyframes animation {
from {
background-position: 0px 0px;
}
to {
background-position: 240px 240px;
}
}
<div class="animation"></div>
Or this effect?
html,
body {
width: 100%;
height: 100%;
display: flex;
}
.animation {
width: 240px;
height: 240px;
margin: auto;
background-image: repeating-radial-gradient(circle at 17% 32%, white, black 0.00085px);
background-position: center;
animation: back 5s linear infinite;
}
#keyframes back {
from {
background-size: 100% 100%;
}
to {
background-size: 200% 200%;
}
}
<div class="animation"></div>
Edit: Added background-position: center.
By overlaying 2 of those effect on top of each other and each div has a different animation, you can create interference between the two that removes the artifacts of only having 1 static noise made from a single div.
This might be improved as I'm not well versed in css but the proof of concept works
html,
body {
width: 100%;
height: 100%;
display: flex;
}
.container_row {
display: flex;
}
.layer1 {
width: 100%;
background-color: rgba(255, 255, 255, 0.5);
}
.layer2 {
width: 100%;
margin-left: -100%;
background-color: rgba(255, 255, 255, 0.5);
}
.tv-static {
width: 500px;
height: 300px;
margin: auto;
background-image: repeating-radial-gradient(circle at 17% 32%, white, black 0.00085px);
}
.animation1 {
animation: back1 1s linear infinite;
}
.animation2 {
animation: back2 0.1s linear infinite;
}
#keyframes back1 {
from {
background-size: 100% 100%;
}
to {
background-size: 99% 100%;
}
}
#keyframes back2 {
from {
background-size: 48.56% 50%;
}
to {
background-size: 43.9% 50.1%;
}
}
<div class="layer1">
<div class="tv-static animation1"></div>
</div>
<div class="layer2">
<div class="tv-static animation2"></div>
</div>
With smooth timing function, animations don't give that effect we need to use step timing function to give those sudden change effect.
Solution 1: I've changed animation. And tweaked your gradient a little bit. I think using gradient is not a reliable solution because browsers do calculations differently and fractions, rounding change output. You are using radial gradient it looks things are going outwards from center of the placement. You'll have to test his on every platform and browser to see if it looks same.
Solution 2: Used SVG instead of gradient. The feTurbulence filter gives the noise effect. You can use svg as background-image.
Solution 3: Used image instead of gradient with same animation. Advantage of using image is that it'll look same across all browsers and screens.
Solution 3: Simply used noise gif image. No animation is required. :)
View following in 'full page' mode:
body {
text-align: center;
}
.tv {
width: 400px;
height: 200px;
border: 6px solid black;
margin: 0 auto;
overflow: hidden;
position: relative;
border-radius: 50% / 10%;
}
.tv-static {
position: absolute;
top: -200px;
left: -200px;
margin: auto;
height: 800px;
width: 800px;
background-image: repeating-radial-gradient(circle at 17% 132%, white 0.0005px, black 0.00085px);
animation: anim 1s steps(2, jump-both) infinite both;
transform: translate3d(0, 0, 0);
}
/******************************/
.tv0 {
width: 400px;
height: 200px;
border: 6px solid black;
margin: 0 auto;
overflow: hidden;
position: relative;
border-radius: 50% / 10%;
isolation: isolate;
}
.tv-static0 {
position: absolute;
top: 0px;
left: 0px;
margin: auto;
height: 300%;
width: 300%;
animation: anim 1s steps(2, end) infinite both;
transform: translate3d(0, 0, 0);
filter: contrast(300%) brightness(50%);
}
.tv-static0 svg {
height: 200%;
width: 100%;
transform: scale(2.5);
}
/******************************/
.tv1 {
width: 400px;
height: 200px;
border: 6px solid black;
margin: 0 auto;
overflow: hidden;
position: relative;
border-radius: 50% / 10%;
}
.tv-static1 {
position: absolute;
top: -500px;
right: -500px;
bottom: -500px;
left: -500px;
margin: auto;
background-image: url(https://i.stack.imgur.com/uzEM4.png);
animation: anim 1s steps(2, end) infinite both;
transform: translate3d(0, 0, 0);
}
/******************************/
.tv2 {
width: 400px;
height: 200px;
border: 6px solid black;
margin: 0 auto;
overflow: hidden;
position: relative;
border-radius: 50% / 10%;
}
.tv-static2 {
position: absolute;
top: -500px;
right: -500px;
bottom: -500px;
left: -500px;
margin: auto;
background-image: url(https://i.stack.imgur.com/9Be02.gif);
transform: translate3d(0, 0, 0);
}
#keyframes anim {
0% {
transform: translateX(0px, 0px);
}
10% {
transform: translate(-100px, 100px);
}
20% {
transform: translate(150px, -100px);
}
30% {
transform: translate(-100px, 100px);
}
40% {
transform: translate(100px, -150px);
}
50% {
transform: translate(-100px, 200px);
}
60% {
transform: translate(-200px, -100px);
}
70% {
transform: translateY(50px, 100px);
}
80% {
transform: translate(100px, -150px);
}
90% {
transform: translate(0px, 200px);
}
100% {
transform: translate(-100px, 100px);
}
}
Your original code. modified. May not work on every browser.
<div class="tv">
<div class="tv-static"></div>
</div>
<br> Using SVG `feTurbulence` filter
<div class="tv0">
<div class="tv-static0">
<svg viewBox="0 0 200% 200%" xmlns='http://www.w3.org/2000/svg'>
<filter id='noiseFilter'>
<feTurbulence type='turbulence' result='noise' baseFrequency='0.7' numOctaves='6' seed='2'
stitchTiles='noStitch' />
</filter>
<rect width='100%' height='100%' filter='url(#noiseFilter)' />
</svg>
<div class="overlay"></div>
</div>
</div>
<br>
<br> Animating image. Color TV
<div class="tv1">
<div class="tv-static1"></div>
</div>
<br> Using gif. No animation.
<div class="tv2">
<div class="tv-static2"></div>
</div>
I'm trying to create an animated background fill effect (still learning animation) but the fill color jumps quickly before it reaches the end of the div. What's the issue and how to fix it? Thanks in advance.
.outer {
margin: 50px;
}
.button {
border: 1px solid black;
border-radius: 3px;
width: 100px;
height: 30px;
display: block;
background: linear-gradient(to right, black 50%, transparent 50%);
background-size: 200% 100%;
background-position: right bottom;
animation: makeItfadeIn 3s 1s;
animation-fill-mode:forwards;
}
#-webkit-keyframes makeItfadeIn {
100% {
background-position: left bottom;
background: linear-gradient(to right, black 100%, black 0%);
}
}
#keyframes makeItfadeIn {
100% {
background-position: left bottom;
background: linear-gradient(to right, black 100%, black 0%);
}
}
<div class="outer">
<div class="button">
</div>
</div>
Background inside the animation is the culprit. You simply need to animate the position from right to left:
.outer {
margin: 50px;
}
.button {
border: 1px solid black;
border-radius: 3px;
width: 100px;
height: 30px;
display: block;
background: linear-gradient(to right, black 50%, transparent 0);
background-size: 200% 100%;
background-position: right;
animation: makeItfadeIn 3s 1s forwards;
}
#keyframes makeItfadeIn {
100% {
background-position: left;
}
}
<div class="outer">
<div class="button">
</div>
</div>
Related to get more details: Using percentage values with background-position on a linear-gradient
How do I create the border effect of each of the tiles in the Fifteen puzzle below (the sharp edges on each corner of the tiles)?
You can also use :pseudo elements and border
codepen - http://codepen.io/victorfdes/pen/GJYGKV
*,
*:before,
*:after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.a {
width: 100px;
display: inline-block;
height: 100px;
position: relative;
overflow: hidden;
}
.a:nth-child(even) .b {
background: #DCD8BB;
}
.b {
position: absolute;
width: 116px;
height: 116px;
border: 4px solid #8B8B83;
transform: rotate(45deg) translate(-50%, -50%);
transform-origin: left top;
top: 50%;
left: 50%;
background: #490506;
z-index: -1;
}
.b:before,
.b:after {
content: '';
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%) rotate(-45deg);
background: inherit;
border-color: inherit;
}
.b:before {
border-width: 0 4px;
border-style: solid;
width: 100px;
height: 60px;
}
.b:after {
border-width: 4px 0;
border-style: solid;
height: 100px;
width: 60px;
}
.b span {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(-45deg);
z-index: 1;
color: grey;
font-size: 30px;
}
<div class="a">
<div class="b">
<span>1</span>
</div>
</div>
<div class="a">
<div class="b">
<span>2</span>
</div>
</div>
<div class="a">
<div class="b">
<span>3</span>
</div>
</div>
<div class="a">
<div class="b">
<span>4</span>
</div>
</div>
SVG clip-path is what you are looking for, but it is not widely supported.
It is talked about here: Slanted Corner on CSS box
The one you want is called a Bevel Box:
-webkit-clip-path: polygon(20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%, 0% 20%);
clip-path: polygon(20% 0%, 80% 0%, 100% 20%, 100% 80%, 80% 100%, 20% 100%, 0% 80%, 0% 20%);