Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get text and video to flow together

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

like image 341
Paul Avatar asked Nov 19 '16 19:11

Paul


People also ask

What is automatic text flow?

Autoflow is a feature that can be used when placing text that will generate as many pages with text frames as are needed to contain the story. This is a one-page document, and the cursor is loaded with the text to be placed.

Which command is used for automatic text flow?

Flow text automatically without adding pages With a loaded text icon, hold down Shift+Alt (Windows) or Shift+Option (Mac OS).

How do you Autoflow text?

Autoflow by Shift-clicking. Adds pages and frames until all text is flowed into your document. Fixed-page autoflow by holding down Shift+Alt (Windows) or Shift+Option (Mac OS) when you click. Flows all text into the document, adding frames as necessary without adding pages.


3 Answers

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);
    }
});
like image 137
ConnorsFan Avatar answered Oct 17 '22 08:10

ConnorsFan


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>
like image 45
zer00ne Avatar answered Oct 17 '22 07:10

zer00ne


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/

like image 2
Mohammed Avatar answered Oct 17 '22 06:10

Mohammed