Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Animated page transitions with css.
Note: In case you like to do your animations in JavaScript, you may also check out swupjs.
If you'd like to share your work using swup with me or others, please, drop me a link.
Swup enables animated transitions between pages powered by CSS. All you need to do is define how your page looks in the transition state, and swup takes care of the rest. Here's a little preview.
X-Requested-With
request header. In that case, swup can be easily modified based on your solution.npm install swup
or include the file from the dist folder
<script src="./dist/swup.js"></script>
Apart from simply loading the contents of the new page and replacing it in HTML, swup is built around css animation - you defined the transition and timing in CSS and swup handles the rest. Swup detects the end of transition of animated elements and proceeds to replacing the content and animating your page back. For the animations based on CSS to be possible, swup uses several classes that are assigned to the html tag through the process of page transition.
is-animating
- This class is assigned to the html tag once link is clicked and is removed shortly after the content of the page is replaced. (used for defining styles for an unloaded page)is-changing
- Assigned once a link is clicked and removed when the whole process of transition of pages is done. (used for showing some loading)is-leaving
- Assigned once a link is clicked and removed right before the content is replaced. (just in case.. maybe different animations for in/out transition?)is-rendering
- Assigned right before the content is replaced and removed when the whole process of transition of pages is done. (same as above)While developing the site, define the elements that are being animated and need to be replaced. Let's assume we want to fade in/out the main content of the page.
<html>
<head>
<title>Homepage</title>
</head>
<body>
<main>
<h1>This is homepage</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
<a href="/someOtherPage">Go to other page</a>
</main>
<div class="loading">We are loading...</div>
</body>
</html>
The first thing we need to do is enable swup.
import Swup from 'swup'
const swup = new Swup()
or
var swup = new Swup()
in case you've included swup from a dist folder.
Add the swup
id to the main element in HTML so it is replaced with the main element of the loaded page. Also, add the class that handles animations of our faded element - a-fade
.
<main id="swup">
<div class="a-fade">
...
</div>
</main>
<div class="loading">We are loading...</div>
Add your css for the element transition.
.a-fade {
transition: .4s;
opacity: 1;
}
html.is-animating .a-fade{
opacity: 0;
}
In case you'd like to display the loading element while the transition is done, css would be...
.loading {
display: none;
}
html.is-changing .loading{
display: block;
}
And that's it, we're all set, or at least for our fade in/fade out example.
Swup loads the page, handles classes for the css animation, waits for the animation to finish/page to load, replaces content and fades your content back. Swup also changes the title of your page to the loaded one, and exchanges classes of body element (more in options section).
In case you would like to animate the state of an element that stays on the page, but only changes it's style based on the page you're visiting, we've got you covered as well. Let's assume we want our navigation to change the background color for different pages, based on body class. In that case, you would probably like to start the change of background on the click of the link, but we can't really know what is the next body class going to be before the content of next page is loaded. For this purpose, there is special class added to your html tag on transition start and removed once the process of page transition is done.
This special class takes form of to-{route of next page in URL friendly form}
, where the only exception is the homepage, which does not have any route and so to-homepage
is used.
In case we want to use same feature with dynamic pages with unknown routes (blog posts, etc.) data attribute data-swup-class
set on link element will do the trick. Swup takes the content of the attribute of clicked link and adds class name on html tag in a format to-{content of the attribute}
, and also removes it after the whole process of transition is done (so for blog posts, you would want to add something like data-swup-class="blog-post"
on the link, which would result in to-blog-post
class on html tag).
More practical example - let's assume we want our header to be blue on the homepage (/), but yellow in the about (/about) page.
header {
transition: .4s;
}
body.page-homepage header {
background: blue;
}
body.page-about header {
background: yellow;
}
For the color to start changing right after the click on the link, simply add...
html.to-homepage header {
background: blue;
}
html.to-about header {
background: yellow;
}
Note: For popState events (back/forward) the process is disabled and the content of the page is replaced right away, to avoid tedious back button clicking and ensure proper functionality on touch devices (back/forward on horizontal drag).
Swup has a several options passed into a constructor as an object.
let options = {}
const swup = new Swup(options)
Link selector defines link elements that will trigger the transition. By default, the selector takes any link with href
attribute starting with /
, #
or with xlink
attribute for SVG elements. The raw selector form is shown below.
LINK_SELECTOR: 'a[href^="/"]:not([data-no-swup]), a[href^="#"]:not([data-no-swup]), a[xlink\\:href]'
In case you want to exclude links for some routes, lightbox or any other functionality, simply extend the selector. By default, you can simply add data-no-swup
attribute to the link, if you want to exclude just a few.
Tip: In most cases, it is good to disable transition between language versions of your site for multiple reasons - replacing of header/footer, analytics, etc.
Form selector defines forms that will be submitted via swup (with animation and all, as any other request). By default, any form with data-swup-form
attribute is selected. The raw selector form is shown below.
FORM_SELECTOR: 'form[data-swup-form]'
Swup will take the form data and submit it with appropriate method
and action
based on form attributes, where method defaults to GET
and action defaults to current url.
In case of GET
method, swup serializes the data into url. In case of POST
request, swup wraps the data and sends in via POST request.
Note: This feature is rather experimental and serves to enable submission of simple forms such as "search on website" form.
The response from the server must be a valid page with all elements that need to be replaced by swup.
Feature might not play well with swup cache. When cache is enabled, swup does not visit same url twice, including POST
requests with different data. Consider disabling cache or removing page from cache when necessary with swup.cache.remove('/your-url')
(swup does this before form submission, so the submit goes through every time).
This method does not support submission of files, or other advanced features.
Please refer to API section, for using swup API for sending requests.
Elements option defines the array of selectors of elements to be replaced.
Elements option usually contains the main element with the content of the page.
However, elements can include any element that is common for all transitioned pages.
This creates a possibility of animating elements on the page while still replacing it's parts.
Another good example is the "change language" link, which usually appears the same across the site, but leads to a different URL on each page.
Option defaults to the single element of id #swup
.
options = {
elements: ['#swup']
}
As swup is built on animations, it is required to define the elements that are being animated. Usually, you would like to give the elements some common class or class prefix. By default option is set to [class^='a-']
, which selects all elements with class attribute beginning with prefix a-
.
animationSelector: '[class^="a-"]'
Swup has a built-in cache, meaning that it stores previously loaded contents of the pages in memory in a form of an object. This drastically improves speed for static sites but should be disabled for dynamic sites. Cache option defaults to true
.
cache: true
When enabled, swup starts loading the page on hover of the link and does not wait for the user to click. In case the page is not loaded at the time of clicking on the link, swup simply waits for the request to finish and does not create a new request. Also, swup only creates one preload request at the time, so your server won't be overwhelmed by people just passing their cursor through some grid of links.
If cache is disabled, swup still preloads pages of hovered links, but the content of cache is removed after each page transition.
In case you want to preload some page automatically without any trigger by the user, data-swup-preload
on the link will do the trick.
preload: true
Some CSS styles are very often based on the class of the page defined in the body element.
Swup replaces the body classes for each loaded page. However, the site may use the body class attribute for functionality such as opening of some sort of menu by adding class to the body element.
In that case, you may want to define a prefix for your page style classes such as page-
, so only those are replaced.
By default option is set to ''
and all classes of body element are replaced during the transition.
In case the class attribute on body is not used at all, the class replacement can be disabled all together by setting the option to false
.
pageClassPrefix: ''
Swup has a built-in scroll control. Scroll to the anchor element in URL is also handled. This feature can be turned off and you can use your own scroll based on the emitted events discussed in events section. By default, the option is set to true
.
scroll: true
There are additional settings for scroll:
doScrollingRightAway
defines if swup is supposed to wait for the replace of the page to scroll to the top.
animateScroll
sets whether the scroll animation is enabled.
Animation of scroll is also adjustable with options scrollFriction
and scrollAcceleration
.
All default values for additional options of scroll are displayed below:
doScrollingRightAway: false,
animateScroll: true,
scrollFriction: .3,
scrollAcceleration: .04,
Due to the use of promises, transitionEnd and pushState features of JavaScript, swup has a basic support check built in to avoid breaking of the site in case of an older browser that doesn't support used features. However, as there may always be some exceptions for browsers or polyfills can be used on the page (that may or may not work), this support check can be disabled and you can use your own support check before creating the instance. Support option is enabled by default.
support: true
Debug mode is useful for integrating swup into your site. When enabled, swup displays emitted events (see events section) in the console, as well as contents of the cache when changed. Swup instance is also accessible globally as window.swup
in debug mode. Option defaults to false.
debugMode: false
Swup is built around browser history API, but sometimes some other tools manipulating the browser history can be used as well.
For this reason, swup places a source property into every history state object it creates, so it can be later identified (swup also modifies current history record on start, to include the "swup" source property as well).
On popState
events, swup only handles the records that were created by swup.
This behavior can be modified by skipPopStateHandling
option, which is represented by a function returning boolean (false = handle the popstate, true = do nothing).
The function accepts one argument - the popstate event. Option defaults to the following:
skipPopStateHandling: function(event){
if (event.state && event.state.source == "swup") {
return false;
}
return true;
}
let options = {
LINK_SELECTOR: 'a[href^="/"]:not([data-no-swup]), a[href^="#"]:not([data-no-swup]), a[xlink\\:href]',
FORM_SELECTOR: 'form[data-swup-form]',
elements: [
'#swup'
],
animationSelector: '[class^="a-"]',
cache: true,
pageClassPrefix: '',
scroll: true,
debugMode: false,
preload: true,
support: true,
disableIE: false,
skipPopStateHandling: function(event){
if (event.state && event.state.source == "swup") {
return false;
}
return true;
},
}
As we are replacing the native functionality of the browser, there may be some constraints related to that. For this purpose, swup emits bunch of events triggered on the document while working. We can use those events to enable our JavaScript, trigger some analytics, etc.
// trigger page view for GTM
document.addEventListener('swup:pageView', event => {
dataLayer.push({
'event': 'VirtualPageview',
'virtualPageURL': window.location.pathname,
'virtualPageTitle' : document.title
});
});
// load scripts for replaced elements
document.addEventListener('swup:contentReplaced', event => {
swup.options.elements.forEach((selector) => {
// load scripts for all elements with 'selector'
})
});
destroy()
destroy()
Some functionality is only necessary in certain projects. For this reason, swup has support for plugins.
import Swup from 'swup'
import pluginName from 'swup/plugins/pluginName'
or
<script src="./dist/swup.js"></script>
<script src="./dist/plugins/pluginName.js"></script>
and enable plugin at initialisation of swup by including it in options:
var options = {
plugins: [
pluginName
]
}
var swup = new Swup(options)
Plugins may also have some default options. To rewrite default options of plugin, use swup's usePlugin
function to enable plugin.
var swup = new Swup()
swup.usePlugin(pluginName, {option: "value of option"})
Merge Head Plugin replaces the html tags in head on each content replace (swup:contentReplaced
event).
Plugin has one option runScripts
. If the options is set to true
, script tags placed into head are executed (code inside of the tag as well as linked by src
attribute).
Option defaults to false
.
Google Analytics Plugin triggers pageview
event on swup:contentReplaced
(on each page change).
Note that this event is not triggered at the first load, so the first page view must be triggered elsewhere.
However, page view event is by default triggered in Javascripts tracking snippet.
Simplified code run by this plugin on swup:contentReplaced
:
window.ga('set', 'title', document.title);
window.ga('set', 'page', window.location.pathname + window.location.search);
window.ga('send', 'pageview');
Google Tag Manager Plugin triggers VirtualPageview
event on swup:contentReplaced
(on each page change) which can be associated with a page view within GTM.
Event object also includes virtualPageURL
holding the url of the page and virtualPageTitle
holding the title of the page.
Note that this event is not triggered at the first load, so the first page view must be triggered elsewhere.
Simplified code run by this plugin on swup:contentReplaced
:
window.dataLayer.push({
'event': 'VirtualPageview',
'virtualPageURL': window.location.pathname + window.location.search,
'virtualPageTitle': document.title
});
The instance of the swup can be imported and used across your sites JavaScript to enable some additional features. When debug mode (see options section) is enabled, instance is also available in window
object as window.swup
.
We can access some of the information used by swup such as used options:
swup.options.elements.forEach((selector) => {
// do whatever for each replaced element
})
swup.options.cache; // true/false
or change options
// enable cache
swup.options.cache = true;
or remove page from cache
// enable cache
swup.cache.remove('/your-url');
or use built in functions
// navigates to /someRoute with the animations and all... (can be used to submit forms)
swup.loadPage({
url: "/someRoute", // route of request (defaults to current url)
method: "GET", // method of request (defaults to "GET")
data: data, // data passed into XMLHttpRequest send method
});
Note: This built in function is used to submit forms with swup. For more information on submitting forms with XMLHttpRequest
, refer to Sending forms through JavaScript.
// disable swup
swup.destroy()
Sky is the limit here...
Swup is currently stable and production-ready. However, it is a "one-man show" and any contributions or suggestions are more than welcome.
1.0.1 - 2018-08-26
FAQs
Versatile and extensible page transition library for server-rendered websites
The npm package swup receives a total of 1,788 weekly downloads. As such, swup popularity was classified as popular.
We found that swup demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.