{"id":15713149,"url":"https://github.com/alexmacarthur/slide-element","last_synced_at":"2025-10-05T07:45:28.284Z","repository":{"id":40989719,"uuid":"292172799","full_name":"alexmacarthur/slide-element","owner":"alexmacarthur","description":"A \u003c 750 byte Promise-based library for animating elements with dynamic heights open \u0026 closed. Basically, a modern variant of jQuery's slideUp(), slideDown(), and slideToggle(). ","archived":false,"fork":false,"pushed_at":"2023-06-21T21:21:41.000Z","size":975,"stargazers_count":184,"open_issues_count":2,"forks_count":10,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-29T02:07:07.967Z","etag":null,"topics":["animation","jquery","slidetoggle","transition","web-animations-api"],"latest_commit_sha":null,"homepage":"https://www.macarthur.me/slide-element","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexmacarthur.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-02T03:51:32.000Z","updated_at":"2025-03-23T11:13:33.000Z","dependencies_parsed_at":"2024-06-19T19:06:12.014Z","dependency_job_id":"f2a771bf-5bd8-49f0-b69f-450c951a80c3","html_url":"https://github.com/alexmacarthur/slide-element","commit_stats":{"total_commits":63,"total_committers":7,"mean_commits":9.0,"dds":"0.12698412698412698","last_synced_commit":"57947c02f82ea2d2683ebcaf366f2748a194b2dd"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexmacarthur%2Fslide-element","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexmacarthur%2Fslide-element/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexmacarthur%2Fslide-element/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexmacarthur%2Fslide-element/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexmacarthur","download_url":"https://codeload.github.com/alexmacarthur/slide-element/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247280272,"owners_count":20912967,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["animation","jquery","slidetoggle","transition","web-animations-api"],"created_at":"2024-10-03T21:21:34.872Z","updated_at":"2025-10-05T07:45:23.238Z","avatar_url":"https://github.com/alexmacarthur.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# slide-element\n\n[![Bundle Size](https://badgen.net/bundlephobia/minzip/slide-element)](https://bundlephobia.com/result?p=slide-element)\n\nA [tiny](https://bundlephobia.com/result?p=slide-element), accessible, Promise-based, jQuery-reminiscent library for sliding elements with dynamic heights open \u0026 closed.\n\nTo see it in action, check out the following demos:\n\n- [Project Landing Page](https://alexmacarthur.github.io/slide-element/)\n- [CodePen Example](https://codepen.io/alexmacarthur/pen/VwpEgom)\n\n## Why?\n\nUsing JavaScript to **animate** an element open and closed hasn't traditionally been a straightforward task, especially if it contains dynamically sized content. You could go with something like [jQuery's `slideToggle()`](https://api.jquery.com/slidetoggle/), but that path would require you to take on a lot more code than necessary. Another option is using CSS to change the `max-height` value of an element, but this approach is filled with arbitrariness and difficult to pull off well when you're not sure how much content you'll be animating over.\n\nThis library gets the job done using the [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API/Using_the_Web_Animations_API#meet_the_web_animations_api), and it doesn't require elements to have fixed heights. Instead, element heights are calculated based on their contents, and then the appropriate values are applied to trigger a smooth, native transition. The animations themselves are powered by the same mechanics used within CSS transitions, making it one of the best ways to pull it off in terms of performance.\n\nIt's small, smooth, and focuses on doing one job well: sliding stuff open and closed.\n\n## Installation\n\nRun `npm install slide-element`, or use a CDN like [unpkg](https://unpkg.com/slide-element).\n\n## Setup\n\nMake sure your target element is set to `display: none;`.\n\n## Usage\n\n### Toggling Elements\n\nUse the `toggle` function to slide an element open \u0026 closed based on its current state.\n\n```javascript\nimport { toggle } from \"slide-element\";\n\ndocument.getElementById(\"button\").addEventListener(\"click\", (e) =\u003e {\n  toggle(document.getElementById(\"box\"));\n});\n```\n\n### Sliding Elements Down\n\nUse the `down` function to slide an element open.\n\n```javascript\nimport { down } from \"slide-element\";\n\ndocument.getElementById(\"button\").addEventListener(\"click\", (e) =\u003e {\n  down(document.getElementById(\"boxToSlideOpen\"));\n});\n```\n\n### Sliding Elements Up\n\nUse the `up` function to slide an element closed, and then set its `display` property to `none`.\n\n```javascript\nimport { up } from \"slide-element\";\n\ndocument.getElementById(\"button\").addEventListener(\"click\", (e) =\u003e {\n  up(document.getElementById(\"boxToSlideClosed\"));\n});\n```\n\n### Everything's a Promise\n\nEach of the functions provided return promises, so you can easily wait to perform an action after an animation is complete. The resolved value will indicate if the element has just been opened (`true`), closed (`false`), or the result of an animation that interruped another (see more below).\n\n```typescript\nimport { toggle } from \"slide-element\";\n\ndocument.getElementById(\"button\").addEventListener(\"click\", (e) =\u003e {\n  toggle(document.getElementById(\"someElement\")).then((isOpen: boolean | null) =\u003e {\n    console.log(\"Toggling is done!\");\n  });\n});\n```\n\n### Interrupting In-Progress Animations\n\nDepending on your settings, some users may be able to repeatedly trigger a _new_ before a previous one has been allowed to finish, which will cause the in-progress animation instantly finish before the new one can begin.\n\nWhen this occurs, the `isOpen` Promise that resolves after the animation is complete will return `null` for each animation that was triggered in interruption of the first. The initial animation, however will still resolve to the correct value. For example, pretend the following animation is clicked rapidly three times in a row.\n\n```typescript\nimport { toggle } from \"slide-element\";\n\ndocument.getElementById(\"button\").addEventListener(\"click\", (e) =\u003e {\n  toggle(document.getElementById(\"someElement\")).then((isOpen: boolean | null) =\u003e {\n    console.log(isOpen);\n  });\n});\n```\n\nWhen the animation has been allowed to complete, the following values will be logged -- two `null` values for the interrupting animations, and one boolean for the initial (and now complete) one. The point here is that it may be necessary to explicitly check for a non-`null` value when using the resolved \"open\" state.\n\n```\ntrue\nnull\nnull\n```\n\n### Animating Boxes with Padding\n\nIf the element you're animating has any `padding` set to it, be sure to also apply `box-sizing: border-box` as well. If you don't, the resulting animation will be weird and jumpy.\n\n```html\n\u003cdiv id=\"myTarget\" style=\"padding: 1rem; box-sizing: border-box; display: none;\"\u003e\n  My contents!\n\u003c/div\u003e\n```\n\n### Customizing the Animation\n\nBy default, `slide-element` uses the following transition property values:\n\nProperty                                                                                                 | Value\n-------------------------------------------------------------------------------------------------------- | ------\nduration (in milliseconds)                                                                               | 250\neasing ([choose one](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-timing-function#syntax)) | `ease`\n\nYou can override these by passing an object as the seceond parameter of any method:\n\n```javascript\nup(document.getElementById(\"element\"), {\n  duration: 500,\n  easing: \"ease-in-out\",\n});\n```\n\n### Customizing the Opened `display` Value\n\nOut of the box, `slide-element` will set your opened element to `display: block;`. If you'd like to customize this, pass a `display` value as an option:\n\n```javascript\ndown(document.getElementById(\"element\"), {\n  display: \"flex\"\n});\n```\n### Customizing the `overflow` Value Used During Animation\n\nOut of the box, `slide-element` will animate your element open \u0026 closed with `overflow: hidden;`. If you'd like to pass your own value, use the `overflow` option:\n\n```javascript\ndown(document.getElementById(\"element\"), {\n  overflow: \"auto\"\n});\n```\n\n## Usage w/o a Bundler\n\nIf you'd like to use `slide-element` directly in the browser via CDN, simply load the code, and then reference the function you'd like to use on the global `SlideElement` object:\n\n```javascript\n\u003cscript src=\"./path/to/slide-element.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n  document.getElementById('someElement').addEventListener('click', (e) =\u003e {\n    SlideElement.toggle(document.getElementById(\"someBox\"));\n});\n\u003c/script\u003e\n```\n\n## API\n\n```typescript\n// Toggle an element based on current state.\ntoggle(element: HTMLElement, options?: object): Promise\u003cboolean\u003e\n\n// Slide an element down.\nup(element: HTMLElement, options?: object): Promise\u003cboolean\u003e\n\n// Slide an element down.\ndown(element: HTMLElement, options?: object): Promise\u003cboolean\u003e\n```\n\nParam   | Type          | Description\n------- | ------------- | --------------------------------------------\nelement | `HTMLElement` | A single HTML node to be slid open or closed\noptions | `object`      | Options to customize sliding animation.\n\n## Accessibility\n\nThis library will respect the `prefers-reduced-motion` setting on a user's machine. When it's set to `reduce`, the sliding animation will be forced to a duration of `0`, making the respective elements open and close instantly.\n\nAdditionally, it's highly recommended that you toggle the `aria-expanded` attribute on any element (like a button) that's responsible for triggering an animation. This can be done by adding a single line of code that fires afters an animation is complete:\n\n```javascript\ndocument.getElementById('someButton').addEventListener('click', (e) =\u003e {\n    toggle(document.getElementById('thing2')).then((opened) =\u003e {\n\n      \u003c!-- Set the appropriate `aria-expanded` value based on the state of the container. --\u003e\n      e.target.setAttribute(\"aria-expanded\", opened);\n    });\n  });\n```\n## Show Off Your Use Case\n\nI love to see examples of how you're using the stuff I build. If you're comfortable, please [send it my way](http://macarthur.me/contact)!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexmacarthur%2Fslide-element","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexmacarthur%2Fslide-element","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexmacarthur%2Fslide-element/lists"}