Different way to vertically center svg on border

Is there a different way this can be done?
https://jsfiddle.net/r5ygeL3x/

.home {
  position: absolute;
  top: calc(50% - 12px);
  /*12px is half the height of the svg*/
  right: -20px;
  width: 20px;
  height: 20px;
  cursor: pointer;
  border: none;
  background: blue;
  fill: red;
  padding: 0;
}

The way you have done it is probably the best way for that situation.

Instead of using calc you could have said top:0;bottom:0;margin:auto; instead and not need to work out what half the height is. That means if you changed the button height at a later date you wouldn’t need to re-position it.

In the end its all swings and roundabouts.:slight_smile:

1 Like

What if I wanted to place it centered horizontally, how whould that be written?
https://jsfiddle.net/b4gnk506/

.home {
  position: absolute;
  top: -384px;
  bottom: 0;
  margin: auto;
  right: 50%;
}

Currently, it goes from this:

Then when the video gets smaller, the svg falls off the border.

I would do it like this.

.home {
    position: absolute;
    top: -20px;
    bottom: auto;
    margin: auto;
    right: 0;
    left: 0;
    width: 20px;
    height: 20px;
    cursor: pointer;
    border: none;
    background: transparent;
    fill: red;
    padding: 0;
}
1 Like

As I was adjusting the code, trying different things, I was able to see the purple background appear.

https://jsitor.com/Zb7cVWjvI

https://jsfiddle.net/o1bshq40/

I thought that was resolved.

It was resolved for the video but now you are pushing something outside that container and thus it no ,longer influences the flow of the element holding the background.

I believe I said the real answer was to have the background on the body element and then it will always encompass its content (assuming the html element doesn’t have a background also).

If the background is on the body element,

Then I wouldn’t be able to have a color background here:

If I understand correctly.

Yes you could have any background you want as you can swap a class on the body element instead of the container.

I’m sure we did a demo of this but maybe we just talked about it. I vaguely remember you wanted the purple to fade out rather than being replaced by a new background fading in.

It may also be that the linear gradient background behaves differently on the body so i’d need to double check if it was viable or if the same issue arises.

As I understand it, this was the code where everything was fixed.

Absolute was removed, replacing it with Flex.

And this is the code I have been using ever since that change was made.

https://jsitor.com/Zb7cVWjvI

https://jsfiddle.net/o1bshq40/

I just never saw the purple background showing until I placed an svg below the video.

Which was the first time I tried that.

And now you have an absolute element again so the flow is not controlled.

The ratio keeper is in the flow and keeps the background around it. Therefore the video which is fully contained within the ratio keeper does not cause any problems.

However now you push the button outside that area using absolute positioning and the background from the container no longer follows.

If the button was below the ratio keeper and not absolutely positioned then the background would surround it.

I’m not on my computer at the moment so can’t test but I’ll have a look in the morning.

1 Like

I tested a color instead of a gradient and it occurs there also.
https://jsitor.com/jScVRTnndR

Yes I guessed as much.

What happened to the version where the background was fixed positioned.on a pseudo element?

Here’s an example of changing the background on a pseudo element of the body.

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

body {
  background: #353198;
  animation: fade 2s ease 0s forwards;
}

.bodytoggle {
  animation: fade2 2s ease forwards;
}

@keyframes fade {
  0% {
    opacity: 0;
  }

  100% {
    opacity: 1;
  }
}

@keyframes fade2 {
  0% {
    opacity: 0;
  }

  100% {
    opacity: 1;
  }
}

.outer {
  display: flex;
  min-height: 100%;
  box-sizing: border-box;
  justify-content: center;
}

.container {
  display: flex;
  justify-content: center;
  position: relative;
  z-index: 2;
}

