Responsive Sticky Element

Hi,
I need some guidance please on how to construct a Sticky element for large up screens and destroy it for medium down with Javascript.

My JavaScript Sticky construct is as follows:

var $sticky_elem = new Foundation.Sticky($('#sticky-element'), {
    stickTo: 'bottom',
    topAnchor: 1,
    btmAnchor: 'sticky-bottom:top',
    marginTop: 0,
    marginBottom: 0,
    stickyOn: 'large'
});

I’m now stuck with the media query JavaScript functions!
How should I work this out?
Thank you.

Doesn’t your stickyOn setting already work like you need it?

https://get.foundation/sites/docs/sticky.html#js-options

For me it works with the latest version of Foundation Sites:

The stickyOn setting does stick the element only on large up, but I need to destroy the css properties and classes of the element and the container for my element to display correctly on medium down screens.

My issue is related to the Media Query functions, not the sticky construct.

Thank you!

I do not really understand, we just apply the position. I see no Media Query function here.

If you want to watch the current breakpoint, see https://get.foundation/sites/docs/media-queries.html#watching-for-breakpoint-changes

But generally you can apply CSS styles with a normal @media declaration.
Also see the classes on the sticky element and the container when it is sticky.

My difficulty is that I don’t know how to work with the media query functions. Could you please show me an example? If I just watch for breakpoint changes it doesn’t construct the sticky element if I’m starting on large up screens. I need to start by constructing the element if it’s on large up and destroy it if it goes medium down and construct it again if the screen is large up.

I’m thinking of this method because otherwise (using css) I need to look for all the properties and classes on the .sticky and sticky-container elements and “cancel” them. If I can do that with the destroy method with JavaScript it’s much easier. Does this makes sense?

This is already the case with the stickyOn setting, please check my codepen. You do not have to do that manually.

Also please check the events in the documentation for sticky.

If you want to apply simple CSS, use native media queries and target the classes which are added by the sticky component.

No, I don’t want to use CSS, that’s what I have been trying to say. There are too many CSS properties to address in the sticky element and the container. I would rather use the destroy method.
My element, that I want to stick on large up, is already beautifully styled for medium down, it would be a mess to get it to work if I had to deal with a sticky div and the container.

Please check the container, container-class and sticky-class options.

https://get.foundation/sites/docs/sticky.html#js-options

Sticky automatically sets the configured values when it becomes sticky and unsticky.

With this you can scope your changes in CSS.
Also please see the events at https://get.foundation/sites/docs/sticky.html#js-events

Besides this all plugins trigger the same events.
See https://github.com/foundation/foundation-sites/blob/33623c48433c0466c5afe5f670104192becfdb14/js/foundation.core.plugin.js#L33

This is the html structure that works for me on medium down:

<div class="top-bar" id="responsive-menu" data-toggler=".is-open">
	<div class="top-bar-navigation">
		<ul class="menu">
			<li><a href="w.html">what we do</a></li>
			<li><a href="o.html">ongoing</a></li>
			<li><a href="p.html">projects</a></li>
			<li><a href="ag.html">agenda</a></li>
			<li><a href="ab.html">about</a></li>
		</ul>
	</div>
	<div class="top-bar-courses">
		<ul class="menu">
			<li><a href="external.html">our courses</a></li>
		</ul>
	</div>
	<div class="top-bar-contact">
		<ul class="vertical menu">
			<li><a href="mailto:walele@domain.com">say hello:<br>walele@domain.com</a></li>
			<li><a href="facebook">facebook</a></li>
			<li><a href="instagram">instagram</a></li>
		</ul>
	</div>
</div>

As I’m designing mobile first, further down the development I needed to add a sticky element for large up, like so:

<div class="top-bar" id="responsive-menu" data-toggler=".is-open">
	<div id="sticky-element" data-sticky data-stick-to="bottom" data-top-anchor="1" data-btm-anchor="sticky-bottom:top" data-margin-top="0" data-margin-bottom="0" data-sticky-on="large">
		<div class="top-bar-navigation">
			<ul class="menu">
				<li><a href="w.html">what we do</a></li>
				<li><a href="o.html">ongoing</a></li>
				<li><a href="p.html">projects</a></li>
				<li><a href="ag.html">agenda</a></li>
				<li><a href="ab.html">about</a></li>
			</ul>
		</div>
		<div class="top-bar-courses">
			<ul class="menu">
				<li><a href="external.html">our courses</a></li>
			</ul>
		</div>
	</div>
	<div id="sticky-bottom" class="top-bar-contact">
		<ul class="vertical menu">
			<li><a href="mailto:walele@domain.com">say hello:<br>walele@domain.com</a></li>
			<li><a href="facebook">facebook</a></li>
			<li><a href="instagram">instagram</a></li>
		</ul>
	</div>
