How to change text color in different fragments - reveal.js

Say I have a simple reveal.js slide like this:
<section>
<h1>Title</h1>
<p >Text</p>
<p class="fragment">Fragment</p>
</section>
I'd like to change Text colour to red after Fragment appears on screen. How should I do it?

You could simply do
<section>
<h1>Title</h1>
<p class="fragment highlight-red" data-fragment-index="1" >Text</p>
<p class="fragment data-fragment-index="1"">Fragment</p>
</section>
That way, the red text and the "Fragment" text will always be in sync.

It's not rather simple:
<section>
<h1>Title</h1>
<p id="postfragment">Text</p>
<p class="fragment">Fragment</p>
</section>
...
<script>
Reveal.addEventListener('fragmentshown', function(event) {
document.getElementById("postfragment").style.color="red";
});
</script>

For those who want the highlight to actually appear after (rather than at the same time):
<section>
<h1>Title</h1>
<span class="fragment fade-in" data-fragment-index="1">
<p class="fragment highlight-red" data-fragment-index="3">Text</p>
</span>
<p class="fragment" data-fragment-index="2">Fragment</p>
</section>

Here is a sample of how to do it with red blue and green
<p>Highlight <span class="fragment highlight-red">red</span> <span class="fragment highlight-blue">blue</span> <span class="fragment highlight-green">green</span></p>

Related

Bootstrap gutter class gx-5 isn't working horizontally

I want some gaps between my cards horizontally. But when I am adding gx-5 bootstrap 5 class, it's not taking any gap horizontally. here is my code below.
<div className="container">
<div className="row gx-5">
{myProducts.map((product) => (
<div
key={product._id}
class="card col-sm-12 col-md-4 "
style={{ boxShadow: "rgba(0, 0, 0, 0.24) 0px 3px 8px" }}
>
<img class="card-img-top img-fluid" src={product.image} alt="" />
<div class="card-body">
<h5 class="card-title">{product.name}</h5>
<p class="card-text">{product.description}</p>
</div>
</div>
))}
</div>
</div>
Is anyone there to help me, please?
Try this card snippet out:
<div class="col-sm-12 col-md-4">
<div class="card">
<img class="card-img-top" src="..." alt="..." />
<div class="card-body">
<h5 class="card-title">Product</h5>
<p class="card-text">Product</p>
</div>
</div>
</div>
Explanation:
I just nested a new card div inside the column because card class affects how Boostrap manages the gutters.
A working example:
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<div class="row gx-5">
<div class="col-sm-12 col-md-4">
<div class="card">
<img class="card-img-top" src="https://media.istockphoto.com/photos/forest-wooden-table-background-summer-sunny-meadow-with-green-grass-picture-id1353553203?b=1&k=20&m=1353553203&s=170667a&w=0&h=QTyTGI9tWQluIlkmwW0s7Q4z7R_IT8egpzzHjW3cSas=" alt="" />
<div class="card-body">
<h5 class="card-title">Product 01</h5>
<p class="card-text">Product 01 description</p>
</div>
</div>
</div>
<div class="col-sm-12 col-md-4">
<div class="card">
<img class="card-img-top" src="https://media.istockphoto.com/photos/forest-wooden-table-background-summer-sunny-meadow-with-green-grass-picture-id1353553203?b=1&k=20&m=1353553203&s=170667a&w=0&h=QTyTGI9tWQluIlkmwW0s7Q4z7R_IT8egpzzHjW3cSas=" alt="" />
<div class="card-body">
<h5 class="card-title">Product 01</h5>
<p class="card-text">Product 01 description</p>
</div>
</div>
</div>
<div class="col-sm-12 col-md-4">
<div class="card">
<img class="card-img-top" src="https://media.istockphoto.com/photos/forest-wooden-table-background-summer-sunny-meadow-with-green-grass-picture-id1353553203?b=1&k=20&m=1353553203&s=170667a&w=0&h=QTyTGI9tWQluIlkmwW0s7Q4z7R_IT8egpzzHjW3cSas=" alt="" />
<div class="card-body">
<h5 class="card-title">Product 01</h5>
<p class="card-text">Product 01 description</p>
</div>
</div>
</div>
</div>
</div>
Note: I converted the code snippet into plain HTML please consider converting it back to its original state without changing the classes.

