7

I have a very specific question and I am not sure you can do what I want with css. For what I've seen on other posts, this might be out limits, but I thought I'd ask in case there are some css geniuses out there. I want to achieve a very specific behaviour. I have a column of text and some words in that column are highlighted. When you click the word, I want the text to split and a video to slide up.

my html is simple:

<p>text<span id="clickable" class="link">highlighted text</span>.
    <div class="closed">
            <video id="video" width="100%">
                <source src="myVideo.mp4" type="video/mp4">
            </video>
    </div>text</p> 

the css contains the class closed (with height 0) and the class open with a certain height

css

.closed {
    overflow: hidden;
    height: 0px;
    transition-property: all;
    transition-duration: 2s;
    transition-timing-function: ease-in-out;
}

.open {
    height: 11.4vw;
}

the js applies the class open when the text is clicked and plays the video, all very straight forward

JavaScript

$(document).ready(function() {
  $("#clickable").click(function() {
    var vid = document.getElementById("video");
    var closed = $('.closed');
    if(closed.hasClass("open")) {
      closed.removeClass('open');
      vid.pause();
    } else {
      closed.addClass('open');
      vid.play();
    }
  });
});

It all works. But here is the thing, and I know I am being picky so I am not sure if css can do this. The problem I have is that the text just after the "clickable" jumps to the next line. I want it to not do that as it disrupts the reading. I know this is happening because the div in which I have my video is a block element. But if I change the tag to make it a span (I know, a heresy), like so:

    <span class="closed">
            <video id="video" width="100%">
                <source src="myVideo.mp4" type="video/mp4">
            </video>
    </span>

the video refuses to follow the

overflow: hidden;

rule and is just not hidden from sight which is the whole point of the thing I am trying to do. Adding

display: inline-block;

to the div doesn't do it. I've experimented with some floats but I get erratic behaviour in Chrome. So I am running out of ideas. I want the video to behave like an inline element. Can someone just put me out of my misery and tell me it can't be done please so I can move on. Thanks for your time.

----------------------------------------------------------------EDIT-------------------------------------------------------------

Here is a gif of what my project looks like. This is with the "div" option, and it works like I want to except that as I was saying the after the video text is moving to the next line which I don't want.

GIF:

enter image description here

Paul
  • 1,277
  • 5
  • 28
  • 56
  • _For clarity:_ Are you asking about that sudden "drop down by 1 pixel " effect at the very end of the slide-down animation? – VC.One Nov 22 '16 at 00:34
  • No, not at all. I just want to be able to have the sentence that starts at "Then and there, I knew that I had to sing" to not be on the next line. – Paul Nov 22 '16 at 00:38
  • So it should read "`Rickie Lee Jones. Then and there,`" in one line? – VC.One Nov 22 '16 at 00:47
  • Yes. But it won't let me do it because the video is inside a div tag – Paul Nov 22 '16 at 01:25

3 Answers3

6

There should be no div element inside a paragraph (p) element. It causes the paragraph to be closed at that point, even if display: none is set for the div. You can see that behavior if you inspect the DOM with the F12 tool, and find more details on that subject in this post.

You can replace the div with a span to avoid the line break, set display: none when the video is hidden, and switch to display: block when the video is to be shown.

When the video is made visible, a line break appears in the text. One solution to that problem is to position the video dynamically at the end of the line. It can be done by taking some of the text that follows the video and move it inside of a span positioned in front of the video.

These suggestions are implemented in this jsfiddle. You can change the container width to test the behavior.

HTML:

<div>
    <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 
        incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
        quis nostrud exercitation <span id="clickable" class="link">ullamco</span>
        <span id="spanBefore"></span>
        <span id="spanVideo" class="closed">
            <video id="video" width="100%">
                <source src="http://html5demos.com/assets/dizzy.mp4" type="video/mp4">
            </video>
        </span>
        <span id="spanAfter">laboris nisi ut aliquip ex ea commodo consequat. Duis aute 
            irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat 
            nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa 
            qui officia deserunt mollit anim id est laborum.
        </span>
    </p>
</div>

CSS:

#spanVideo
{
    overflow: hidden;
    transition-property: height;
    transition-duration: 2s;
    transition-timing-function: ease-in-out;
}

.closed
{
    display: none;
}

.open1
{
    display: block;
    height: 0vw;
}

.open2
{
    height: 65vw;
}

.link
{
    background-color: yellow;
    cursor: pointer;
}

Javascript code:

var $spanVideo = $("#spanVideo");

function setVideoPosition() {
    var $spanClickable = $("#clickable");
    var $spanBefore = $("#spanBefore");
    var $spanAfter = $("#spanAfter");

    $spanAfter.text($spanBefore.text() + $spanAfter.text());
    $spanBefore.text("");

    var yBefore = $spanClickable.offset().top;
    var words = $spanAfter.text().split(/(\s)/);

    while ($spanAfter.offset().top <= yBefore && words.length > 0) {
        $spanBefore.text($spanBefore.text() + words.shift());
        $spanAfter.text(words.join(""));
    }
}