</div>

For the css to work on medium down I need to destroy the sticky element and the container because there are flex alignments involve don’t won’t work otherwise.

Hence, my initial request for a solution involving constructing and destroying the sticky element (and the container) with JavaScript.

Can you help me with that?

It is already done by the component afaik.

The _destroy method can be called when the breakpoint changes. Also you can add this check also on documentready.

Not sure what you mean, we do not apply these. Still you can target this using CSS and overwrite / reset values.

Your example does not really work, there are things missing like data-sticky-container.

Please create a working codepen which shows the current state and clearly describe your problem. As already described, you can watch and check the current breakpoint (you can do both - check whenever you need + watch), you can target the sticky element and container when the classes are applied and there are the methods like _init and _destroy.

I don’t think so. Do you mean that the component destroys the sticky element and the container on medium down because of the stickyOn: ‘large’ option? It doesn’t. It doesn’t on your CodePen.

Please tell me how exactly, that’s all I need to know. I cannot write the code by myself.

It’s my css.

You don’t need the data-sticky-container in the initial markup. The component creates the container. You can see from your own codepen.

Here are two codepens.
This is my Top Bar on medium down: https://codepen.io/koiastudio/pen/XWmPgEy
This is the same Top Bar with the sticky element, where I cannot display properly on medium down now: https://codepen.io/koiastudio/pen/NWGLagK

Exactly, I think this is what I need to do, but I am not able to write the code by myself.

Thank you very much for your support.

It sets only the following attributes:

Did you already try the _destroy method?

It’s simple the mediaquery check + _destroy on the sticky element.
I think you are thinking a bit too complicated - the following snippet does what you need:

You just have to add the initialization from your first post where I have added the comments. That’s all.

And in the else branch you can do anything that you have to do like adding / removing classes, chaing the DOM with jQuery, …

Combine this with a check for .sticky as _destroychanges it to this:

1 Like

Thank you! Yes, this is all I needed from the start!
Although I now understand that the destroy method doesn’t remove the sticky element (only the sticky container), but I will unwrap the div manually with jQuery.

Thank you for your patience!

After some implementation, I’m still facing two problems.

  1. Every time the breakpoint changes to something larger than medium it creates a new Sticky component (on top of the previous one already created). I need to create the Sticky component only if the change occurs from medium to large.
  2. If the initial screen size is large up, the Sticky is constructed and works accordingly. If you start with medium and change to large, the Sticky is constructed but there is some kind of miscalculation. The Sticky element jumps to the bottom after scrolling.
    Codepen: https://codepen.io/koiastudio/pen/NWGLagK

Did you destroy it before reinitializing it?

Probably a conflict with the bottom settings.
Currently the debugging is quite complicated here. Also we changed and fixed many issues with sticky in the past. I’m not sure what the cause is.

The thing is, for example, changing from screen size large to xlarge, the sticky element has been initialized and gets initialized again.

Yes because the code (mediaquery watcher) is called on every new breakpoint. You would have to add some additional checks to prevent this and combine it with the other mediaquery functions.

What exactly is your current code?

if (Foundation.MediaQuery.is('large')) {
	$('.top-bar-navigation, .top-bar-courses').wrapAll('<div id="sticky-element"></div>');
	var $sticky_component = new Foundation.Sticky($('#sticky-element'), {
	    stickTo: 'bottom',
	    topAnchor: 1,
	    btmAnchor: 'sticky-bottom:top',
	    marginTop: 0,
	    marginBottom: 0,
	    stickyOn: 'large'
	});
}
$(window).on("changed.zf.mediaquery", function (event, newSize, oldSize) {
	if (Foundation.MediaQuery.is('large')) {
		$('.top-bar-navigation, .top-bar-courses').wrapAll('<div id="sticky-element"></div>');
		var $sticky_component = new Foundation.Sticky($('#sticky-element'), {
		    stickTo: 'bottom',
		    topAnchor: 1,
		    btmAnchor: 'sticky-bottom:top',
		    marginTop: 0,
		    marginBottom: 0,
		    stickyOn: 'large'
		});
	} else {
		$('[data-sticky]').foundation("_destroy");
		$('.top-bar-navigation, .top-bar-courses').unwrap();
	}
});