AntD Carousel only displays the first div in it

This is the Carousel gist from my code.
<Carousel arrows={true}>
<div className='new-offers-item'>
<div className='new-offers-item-bg'>
<div className='new-offers-item-rent-tag'>TEXT HERE</div>
<div className='new-offers-item-favourite' />
<div className='new-offers-posted-at'>ANOTHER TEXT HERE, 10:44</div>
</div>
<div className='new-offers-item-location-rate'>
<div className='new-offers-item-location'>street address, 5<br />CC Espiral,<br /> 1 floor</div>
<div className='new-offers-item-rate'>
<div>
<span className='new-offers-item-rate-value'>240 000 </span>
<span className='new-offers-item-rate-unit'>abcd.</span>
</div>
</div>
</div>
<div className='new-offers-item-city-street'>
<span>City</span>
<span> </span>
<span>Address1</span>
</div>
<div className='new-offers-item-description'>
<div className='new-offers-item-description-row'>
<div className='new-offers-item-description-row-space'>
<div className='new-offers-item-description-row-space-division'>
<div>
<img src={sqM} />
</div>
<p>
<span>Total</span>
<span>600</span>
</p>
<p>
<span> </span>
<span className='span-divider'>/</span>
</p>
<p>
<span>Sale</span>
<span>300</span>
</p>
</div>
<div className='new-offers-item-description-row-metre-rate'>
<p>
<span>Per meter</span>
</p>
<p>
<span>6 700 </span>
<span>unit<sup>2</sup></span>
</p>
</div>
</div>
<div className='new-offers-item-description-row'>
<div className='new-offers-item-description-row-space'>
<div className='new-offers-item-description-row-space-division'>
<div className='new-offers-item-description-second'>
<img src={bldgIcon} />
<span className='item-type'>Торговый центр</span>
</div>
</div>
<div className='new-offers-item-description-row-metre-rate'>
<div className='new-offers-item-description-second'>
<img src={doorsIcon} />
<span className='item-type'>10 floor</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div className='new-offers-item'>
<div className='new-offers-item-bg'>
<div className='new-offers-item-rent-tag'>TEXT HERE</div>
<div className='new-offers-item-favourite' />
<div className='new-offers-posted-at'>ANOTHER TEXT HERE, 10:44</div>
</div>
<div className='new-offers-item-location-rate'>
<div className='new-offers-item-location'>street address, 5<br />CC Espiral,<br /> 1 floor</div>
<div className='new-offers-item-rate'>
<div>
<span className='new-offers-item-rate-value'>240 000 </span>
<span className='new-offers-item-rate-unit'>abcd.</span>
</div>
</div>
</div>
<div className='new-offers-item-city-street'>
<span>City</span>
<span> </span>
<span>Address1</span>
</div>
<div className='new-offers-item-description'>
<div className='new-offers-item-description-row'>
<div className='new-offers-item-description-row-space'>
<div className='new-offers-item-description-row-space-division'>
<div>
<img src={sqM} />
</div>
<p>
<span>Total</span>
<span>600</span>
</p>
<p>
<span> </span>
<span className='span-divider'>/</span>
</p>
<p>
<span>Sale</span>
<span>300</span>
</p>
</div>
<div className='new-offers-item-description-row-metre-rate'>
<p>
<span>Per meter</span>
</p>
<p>
<span>6 700 </span>
<span>unit<sup>2</sup></span>
</p>
</div>
</div>
<div className='new-offers-item-description-row'>
<div className='new-offers-item-description-row-space'>
<div className='new-offers-item-description-row-space-division'>
<div className='new-offers-item-description-second'>
<img src={bldgIcon} />
<span className='item-type'>Торговый центр</span>
</div>
</div>
<div className='new-offers-item-description-row-metre-rate'>
<div className='new-offers-item-description-second'>
<img src={doorsIcon} />
<span className='item-type'>7 floor</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</Carousel>
Only the first div.new-offers-item gets displayed.
How do I get the second one and others to display?
Since antd using slick slider for their Carousel, you should refer to their API
To be more precise, you will need to use prop: "slidesToShow" in order to show the numbers of slides that you need.
For Example:
const settings = {
dots: true,
slidesToShow: 3,
slidesToScroll: 1
};
It is as designed. This shows the first item as current and to move to the next item, you can click on the navigation.
You can set the background of new-offers-item to see the navigation. You can refer to the example here:
https://codesandbox.io/s/nn44020wzp
This is the soultion that produced the desired outcome. Added 2 more
.new-offers-item.
const carouselSettings = {
arrows: true,
slidesToShow: 3,
slidesToScroll: 1
};
Then add the const carouselSettings to the Carousel component:
<Carousel {...carouselSettings}>...</Carousel>.
Based on react-slick docs and playground at https://github.com/akiran/react-slick.
AntD Carousel doesn't place the arrows to the html layout when the number of items inside the Carousel equals to slidesToShow. The arrows which are buttons are transparent by default you'd need to put an arrow image inside the buttons. The css classes for buttons are .ant-carousel .slick-prev and .ant-carousel .slick-next.