$("#clickable").click(function () {
    var video = document.getElementById("video");
    if ($spanVideo.hasClass("closed")) {
        setVideoPosition();
        $spanVideo.toggleClass("closed").toggleClass("open1");
        setTimeout(function () {
            $spanVideo.toggleClass("open2");
            video.play();
        }, 50);
    } else {
        video.pause();
        $spanVideo.toggleClass("open2");
        setTimeout(function () {
            $spanVideo.toggleClass("open1").toggleClass("closed");
        }, 2000);
    }
});
Community
  • 1
  • 1
ConnorsFan
  • 70,558
  • 13
  • 122
  • 146
5

Is this what you were after?

  • Assumed #clickable is the text (wasn't in OP's code). Made it in a class .clickable since there doesn't seem to be any advantage of having it as an id.

  • Added a neutral class .frame to span.closed and then changed span.frame.closed to div.frame.closed and added display:inline-block to it as well.

  • Changed the jQuery so that the state classes .opened and .closed alternate evenly when toggled on div.frame.

  • Added the transitions to both states on div.frame and video#video. video#video behaves correctly on opened state, but on closed state is still abrupt, we'll leave that job open for OP.

  • Added float to div.frame.opened and all paragraphs and expected the text to wrap around div.frame.opened. Floats are fickle, a better alternative is flexbox. Didn't use flexbox because of time.

SNIPPET

$(document).ready(function() {
          $(".clickable").click(function() {
            var vid = document.getElementById("video");
            var frame = $(this).next(".frame");
            if (frame.hasClass("opened")) {
              vid.pause();
              frame.removeClass('opened').addClass('closed');;
              
            } else {
              frame.addClass('opened').removeClass('closed');
              vid.play();
            }
          });
        });
.closed {
  overflow: hidden;
  height: 0px;
  transition-property: all;
  transition-duration: 2s;
  transition-timing-function: ease-in-out;
}
.closed #video {
  opacity: .3;
  height: 0px;
  transition-property: all;
  transition-duration: 2s;
  transition-timing-function: ease-in-out;
}
.opened {
  height: 190px;
  transition-property: all;
  transition-duration: 2s;
  transition-timing-function: ease-in-out;
  float: left;
  display: inline-block;
}
.opened #video {
  opacity: 1;
  height: 190px;
  transition-property: all;
  transition-duration: 2s;
  transition-timing-function: ease-in-out;
}
p {
  float: right;
  margin: 5px 0;
}
.clickable {
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p class="clickable">Attack of opportunity bolster undead class darkness ethereal plane grab infection inflict spell initiative modifier movement modes natural armor bonus paladin plant domain plant type sonic attack spell failure staggered suppress surprise tiny.</p>
<div class="frame closed">
  <video id="video" width="50%" controls="">
    <source src="http://html5demos.com/assets/dizzy.mp4" type="video/mp4">
  </video>
</div>
<p>5-foot step charm subschool class level coup de grace creation subschool critical hit massive damage natural nauseated paladin</p>
Community
  • 1
  • 1
zer00ne
  • 41,936
  • 6
  • 41
  • 68
  • Hi, thanks this is close to what I am looking at, but not quite. Your code is very similar to one of the many things I have tried. One thing that's important to me is the way the video looks when it opens. I will edit my original post with a gif that will get the point better than I can here. Notice that in the gif, the text after the video is separated from the text before the video which is what I am trying to correct. – Paul Nov 20 '16 at 01:37
2

After reading your edit I made this code that could help using zer00ne video

jquery

$(document).ready(function() {
  $("#text").on('click', function(event) {
    $("#video").slideToggle(400);
  });
});

Css

  #video {
    width: 25vw;
    height: 25vh;
    display: none;
    position: absolute;
    z-index: 100;
  }

HTML

<p id="text"><a href="#">
  Click me Click meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick meClick me
  </a>
  </p>
    <video id="video" controls="">
    <source src="http://html5demos.com/assets/dizzy.mp4" type="video/mp4">
  </video>


Advice me cousin an spring of needed. Tell use paid law ever yet new. Meant to learn of vexed if style allow he there. Tiled man stand tears ten joy there terms any widen. Procuring continued suspicion its ten. Pursuit brother are had fifteen distant has. Early had add equal china quiet visit. Appear an manner as no limits either praise in. In in written on charmed justice is amiable farther besides. Law insensible middletons unsatiable for apartments boy delightful unreserved. 
</p>

I basically add a position of absolute and then used jquery to show the video hopefully that helps

You can see it here https://jsfiddle.net/nbkn6u3d/

Mohammed
  • 352
  • 4
  • 18