{"id":27942598,"url":"https://github.com/propjockey/css-api-fetch","last_synced_at":"2025-05-07T11:57:24.271Z","repository":{"id":270054339,"uuid":"908798139","full_name":"propjockey/css-api-fetch","owner":"propjockey","description":"Make API Requests in CSS and store the response data on :root --vars without JavaScript.","archived":false,"fork":false,"pushed_at":"2025-01-06T18:31:11.000Z","size":53,"stargazers_count":85,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-07T11:57:18.636Z","etag":null,"topics":["api","css"],"latest_commit_sha":null,"homepage":"http://css-api.com","language":"CSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/propjockey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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":"2024-12-27T02:06:41.000Z","updated_at":"2025-04-05T22:27:31.000Z","dependencies_parsed_at":"2024-12-28T03:37:14.715Z","dependency_job_id":null,"html_url":"https://github.com/propjockey/css-api-fetch","commit_stats":null,"previous_names":["propjockey/css-api-fetch"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/propjockey%2Fcss-api-fetch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/propjockey%2Fcss-api-fetch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/propjockey%2Fcss-api-fetch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/propjockey%2Fcss-api-fetch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/propjockey","download_url":"https://codeload.github.com/propjockey/css-api-fetch/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252873984,"owners_count":21817711,"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":["api","css"],"created_at":"2025-05-07T11:57:23.633Z","updated_at":"2025-05-07T11:57:24.254Z","avatar_url":"https://github.com/propjockey.png","language":"CSS","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Jane Ori - PropJockey.io](https://img.shields.io/badge/Jane%20Ori%20%F0%9F%91%BD-%F0%9F%A4%8D%20PropJockey.io-7300E6.svg?labelColor=FB04C2\u0026style=plastic)](http://jane.propjockey.io/)\n\n# css-api-fetch from \u003cimg src=\"https://github.com/user-attachments/assets/87119fb5-c39d-429a-9bfd-424f0e100720\" alt=\"\" width=\"30px\"\u003e PropJockey\nMake remote API Requests in CSS (Cascading Style Sheets) and store the response data in `--vars` on `:root` *without JavaScript*.\n\nCurious *how* this works? [Read about it here!](https://dev.to/janeori/getting-your-ip-address-with-css-and-other-32-bit-api-responses-without-javascript-402h)\n\n## api-fetch.css, api-fetch-root.css, or api-fetch-compat.css?\n\nThere are 3 css files you can use with different trade-offs.\n\n1) `api-fetch.css` - contains both of the following\n\n2) `api-fetch-root.css`\n\n* currently only works in Chrome\n* Response data is lifted to `:root` and can be used anywhere.\n* Up to 4 responses can be stored at the same time for use anywhere in your project.\n* Triggering the request requires specific setup but there are no limits on when you choose to initiate the requests.\n\n3) `api-fetch-compat.css`\n\n* works in Chrome, FireFox, Safari\n* Does not lift the response data to `:root`, it can only be used within the element.\n* Does not let you store more than one response at a time unless they are in sepearate elements.\n* The element that contains the response data must have a fixed width and height and can't automatically resize based on the content.\n* Overflow is hidden and can't be avoided.\n* Anything you build that uses the single response must be within the provided element.\n* Triggering the request is in your hands, based on however/whenever you choose to set the `url()`\n\n## Installation and Setup\n\n`css-api-fetch` requires specific html in additon to the CSS.\n\n### Add the CSS first:\n\n`$ npm install css-api-fetch`\n\nThen include `/node_modules/css-api-fetch/api-fetch.css`\n\n#### OR Use your favorite NPM CDN for small projects\n\nFrom html:\n\n```html\n\u003clink rel=\"stylesheet\" type=\"text/css\" href=\"https://unpkg.com/css-api-fetch@3/api-fetch.css\"\u003e\n```\n\nor directly from your CSS:\n\n```css\n@import url(https://unpkg.com/css-api-fetch@3/api-fetch.css);\n```\n\n### Adding the HTML\n\nSee `./html-templates-compat.md` for instructions on the `compat` version setup and usage.\n\nFor the `root` version, add a single tag anywhere on the page per api you want to use:\n\n```html\n\u003cdiv class=\"api-1-fetch\"\u003e\u003c/div\u003e\n```\n\nYou can save responses to `:root` from up to 4 different API requests at the same time.\n\n`api-1-fetch` `api-2-fetch` `api-3-fetch` `api-4-fetch`\n\nUse separate html elements for each of these, do not nest anything inside.\n\nIf you wish to see debug info, add this tag anywhere on the page:\n\n```html\n\u003cdiv class=\"api-debug-on\"\u003e\u003c/div\u003e\n```\n\nBoth versions, `root` and `compat`, can be used at the same time.\n\n### Customize API endpoints in the CSS (:root version)\n\nYou can specify any of the API endpoints anywhere in your CSS so long as the var is visible to the corresponding `api-fetch-X` tag:\n\n```css\nbody {\n  --api-1-fetch: url(https://css-api.propjockey.io/os-country.php);\n  --api-2-fetch: url(https://picsum.photos/512/256);\n  --api-3-fetch: url(https://picsum.photos/100/222);\n  --api-4-fetch: url('data:image/svg+xml;utf8,\u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"0px\" height=\"99999px\"\u003e\u003c/svg\u003e');\n}\n```\n\nYou may want to only fetch this API data in specific app state conditions.\n\nYou can easily use container style queries to conditionally use an endpoint:\n\n```css\n@container style(--amazing-computation: 0) {\n  .api-2-fetch { --api-2-fetch: none; }\n}\n@container style(--amazing-computation: 1) {\n  .api-2-fetch { --api-2-fetch: url(...) }\n}\n...\n```\n\n### Customize API Response maximum values (root version)\n\nAdded in v 3.1.0 - no functionality changes unless you set these.\n\nIn the `root` version, you can configure the maximum response size by setting a variable on `:root`:\n\n`:root { --api-1-max-w: \u003cinteger\u003e; }` // maximum width returned from api 1\n\n`:root { --api-4-max-h: \u003cinteger\u003e; }` // maximum height returned from api 4\n\nYou can be less specific and specify both height and width at once:\n\n`:root { --api-2-max: \u003cinteger\u003e; }` // maximum height and width returned from api 2\n\nYou can be even less specific and specify a maximum height OR width for all api results:\n\n`:root { --api-max-w: \u003cinteger\u003e; }` // maximum width returned from all apis\n\n`:root { --api-max-h: \u003cinteger\u003e; }` // maximum height returned from all apis\n\nYou can be as non-specific as possible and specify the maximum for height AND width of all api responses:\n\n`:root { --api-max: \u003cinteger\u003e; }` // maximum height and width returned from all APIs.\n\nHigher specificity overrides lower specificity.\n\nThe default is the lowest specificity, and you can set it to whatever you want:\n\n`:root { --api-max: 99999; }`\n\n## Setting up a compatible API (both versions)\n\n`css-api-fetch` expects an image response with the response data encoded into the height and width.\n\nUnless overwritten within the `:root` version, the maximum width in both versions is `99999px` which is more than 16 bits of data.\n\nUnless overwritten within the `:root` version, the maximum height in both versions is also `99999px` which is more than 32 bits of data total.\n\n### For example, getting the user's IP Address with CSS\n\nHere, is php generating an svg that encodes the 32 bit request IP Address:\n\n```php\n\u003c?php\n  header('Content-type: image/svg+xml');\n\n  $adr = $_SERVER['REMOTE_ADDR'] ?: '255.255.255.255';\n  $hex = str_pad(implode(array_map('dechex', explode('.', $adr, 4))), 8, '0', STR_PAD_LEFT);\n  $width = hexdec(preg_replace('/(^0{0,3})|(.{4}$)/', '', $hex) ?: '0');\n  $height = hexdec(preg_replace('/^.{4}0{0,3}/', '', $hex) ?: '0');\n\n  echo '\u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"' . $width . 'px\" height=\"' . $height . 'px\"\u003e\u003c/svg\u003e';\n?\u003e\n```\n\n16 bits in width, 16 bits in height\n\nHere is a live example of this in action:\n\n[![screenshot of the live demo here](https://github.com/user-attachments/assets/2248a215-cb69-4708-860c-cd1b644f6422)](https://codepen.io/propjockey/pen/JoPyxrK/a2aec757b3cd020a7e1bddce17ff31ed?editors=1100)\n\n\n## Accessing the remote request's Response Data (:root version)\n\nOnce a request is complete, response data from the width and height of the image will be returned and set on root as an integer.\n\n```css\n@property --api-1-w { syntax: \"\u003cinteger\u003e\"; inherits: true; initial-value: 0; }\n@property --api-1-h { syntax: \"\u003cinteger\u003e\"; inherits: true; initial-value: 0; }\n@property --api-2-w { syntax: \"\u003cinteger\u003e\"; inherits: true; initial-value: 0; }\n@property --api-2-h { syntax: \"\u003cinteger\u003e\"; inherits: true; initial-value: 0; }\n@property --api-3-w { syntax: \"\u003cinteger\u003e\"; inherits: true; initial-value: 0; }\n@property --api-3-h { syntax: \"\u003cinteger\u003e\"; inherits: true; initial-value: 0; }\n@property --api-4-w { syntax: \"\u003cinteger\u003e\"; inherits: true; initial-value: 0; }\n@property --api-4-h { syntax: \"\u003cinteger\u003e\"; inherits: true; initial-value: 0; }\n```\n\nYou can use `calc()` and other techniques to do any decoding necessary. Please reach out if you have a specific goal, there's not much that can't be done yet.\n\nFor example, [css-bin-bits](https://propjockey.github.io/css-bin-bits/) can help you convert 16 bit decimal numbers between decimal and binary and perform bitwise operations on the values without JS.\n\nAdditionally, there is a ready bit available for all 4 api ids that will be set to `1` when it has any non-0 data:\n\n```css\n@property --api-1-ready { syntax: \"\u003cinteger\u003e\"; inherits: true; initial-value: 0; }\n@property --api-2-ready { syntax: \"\u003cinteger\u003e\"; inherits: true; initial-value: 0; }\n@property --api-3-ready { syntax: \"\u003cinteger\u003e\"; inherits: true; initial-value: 0; }\n@property --api-4-ready { syntax: \"\u003cinteger\u003e\"; inherits: true; initial-value: 0; }\n```\n\n## Many Thanks\n\n[Kizu](https://front-end.social/@kizu) for [suggesting a different way to lift data to root](https://front-end.social/@kizu/113732033335417449) and for providing a firefox precision fix in the compat version.\n\n[T. Afif](https://front-end.social/@css) for [this article](https://frontendmasters.com/blog/how-to-get-the-width-height-of-any-element-in-only-css/) demonstrating the concept of using view timelines as a better way to measure and pass around element sizes instead of using my own [tan(atan2())](https://dev.to/janeori/css-type-casting-to-numeric-tanatan2-scalars-582j) approach to do it.\n\n[Bramus](https://x.com/bramus) for writing many articles on scroll and view timelines and building [amazing tools](https://scroll-driven-animations.style/tools/view-timeline/ranges/) so I could learn what I needed to make it uniquely and accurately work for this.\n\n## Open Contact 👽\n\nPlease do reach out if you need help with any of this, have feature requests, want to share what you've created, or wish to learn more.\n\n| PropJockey.io | CodePen | DEV Blog | GitHub | Mastodon |\n| --- | --- | --- | --- | --- |\n| [![PropJockey.io](https://raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/propjockey-lines.svg)](https://propjockey.io) | [![CodePen](https://raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/codepen.svg)](https://codepen.io/propjockey) | [![DEV Blog](https://raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/dev.svg)](https://dev.to/janeori) | [![GitHub](https://raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/github.svg)](https://github.com/propjockey) | [![Mastodon](https://raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/mastodon.svg)](https://front-end.social/@JaneOri) |\n\n\n[🦋@JaneOri.PropJockey.io](https://bsky.app/profile/janeori.propjockey.io)\n\n[𝕏@Jane0ri](https://x.com/jane0ri)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpropjockey%2Fcss-api-fetch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpropjockey%2Fcss-api-fetch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpropjockey%2Fcss-api-fetch/lists"}