Two fixed size columns in 3 column layout in AngularJS Material

I have a question similar to this one Flexbox - two fixed width columns, one flexible
But that one is about doing it using just Flexbox. I'm trying to use AngularJS Material. I want my left and right divs to be a fixed 28px width, and the center div to flex.
Something like this:
<div layout="row" layout-margin>
<!-- Alphabet - First Half -->
<div flex="28px">
<md-list>
<md-list-item>
<md-button class="md-fab md-mini">
<div align="center">A</div>
</md-button>
</md-list-item>
</md-list>
</div>
<div flex>
<md-content></md-content>
</div>
<!-- Alphabet - Second Half -->
<div flex="28px">
<md-list>
<md-list-item>
<md-button class="md-fab md-mini">
<div align="center">N</div>
</md-button>
</md-list-item>
</md-list>
</div>
</div>
The flex attribute value is restricted to 33, 66, and multiples of five.
For example: flex="5", flex="20", "flex="33", flex="50", flex="66", flex="75", ....
Try this
<div layout="row" layout-margin>
<div flex="25">
<md-list>
<md-list-item>
<md-button class="md-fab md-mini">
<div align="center">A</div>
</md-button>
</md-list-item>
</md-list>
</div>
<div flex>
<md-content></md-content>
</div>
<div flex="25">
<md-list>
<md-list-item>
<md-button class="md-fab md-mini">
<div align="center">N</div>
</md-button>
</md-list-item>
</md-list>
</div>
</div>

<img> element with onclick submits the form instead of firing action