.container.active {
  flex: 1 0 0;
}
body.bg1:after {
  content: "";
  position: fixed;
  z-index: 1;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  animation: fadebody 5s ease 0s forwards;
  background-size: 165px 165px;
  background-image: linear-gradient(teal 5px, #0000 5px),
    linear-gradient(90deg, teal 5px, #0000 5px),
    linear-gradient(black 10px, #0000 10px 160px, black 160px),
    linear-gradient(90deg, black 10px, #0000 10px 160px, black 160px),
    linear-gradient(orange 15px, #0000 15px 155px, orange 155px),
    linear-gradient(90deg, orange 15px, #0000 15px 155px, orange 155px),
    linear-gradient(black 20px, #0000 20px 150px, black 150px),
    linear-gradient(90deg, black 20px, #0000 20px 150px, black 150px),
    linear-gradient(teal 25px, #0000 25px 145px, teal 145px),
    linear-gradient(90deg, teal 25px, #0000 25px 145px, teal 145px),
    linear-gradient(black 30px, #0000 30px 140px, black 140px),
    linear-gradient(90deg, black 30px, #0000 30px 140px, black 140px),
    linear-gradient(orange 35px, #0000 35px 135px, orange 135px),
    linear-gradient(90deg, orange 35px, #0000 35px 135px, orange 135px),
    linear-gradient(black 40px, #0000 40px 130px, black 130px),
    linear-gradient(90deg, black 40px, #0000 40px 130px, black 130px),
    linear-gradient(teal 45px, #0000 45px 125px, teal 125px),
    linear-gradient(90deg, teal 45px, #0000 45px 125px, teal 125px),
    linear-gradient(black 50px, #0000 50px 120px, black 120px),
    linear-gradient(90deg, black 50px, #0000 50px 120px, black 120px),
    linear-gradient(orange 55px, #0000 55px 115px, orange 115px),
    linear-gradient(90deg, orange 55px, #0000 55px 115px, orange 115px),
    linear-gradient(black 60px, #0000 60px 110px, black 110px),
    linear-gradient(90deg, black 60px, #0000 60px 110px, black 110px),
    linear-gradient(teal 65px, #0000 65px 105px, teal 105px),
    linear-gradient(90deg, teal 65px, #0000 65px 105px, teal 105px),
    linear-gradient(black 70px, #0000 70px 100px, black 100px),
    linear-gradient(90deg, black 70px, #0000 70px 100px, black 100px),
    linear-gradient(orange 75px, #0000 75px 95px, orange 95px),
    linear-gradient(90deg, orange 75px, #0000 75px 95px, orange 95px),
    linear-gradient(black 80px, #0000 80px 90px, black 90px),
    linear-gradient(90deg, black 80px, #0000 80px 90px, black 90px),
    linear-gradient(teal, teal);
}

.thePlay:hover {
  box-shadow: 0 0 0 5px rgba(43, 179, 20, 0.5);
}

.thePlay:focus {
  outline: 0;
  box-shadow: 0 0 0 5px rgba(0, 255, 255, 0.5);
}

.inner-container {
  display: none;
}

/* when container is active hide the svg and show the inner container*/
.container.active .thePlay {
  display: none;
}

.container.active .inner-container {
  display: flex;
}

.container.active .inner-container.curtain {
  display: block;
}

@keyframes fadebody {
  0% {
    opacity: 0;
  }

  100% {
    opacity: 1;
  }
}

.playa,
.playb,
.playc {
  margin: auto 20px;
  width: 90px;
  height: 90px;
  border-radius: 50%;
  cursor: pointer;
  flex-shrink: 0;
  border: none;
  background: transparent;
  padding: 0;
}

.playa {
  fill: red;
  filter: drop-shadow(3px 3px 3px rgba(0, 0, 0, 0.7));
}

.playb {
  fill: blue;
  filter: drop-shadow(3px 3px 3px rgba(0, 0, 0, 0.7));
}

.playc {
  fill: orange;
  filter: drop-shadow(3px 3px 3px rgba(0, 0, 0, 0.7));
}

button.thePlay {
  pointer-events: none;
}

.home {
  position: absolute;
  top: auto;
  bottom: -20px;
  margin: auto;
  right: 0;
  left: 0;
  width: 20px;
  height: 20px;
  cursor: pointer;
  border: none;
  background: transparent;
  fill: red;
  padding: 0;
}

.homesvg {
  fill: none;
  fill-rule: evenodd;
  stroke: #ff0000;
  stroke-width: 17.80202103;
  stroke-linecap: butt;
  stroke-linejoin: miter;
  stroke-miterlimit: 4;
  stroke-dasharray: none;
  stroke-opacity: 1;
  border: 4.625px solid #4e4e4e;
  border-radius: 100%;
}

.curtain {
  position: relative;
  max-width: 642px;
  margin: auto;
  flex: 1 0 0%;
  background: #0a0a0a;
  border: 20px solid #000;
  border-radius: 3.2px;
  border-color: #000 #101010 #000 #101010;
}

.panel-left,
.panel-right {
  position: absolute;
  height: 100%;
  width: calc(50% + 1px);
  /* rounding error fix */
  top: 0%;
  transition: all ease 10s;

  /*background-image: url("https://picsum.photos/600");
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center;*/
  overflow: hidden;
}

.panel-left {
  left: 0;
  /*background-color: rgb(91, 96, 106);*/
}

.panel-right {
  right: 0;
  /*background-color: rgb(229, 211, 211);*/
}

.panel-left::before,
.panel-right::before {
  content: "";
  position: absolute;
  height: 100%;
  width: 200%;
  top: 0;
  left: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'> <filter id='filter'> <feTurbulence baseFrequency='0.01 0.0001' numOctaves='5'/> <feColorMatrix values='1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1'/></filter> <rect width='100%' height='100%' filter='url(%23filter)'/> </svg>");
  background-size: auto;
  background-repeat: no-repeat;
  background-position: 0 0;
}

.curtain2 .panel-left::before,
.curtain2 .panel-right::before {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'> <filter id='filter'> <feTurbulence baseFrequency='0.01 0.0001' numOctaves='5'/> <feColorMatrix values='1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1'/></filter> <rect width='100%' height='100%' filter='url(%23filter)'/> </svg>");
}

.curtain3 .panel-left::before,
.curtain3 .panel-right::before {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'> <filter id='filter'> <feTurbulence baseFrequency='0.01 0.0001' numOctaves='5'/> <feColorMatrix values='1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1'/></filter> <rect width='100%' height='100%' filter='url(%23filter)'/> </svg>");
}

.panel-right::before {
  left: -100%;
}

.container.active .curtain .panel-left {
  animation: curtain1 8s forwards;
  animation-delay: 1s;
}

@keyframes curtain1 {
  to {
    transform: translateX(-100%);
  }
}

.container.active .curtain .panel-right {
  animation: curtain2 8s forwards;
  animation-delay: 1s;
}

.container.active .curtain .panel-right {
  animation: curtain3 8s forwards;
  animation-delay: 1s;
}

@keyframes curtain2 {
  to {
    transform: translateX(100%);
  }
}

@keyframes curtain3 {
  to {
    transform: translateX(100%);
  }
}

.ratio-keeper {
  position: relative;
  height: 0;
  padding-top: 56.25%;

  margin: auto;
  overflow: hidden;
  border: 1px solid #333;
}

.video-frame {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.hide {
  display: none;
}

And.

const manageCover = (function makeManageCover() {
  const config = {};

  function show(el) {
    el.classList.remove("hide");
  }

  function hide(el) {
    el.classList.add("hide");
  }

  function hideAll(elements) {
    elements.forEach(hide);
  }

  function showCovers(playButton) {
    const cover = playButton.parentElement;
    const theBody = document.querySelector("body");
    cover.classList.add("active");
    theBody.classList.add("bg1");
    show(cover);
  }

  function coverClickHandler(evt) {
    hideAll(config.containers);
    const cover = evt.currentTarget;
    showCovers(cover);
  }

  function homeClickHandler(evt) {
    const home = evt.currentTarget;
    showHome(home);
  }

  function showHome() {
    const theActive = document.querySelector(".with-curtain.active");
    const theHides = document.querySelectorAll(".hide");
    const theBody = document.querySelector("body");
    theActive.classList.remove("active");
    theBody.classList.remove("bg1");
    theHides.forEach(function (removeHide) {
      removeHide.classList.remove("hide");
    });

    // void theBody.offsetWidth; //restart animation
    theBody.classList.toggle("bodytoggle");
  }

  function addClickToButtons(playButtons) {
    playButtons.forEach(function addEventHandler(playButton) {
      playButton.addEventListener("click", coverClickHandler);
    });
  }

  function addClickToHome(goHome) {
    goHome.forEach(function addEventHandler(goHome) {
      goHome.addEventListener("click", homeClickHandler);
    });
  }

  function addCoverHandler(coverSelector, handler) {
    const cover = document.querySelector(coverSelector);
    cover.addEventListener("click", handler);
  }

  function init(selectors) {
    config.containers = document.querySelectorAll(selectors.container);
    const playButtons = document.querySelectorAll(selectors.playButton);
    addClickToButtons(playButtons);
    const goHome = document.querySelectorAll(".home");
    addClickToHome(goHome);
  }

  return {
    addCoverHandler,
    init
  };
})();

function combinePlayerOptions(options1 = {}, options2 = {}) {
  const combined = Object.assign({}, options1, options2);
  Object.keys(options1).forEach(function checkObjects(prop) {
    if (typeof options1[prop] === "object") {
      combined[prop] = Object.assign({}, options1[prop], options2[prop]);
    }
  });
  return combined;
}

const videoPlayer = (function makeVideoPlayer() {
  const players = [];

  const tag = document.createElement("script");
  tag.src = "https://www.youtube.com/player_api";
  const firstScriptTag = document.getElementsByTagName("script")[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

  function onPlayerReady(event) {
    const player = event.target;
    player.setVolume(100);
  }

  function addPlayer(video, settings) {
    const defaults = {
      height: 360,
      host: "https://www.youtube-nocookie.com",
      videoId: video.dataset.id,
      width: 640
    };
    defaults.events = {
      onReady: onPlayerReady
    };

    const playerOptions = combinePlayerOptions(defaults, settings);
    const player = new YT.Player(video, playerOptions);
    players.push(player);
    return player;
  }

  return {
    addPlayer
  };
})();

const managePlayer = (function makeManagePlayer() {
  const defaults = {
    playerVars: {
      autoplay: 0,
      controls: 1,
      disablekb: 1,
      enablejsapi: 1,
      fs: 0,
      iv_load_policy: 3
    }
  };

  function show(el) {
    el.classList.remove("hide");
  }

  function createPlayer(videoWrapper, settings = {}) {
    const video = videoWrapper.querySelector(".video");
    const playerOptions = combinePlayerOptions(defaults, settings);
    return videoPlayer.addPlayer(video, playerOptions);
  }

  function createCoverClickHandler(playerSettings) {
    return function coverClickHandler(evt) {
      const cover = evt.currentTarget;
      const wrapper = cover.nextElementSibling;
      show(wrapper);
      const player = createPlayer(wrapper, playerSettings);
      wrapper.player = player;
    };
  }

  function addPlayer(coverSelector, playerSettings) {
    const clickHandler = createCoverClickHandler(playerSettings);
    manageCover.addCoverHandler(coverSelector, clickHandler);
  }

  return {
    add: addPlayer
  };
})();

function onYouTubeIframeAPIReady() {
  managePlayer.add(".playa", {});

  managePlayer.add(".playb", {
    playerVars: {
      playlist: "0dgNc5S8cLI,mnfmQe8Mv1g,-Xgi_way56U,CHahce95B1g"
    }
  });
  managePlayer.add(".playc", {});

  manageCover.init({
    container: ".container",
    playButton: ".thePlay"
  });
}

That’s just an example to see how the absolute X behaves and it looks like it solves the problem.

Of course it probably messes up something else that you had going on with the fade in and outs but to be honest I’ve lost track of what we solved and what was changed. I don;t really know what the criteria are any more as I;m sure we’ve done all this already in some form.

2 Likes

This seems to work:
https://jsitor.com/yA9rRj5XQZ

Is there anything that should be changed or adjusted?

I added this:

  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  overflow: auto;

overflow: auto; so a scrollbar appears.

To the code:

.container {
  display: flex;
  justify-content: center;
}

.container.active {
  flex: 1 0 0;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  overflow: auto;
  animation: fadebody 5s ease 0s forwards;
  background-size: 165px 165px;
  background-image: linear-gradient(teal 5px, #0000 5px),

Is doing that good?

After I did that:
These properties can be removed.

.container {
 /* justify-content: center;*/
}
.container.active {
 /* flex: 1 0 0;*/
}

Updated: https://jsitor.com/yA9rRj5XQZ

It depends on situation because you could end up with double scroll bars in some circumstances. You should be ok but test outside of the fiddle.

I prefer to use the default window (body) scroll bars to scroll when needed and avoid inner full screen scrolling elements.

1 Like

With your code here:

Code 1
https://jsitor.com/_nvLlQC_sx

The fade is not the same as it is here:

Code 2
https://jsitor.com/Zb7cVWjvI

How it was originally set.

How would I replicate the same fade effect in Code 1 as it is in Code 2?

After clicking on the play images in both codes the fade effects are both different.

You should be able to see the difference right away.

Is it just the video you want to fade in as well. If so I think you can just run the animation on the body instead of the pseudo element.

e.g.

Add this:

body.bg1{
  animation: fadebody 5s ease 0s forwards;
}

Then remove it from here.

body.bg1:after {
  content: "";
  position: fixed;
  z-index: 1;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  /*animation: fadebody 5s ease 0s forwards;*/
  background-size: 165px 165px;
  background-image: linear-gradient(teal 5px, #0000 5px),
    linear-gradient(90deg, teal 5px, #0000 5px),
    linear-gradient(black 10px, #0000 10px 160px, black 160px),
    linear-gradient(90deg, black 10px, #0000 10px 160px, black 160px),
    linear-gradient(orange 15px, #0000 15px 155px, orange 155px),
    linear-gradient(90deg, orange 15px, #0000 15px 155px, orange 155px),
    linear-gradient(black 20px, #0000 20px 150px, black 150px),
    linear-gradient(90deg, black 20px, #0000 20px 150px, black 150px),
    linear-gradient(teal 25px, #0000 25px 145px, teal 145px),
    linear-gradient(90deg, teal 25px, #0000 25px 145px, teal 145px),
    linear-gradient(black 30px, #0000 30px 140px, black 140px),
    linear-gradient(90deg, black 30px, #0000 30px 140px, black 140px),
    linear-gradient(orange 35px, #0000 35px 135px, orange 135px),
    linear-gradient(90deg, orange 35px, #0000 35px 135px, orange 135px),
    linear-gradient(black 40px, #0000 40px 130px, black 130px),
    linear-gradient(90deg, black 40px, #0000 40px 130px, black 130px),
    linear-gradient(teal 45px, #0000 45px 125px, teal 125px),
    linear-gradient(90deg, teal 45px, #0000 45px 125px, teal 125px),
    linear-gradient(black 50px, #0000 50px 120px, black 120px),
    linear-gradient(90deg, black 50px, #0000 50px 120px, black 120px),
    linear-gradient(orange 55px, #0000 55px 115px, orange 115px),
    linear-gradient(90deg, orange 55px, #0000 55px 115px, orange 115px),
    linear-gradient(black 60px, #0000 60px 110px, black 110px),
    linear-gradient(90deg, black 60px, #0000 60px 110px, black 110px),
    linear-gradient(teal 65px, #0000 65px 105px, teal 105px),
    linear-gradient(90deg, teal 65px, #0000 65px 105px, teal 105px),
    linear-gradient(black 70px, #0000 70px 100px, black 100px),
    linear-gradient(90deg, black 70px, #0000 70px 100px, black 100px),
    linear-gradient(orange 75px, #0000 75px 95px, orange 95px),
    linear-gradient(90deg, orange 75px, #0000 75px 95px, orange 95px),
    linear-gradient(black 80px, #0000 80px 90px, black 90px),
    linear-gradient(90deg, black 80px, #0000 80px 90px, black 90px),
    linear-gradient(teal, teal);
}
1 Like

Yes, that works:
https://jsfiddle.net/t8n13p4x/

Bodytoggle removed from code
https://jsfiddle.net/aceugsv6/

This is being used instead, which replaces bodytoggle.

body.bg1{
  animation: fadebody 5s ease 0s forwards;
}

Bodytoggle added to code
https://jsfiddle.net/5b3frjc8/

Is bodytoggle not needed anymore?

The answer to that would be no then, it’s not needed.

It doesn’t look like its needed now as the fade keyframe animation still runs ok. Unless there is something I didn’t notice.

1 Like

Usually when z-index is being used, rearranging the html makes it possible to remove z-index from the code.

Is that able to be done in this case?

https://jsfiddle.net/gL4a6zow/

.container {
  z-index: 2;
}

body.bg1:after {
  z-index: 1;
}
<div class="outer">
	<div class="container with-curtain">
		<button class="playa thePlay" type="button" aria-label="Open">
         <svg width="100%" height="100%" viewBox="0 0 64 64">
            <g id="play">
               <title>Play</title>
               <circle cx="32" cy="32" r="32" fill="transparent" pointer-events="visiblePainted" />
               <path d="M25.6,46.4L44.8,32L25.6,17.6V46.4z M32,0C14.3,0,0,14.3,0,32s14.3,32,32,32s32-14.3,32-32S49.7,0,32,0z
                  M32,57.6C17.9,57.6,6.4,46.1,6.4,32S17.9,6.4,32,6.4S57.6,17.9,57.6,32S46.1,57.6,32,57.6z" />
            </g>
         </svg>
      </button>
		<div class="inner-container curtain curtain1">
			<div class="ratio-keeper">
				<div class="wrapa">
					<div class="video video-frame" data-id="CHahce95B1g"></div>
				</div>
				<div class="panel-left"></div>
				<div class="panel-right"></div>
			</div>

			<button class="home" type="button" aria-label="Close">
            <svg class="homesvg" width="38.39" height="38.39" viewBox="0 0 100 100">
               <g id="home">
                  <title>Home</title>

  <path d="M 6.3895625,6.4195626 C 93.580437,93.610437 93.580437,93.610437 93.580437,93.610437" />
  <path d="M 6.3894001,93.6106 C 93.830213,6.4194003 93.830213,6.4194003 93.830213,6.4194003"  />
               </g>
            </svg>
         </button>
		</div>
	</div>
</div>