I am having a weird issue in my Login.cshmtl view which I posted below. So on the top right corner of my login page, I have two textboxes for credentials and two .png images as their labels, a "Remember Me" checkbox and a .png image as its label, and finally a "ForgotPassword" .png image defined as:
<img onclick="location.href ='#Url.Action("ForgotPassword", "Account")'" src="~/Content/Images/ForgotPassword.png" />
Everything worked fine until I changed this line as follows:
<input type="image" onclick="location.href ='#Url.Action("ForgotPassword", "Account")'" src="~/Content/Images/ForgotPassword.png" />
Surprisingly, now my image-button is broken and it submits the page! Using the debugger I observe that POST method of my Login action is called instead of ForgotPassword action. Can you please explain how this happens? Below, I am posting the Login.cshtml view with irrelevant parts removed.
#model FooProject.Web.ViewModels.LoginViewModel
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
....
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="navbar navbar-fixed-top">
<div class="navbar-header">
<input type="image" class="navbar-brand" onclick="location.href ='#Url.Action("Index", "Home")'" src="~/Content/Images/logo.png"/>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav" style="margin:10px">
<li>#Html.ActionLink("About", "About", "Home")</li>
<li>#Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
<div class="nav navbar-nav navbar-right">
<div class="row">
<div class="col-md-5">
<span class="actionLink">
<img src="~/Content/Images/Username.png"/>
</span>
</div>
<div class="col-md-7">
<span class="actionLink">
<img src="~/Content/Images/Password.png"/>
</span>
</div>
</div>
#using (Html.BeginForm("Login", "Account", FormMethod.Post, new { id = "loginForm", #class = "navbar-right form-inline" }))
{
#Html.AntiForgeryToken()
<div class="row">
<div class="col-md-5">
#Html.TextBoxFor(m => m.UserName, new { #class = "" })
</div>
<div class="col-md-5">
#Html.PasswordFor(m => m.Password) <br />
</div>
<div class="col-md-2" style="padding-left:0">
<input type="image" alt="Submit" src="~/Content/Images/Login.png" style="width:45px" />
</div>
</div>
<div class="row">
<div class="col-md-5">
#Html.CheckBoxFor(m => m.RememberMe)
<span class="actionLink">
<img src="~/Content/Images/RememberMe.png" style="height:11px;vertical-align:top;margin-top:2px" />
</span>
</div>
<div class="col-md-7">
<img onclick="location.href ='#Url.Action("ForgotPassword", "Account")'" src="~/Content/Images/ForgotPassword.png" />
</div>
</div>
}
</div>
</div>
</div>
</div>
</div>
</body>
</html>
<input type="image"> works as submit button, so this is expected behavior.
But there is solution:
<input type="image" onclick="location.href ='#Url.Action("ForgotPassword", "Account")'; return false;" src="~/Content/Images/ForgotPassword.png" /> will do the trick.
By adding return false; you prevent submission from being executed.
There is also alternative solution:
There is no reason to replace img tag with input. If you want to see cursor on hover, you can do it with CSS:
img.submit:hover {
cursor: pointer;
}
and decorate img with submit class:
<img class="submit" onclick="location.href ='#Url.Action("ForgotPassword", "Account")'" src="~/Content/Images/ForgotPassword.png" />
And the way I would do that:
<a href='#Url.Action("ForgotPassword", "Account")'>
<img src="/Content/Images/ForgotPassword.png" />
</a>
By changing the image tag to an input tag you've create an image as a submit button and it's doing what you should expect: submitting the form with the action and method defined.
See http://www.w3schools.com/tags/att_input_type.asp for more information
From the W3C Wiki (emphasis is mine):
The image button state represents either an image from which a user
can select a coordinate and submit the form, or alternatively a button
from which the user can submit the form. The element is a button,
specifically a submit button

Replace image in reveal.js

Suppose I have two very similar images I want to display in succession (say first is a photo and the second one the same photo with some area highlighted). I'd like to avoid a transition animation and just have the second image replace the first image. Is this possible with reveal.js?
Setting data-transition="none" doesn't work very well because the previous slide still retains its animation.
Reveal.js does not have any direct method by itself for doing of what is being asked. However, it can be done using a div container and the fragment feature of reveal.js. The container includes the images, which are absolutely positioned within it, and because of that it has to have fix dimensions.
The following piece of html displays the first image and on the next slide the second image on top of the first one.
<section>
<h1>Slide 1</h1>
<div style="position:relative; width:640px; height:480px; margin:0 auto;">
<img class="fragment" width="640" height="480" src="img1.jpg" style="position:absolute;top:0;left:0;" />
<img class="fragment" width="640" height="480" src="img2.jpg" style="position:absolute;top:0;left:0;" />
</div>
</section>
While this piece of html displays the first image and on the next slide the first image fades out and the second image fades in instead.
<section>
<h1>Slide 2</h1>
<div style="position:relative; width:640px; height:480px; margin:0 auto;">
<img class="fragment fade-out" data-fragment-index="0" width="640" height="480" src="img1.jpg" style="position:absolute;top:0;left:0;" />
<img class="fragment fade-in" data-fragment-index="0" width="640" height="480" src="img2.jpg" style="position:absolute;top:0;left:0;" />
</div>
</section>
reveal.js 4.0 introduces a new r-stack class that makes it easier to stack elements on top of each other.
<div class="r-stack">
<img class="fragment" src="https://placekitten.com/450/300" width="450" height="300">
<img class="fragment" src="https://placekitten.com/300/450" width="300" height="450">
<img class="fragment" src="https://placekitten.com/400/400" width="400" height="400">
</div>
The above example fades in images on top of each other. If you want to only show one image at a time you'll need to use slightly different fragment settings.
<div class="r-stack">
<img class="fragment current-visible" src="...">
<img class="fragment current-visible" src="...">
<img class="fragment" src="...">
</div>
You can see examples of how this works in the reveal.js docs https://revealjs.com/layout/#stack
Another possible solution would be to use Javascript. With this code you can not only replace images, but any content.
It is important to apply the classes content-target and content-source. It is also important to use the display: none; style.
The html could look like:
<section>
<h3>Headline</h3>
<div class="content-target"></div>
<div style="display: none;">
<div class="content-source fragment" data-fragment-index="0">
<img src="path/to/image.jpg" />
<p>Some text</p>
</div>
<div class="content-source fragment" data-fragment-index="1">
<ul>
<li>List item 1</li>
<li>List item 2</li>
</ul>
</div>
<div class="content-source fragment" data-fragment-index="2">
<img src="path/to/another/image.jpg" />
</div>
</div>
</section>
Now we add a function fadeContent() and call it every time fragmentshown or fragmenthidden is triggered.
function fadeContent($el, back=false) {
// If we go back, choose previous element, otherwise current element
$new = (back ? $el.prev() : $el);
if($new.length == 0) {
$text = $el.parent().siblings('.content-target');
$text.fadeOut(200);
} else {
$text = $new.parent().siblings('.content-target');
$text.hide(0, function() {
$text.html($new.html());
$text.fadeIn(300);
});
}
}
Reveal.addEventListener('fragmentshown', function(event) {
// Get first fragment which has "content-source" class
var $el = $($(event.fragments).filter(function() {
return $(this).hasClass('content-source')
})[0]);
// Show content
if ($el.hasClass('content-source'))
fadeContent($el);
});
Reveal.addEventListener('fragmenthidden', function(event) {
// Get first fragment which has "content-source" class
var $el = $($(event.fragments).filter(function() {
return $(this).hasClass('content-source')
})[0]);
// Hide element
if ($el.hasClass('content-source'))
fadeContent($el, back=true);
});
Since we have just extended the fragment functionality, we can still use the data-fragment-index attribute and change the order.
The solution can easily be optimized/customized.
You can specify two transitions, for entering and for leaving, thus the following works but has a glitch (image flicker when appearing) :
<section data-transition="slide none">
<img src="timeline2.a.svg">
</section>
<section data-transition="none">
<img src="timeline2.b.svg">
</section>
<section data-transition="none side">
<img src="timeline2.c.svg">
</section>
Otherwise this may also be a solution, this is a bit different from what you want but is not bad :
<section data-transition="slide fade-out">
<img src="timeline2.a.svg">
</section>
<section data-transition="fade-in fade-out">
<img src="timeline2.b.svg">
</section>
<section data-transition="fade-in side">
<img src="timeline2.c.svg">
</section>
Suppose, you are using data-background for displaying your photos, then you need to use data-background-transition="none" for the desired effect.

Resources