[{"data":1,"prerenderedAt":255},["ShallowReactive",2],{"DefaultLayouten":3,"language-blog-slug-the-popover-api-your-new-best-friend-for-tooltips-i18n-slugs":134,"language-blog-slug-en-the-popover-api-your-new-best-friend-for-tooltips":140},{"app":4,"menu":31,"footer":66},{"githubUrl":5,"youtubeUrl":6,"linkedinUrl":7,"phoneNumber":8,"emailAddress":9,"legal":10,"addresses":20},"https:\u002F\u002Fgithub.com\u002Fvoorhoede\u002F","https:\u002F\u002Fwww.youtube.com\u002Fchannel\u002FUCzHuhQVYFRixtQN2-swcuGg","https:\u002F\u002Fwww.linkedin.com\u002Fcompany\u002Fde-voorhoede","+31 20 2610 954","post@voorhoede.nl",[11,14,17],{"title":12,"value":13},"KvK","56017235",{"title":15,"value":16},"BTW","NL851944620B01",{"title":18,"value":19},"IBAN","NL14TRIO0320142078",[21,26],{"address":22,"city":23,"googleMapsLink":24,"postalCode":25},"Koivistokade 70","Amsterdam","https:\u002F\u002Fwww.google.com\u002Fmaps\u002Fplace\u002FDe+Voorhoede+%7C+Front-end+Development\u002F@52.396847,4.8700823,17z\u002Fdata=!3m1!4b1!4m5!3m4!1s0x47c5e21d502d2d59:0xbf570944a96ebf45!8m2!3d52.347647!4d4.8502154","1013 BB",{"address":27,"city":28,"googleMapsLink":29,"postalCode":30},"Koornmarkt 22","Delft","https:\u002F\u002Fwww.google.nl\u002Fmaps\u002Fplace\u002FKoornmarkt+22,+2611+EG+Delft\u002F@52.0093477,4.3573054,17z\u002F","2611 EG",{"title":32,"callToActions":33,"links":39},"Site Menu",[34],{"id":35,"title":36,"link":37},"163140902","Contact",{"__typename":38},"ContactRecord",[40,46,51,56,61],{"id":41,"title":42,"link":43},"163140904","Impact",{"__typename":44,"slug":45},"PageRecord","impact",{"id":47,"title":48,"link":49},"163140905","Services",{"__typename":50},"ServiceOverviewRecord",{"id":52,"title":53,"link":54},"163140906","Cases",{"__typename":55},"CaseOverviewRecord",{"id":57,"title":58,"link":59},"163140908","About us",{"__typename":44,"slug":60},"about-us",{"id":62,"title":63,"link":64},"d6WdFJq2SOuc3dWtpibbXQ","Work at",{"__typename":44,"slug":65},"work-at",{"links":67,"copyrightTitle":93,"copyrightLabel":94,"copyrightLink":95,"privacyTitle":96,"privacyLabel":97,"privacyLink":98,"certificatesGrid":99},[68,71,74,77,82,85,88],{"id":69,"title":42,"link":70},"144185264",{"__typename":44,"slug":45},{"id":72,"title":48,"link":73},"144185265",{"__typename":50},{"id":75,"title":53,"link":76},"144185266",{"__typename":55},{"id":78,"title":79,"link":80},"144185267","Blog",{"__typename":81},"BlogPostOverviewRecord",{"id":83,"title":58,"link":84},"144185268",{"__typename":44,"slug":60},{"id":86,"title":36,"link":87},"144185269",{"__typename":38},{"id":89,"title":90,"link":91},"144185270","FAQ",{"__typename":44,"slug":92},"faq","Creative Commons licence and disclaimer","CC BY 4.0","https:\u002F\u002Fcreativecommons.org\u002Flicenses\u002Fby\u002F4.0\u002F","De Voorhoede privacy statement (pdf)","Privacy statement","https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1763455455-vh-isms-006-privacy-statement-de-voorhoede-en.pdf",[100,112,123],{"id":101,"image":102,"link":107},"Xq4bBfg_TZ6Fkjax9mkbLQ",{"url":103,"alt":104,"width":105,"height":106},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1687353463-b-corp-logo-black-rgb.png","B Corp logo",404,680,{"__typename":108,"id":109,"title":110,"url":111},"ExternalLinkRecord","fGW1ak8XQYaYDLkBSyncog","B Corp","https:\u002F\u002Fwww.bcorporation.net\u002Fen-us\u002Ffind-a-b-corp\u002Fcompany\u002Fde-voorhoede\u002F",{"id":113,"image":114,"link":119},"c5mCXRTiSraRIB25fw1p7Q",{"url":115,"alt":116,"width":117,"height":118},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1687353461-dda-boxlogo-black.png","Dutch Digital Agencies logo",627,480,{"__typename":108,"id":120,"title":121,"url":122},"P6Jh7B0cTv2cKyNEeKVWVQ","Dutch Digital Agencies","https:\u002F\u002Fdutchdigitalagencies.com\u002Fleden\u002Fde-voorhoede\u002F",{"id":124,"image":125,"link":129},"MT5SCyNxSTSr_v5eeATMZw",{"url":126,"alt":127,"width":128,"height":128},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1775730283-dnv.png","DNV logo",518,{"id":130,"title":131,"link":132},"BRtNB5HnT5i-7HkA8IYzBw","DIV",{"__typename":44,"slug":133},"impact\u002Fdigitale-producten-privacy-by-design",[135,138],{"locale":136,"value":137},"en","the-popover-api-your-new-best-friend-for-tooltips",{"locale":139,"value":137},"nl",{"page":141},{"slug":137,"i18nSlugs":142,"social":145,"title":146,"subtitle":79,"isArchived":149,"headerIllustration":150,"date":154,"authors":155,"introTitle":164,"items":165,"pivots":252,"relatedBlogPosts":253,"tags":254,"onMountedScript":169,"onUnmountedScript":169},[143,144],{"locale":136,"value":137},{"locale":139,"value":137},{"title":146,"description":147,"image":148},"The Popover API: Your New Best Friend for Tooltips","Discover how the Popover API and new CSS features simplify tooltip creation, making them accessible and well-positioned across all major browsers",null,false,{"url":151,"alt":148,"width":152,"height":153},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1726231675-20240808-clippy-deal.svg",639,545,"2024-10-07T15:36:10.707+02:00",[156],{"name":157,"lastName":158,"slug":159,"image":160},"Sjoerd","Beentjes","sjoerd",{"url":161,"alt":148,"width":162,"height":163},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1683534892-sjoerd.jpg",1637,2182,"Effortless Tooltip Creation with the Popover API and New CSS Features",[166,171,175,185,189,193,198,201,209,213,217,221,225,228,231,239,242,248],{"__typename":167,"id":168,"title":169,"body":170},"TextSectionRecord","Ap9OC_80S-GfOVjQq3a8ow","","\u003Cp>I've often struggled with making tooltips that not only look good but also work well across different browsers and screen sizes. In one of my recent projects, I spent hours fixing rendering bugs and tweaking code to ensure the tooltip looked and worked perfectly. That's when I discovered the Popover API, which made everything so much easier.\u003C\u002Fp>\n\u003Cp>\u003Cspan style=\"font-weight: 400;\">The Popover API, supported by all major browsers, simplifies tooltip creation. In addition, new CSS features like \u003C\u002Fspan>\u003Cspan style=\"font-weight: 400;\">\u003Ccode>anchor\u003C\u002Fcode> \u003C\u002Fspan>\u003Cspan style=\"font-weight: 400;\">and \u003C\u002Fspan>\u003Ccode>\u003Cspan style=\"font-weight: 400;\">@\u003C\u002Fspan>\u003Cspan style=\"font-weight: 400;\">position-try\u003C\u002Fspan>\u003C\u002Fcode>\u003Cspan style=\"font-weight: 400;\"> provide more control over tooltip placement and behaviour, enabling customisation and delivering a smooth user experience. \u003C\u002Fspan>\u003Cspan style=\"font-weight: 400;\">So, how do these new tools make implementing tooltips easier? Let&rsquo;s take a closer look.\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":167,"id":172,"title":173,"body":174},"R-UoCnB1Tg6G9fDoE56o8A","The Challenges of Creating Tooltips","\u003Cp>\u003Cspan style=\"font-weight: 400;\">Implementing tooltips is more complex than it might seem at first glance. Developers need to handle various UI issues, such as:\u003C\u002Fspan>\u003C\u002Fp>\n\u003Col>\n\u003Cli style=\"font-weight: 400;\" aria-level=\"1\">\u003Cspan style=\"font-weight: 400;\">Properly associating the tooltip with its triggering element\u003C\u002Fspan>\u003C\u002Fli>\n\u003Cli style=\"font-weight: 400;\" aria-level=\"1\">\u003Cspan style=\"font-weight: 400;\">Preventing the tooltip from appearing in awkward positions\u003C\u002Fspan>\u003C\u002Fli>\n\u003Cli style=\"font-weight: 400;\" aria-level=\"1\">\u003Cspan style=\"font-weight: 400;\">Ensuring the tooltip doesn't get clipped by the viewport\u003C\u002Fspan>\u003C\u002Fli>\n\u003Cli style=\"font-weight: 400;\" aria-level=\"1\">\u003Cspan style=\"font-weight: 400;\">Including necessary ARIA attributes for accessibility\u003C\u002Fspan>\u003C\u002Fli>\n\u003C\u002Fol>",{"__typename":176,"id":177,"image":178,"caption":183,"fullWidth":149,"captionPosition":184},"ImageRecord","OTWmllSTQruhdKw30MojYg",{"url":179,"alt":180,"width":181,"height":182},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1726231099-image1.png","Examples of tooltips and popovers rendering in the wrong place",1715,1579,"Examples of how a tooltip can end up looking weird","bottom",{"__typename":167,"id":186,"title":187,"body":188},"B3RkbjzbTnmzkGIsTn8xLg","Understanding the Popover API","\u003Cp>\u003Cspan style=\"font-weight: 400;\">The Popover API addresses these challenges by providing a standardised way to display popover content on top of other page content. This API allows developers to handle popovers declaratively with HTML attributes or programmatically via JavaScript, which is a significant improvement over traditional methods.\u003C\u002Fspan>\u003C\u002Fp>\n\u003Cp>\u003Cspan style=\"font-weight: 400;\">The Popover API is versatile and can be used for various purposes, including:\u003C\u002Fspan>\u003C\u002Fp>\n\u003Col>\n\u003Cli style=\"font-weight: 400;\" aria-level=\"1\">\u003Cspan style=\"font-weight: 400;\">Tooltips\u003C\u002Fspan>\u003C\u002Fli>\n\u003Cli style=\"font-weight: 400;\" aria-level=\"1\">\u003Cspan style=\"font-weight: 400;\">Complex user-interactive elements like action menus\u003C\u002Fspan>\u003C\u002Fli>\n\u003Cli style=\"font-weight: 400;\" aria-level=\"1\">\u003Cspan style=\"font-weight: 400;\">Custom toast notifications\u003C\u002Fspan>\u003C\u002Fli>\n\u003C\u002Fol>",{"__typename":167,"id":190,"title":191,"body":192},"AWtSG_gxQimuhXPLYvCd1g","Implementing the Popover API","\u003Cp>\u003Cspan style=\"font-weight: 400;\">Here's a basic example of how easy it is to get started:\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":194,"id":195,"language":196,"body":197},"CodeBlockRecord","IWR3MQEzRwOE1OfmRygvvA","html","\u003Cbutton id=\"popover-trigger\" popovertarget=\"popover\">More information\u003C\u002Fbutton>\n\n\u003Cdiv id=\"popover\" popover>\n    Why we need this: We'll send order confirmations and important updates to this email address. Make sure to use an address you check regularly.\n\u003C\u002Fdiv>",{"__typename":167,"id":199,"title":169,"body":200},"MWABNm-YQsilMHUAlQ9XIQ","\u003Cp>\u003Cspan style=\"font-weight: 400;\">This snippet creates a simple tooltip that displays additional information when triggered. It will work out of the box, although the styling leaves something to be desired.\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":176,"id":202,"image":203,"caption":208,"fullWidth":149,"captionPosition":184},"ZSu-IV9kSXqSfs7IKrSsUg",{"url":204,"alt":205,"width":206,"height":207},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1726231308-image2.png","An unstyled example of using the Popover API in HTML",1018,454,"Default look of the popover in most browsers",{"__typename":167,"id":210,"title":211,"body":212},"TZ6N_8EIR1GGRVRByBSpKA","Positioning Tooltips with CSS","\u003Cp>\u003Cspan style=\"font-weight: 400;\">One of the challenges with tooltips is positioning them relative to their trigger element. This calculation involves considering several factors, such as:\u003C\u002Fspan>\u003C\u002Fp>\n\u003Col>\n\u003Cli style=\"font-weight: 400;\" aria-level=\"1\">\u003Cspan style=\"font-weight: 400;\">On which side of the trigger should the tooltip be rendered?\u003C\u002Fspan>\u003C\u002Fli>\n\u003Cli style=\"font-weight: 400;\" aria-level=\"1\">\u003Cspan style=\"font-weight: 400;\">Where is the centre of the tooltip relative to the centre of the trigger?\u003C\u002Fspan>\u003C\u002Fli>\n\u003Cli style=\"font-weight: 400;\" aria-level=\"1\">\u003Cspan style=\"font-weight: 400;\">Is there enough room to render the tooltip?\u003C\u002Fspan>\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>\u003Cspan style=\"font-weight: 400;\">Implementing this in JavaScript can result in a large amount of code. However, with the Popover API and new CSS features, we can achieve the same effect with much less code:\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":194,"id":214,"language":215,"body":216},"d0b5niZtTNuH9GYdwaQtSA","css","#popover-trigger {\n  anchor-name: --popover-trigger;\n}\n\n#popover {\n  position: absolute;\n  max-width: 250px;\n  min-width: 200px;\n  position-anchor: --popover-trigger;\n  inset-area: right;\n}",{"__typename":194,"id":218,"language":219,"body":220},"OAR7N2gWRGiCqWXpPdDKkQ","javascript","const popover = document.querySelector(\"[popover]\");\nconst trigger = document.querySelector(\"[popovertarget]\");\n\ntrigger.addEventListener(\"mouseenter\", (event) => {\n  popover.showPopover();\n});\n\ntrigger.addEventListener(\"mouseleave\", (event) => {\n  popover.hidePopover();\n});",{"__typename":167,"id":222,"title":223,"body":224},"RRyDUACsTB-Ti1DgCb4h5Q","Handling Viewport Overflow","\u003Cp>\u003Cspan style=\"font-weight: 400;\">To ensure the tooltip behaves correctly when it doesn't fit within the viewport, we can use a combination of the \u003C\u002Fspan>\u003Ccode>\u003Cspan style=\"font-weight: 400;\">position-try\u003C\u002Fspan>\u003C\u002Fcode>\u003Cspan style=\"font-weight: 400;\"> rule and the \u003C\u002Fspan>\u003Ccode>\u003Cspan style=\"font-weight: 400;\">@position-try\u003C\u002Fspan>\u003C\u002Fcode>\u003Cspan style=\"font-weight: 400;\"> at-rule:\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":194,"id":226,"language":215,"body":227},"MymkE0AXTX-e6zFtiWi3dQ","#popover {\n  ...\n  --margin: 8px;\n  max-width: 250px;\n  min-width: 200px;\n  margin: var(--margin);\n  position-anchor: --popover-trigger;\n  inset-area: right;\n  position-try-options: --bottom;\n}\n\n@position-try --bottom {\n  margin: var(--margin);\n  inset-area: bottom;\n}",{"__typename":167,"id":229,"title":169,"body":230},"Q_jS-I5RRq26aLQkBJFE9g","\u003Cp>\u003Cspan style=\"font-weight: 400;\">Here's what each property does:\u003C\u002Fspan>\u003C\u002Fp>\n\u003Cp>\u003C\u002Fp>\n\u003Cul>\n\u003Cli style=\"font-weight: 400;\" aria-level=\"1\">\u003Ccode>\u003Cb>position-anchor: --popover-trigger;\u003C\u002Fb>\u003C\u002Fcode>\u003Cspan style=\"font-weight: 400;\">: Anchors the tooltip to the triggering element using a custom anchor point.\u003C\u002Fspan>\u003C\u002Fli>\n\u003Cli style=\"font-weight: 400;\" aria-level=\"1\">\u003Ccode>\u003Cb>inset-area: right;\u003C\u002Fb>\u003C\u002Fcode>\u003Cspan style=\"font-weight: 400;\">: Initially positions the tooltip to the right of the trigger element.\u003C\u002Fspan>\u003C\u002Fli>\n\u003Cli style=\"font-weight: 400;\" aria-level=\"1\">\u003Ccode>\u003Cb>position-try-options: --bottom;\u003C\u002Fb>\u003C\u002Fcode>\u003Cspan style=\"font-weight: 400;\">: Tells the browser to try an alternative position if the tooltip would overflow the viewport.\u003C\u002Fspan>\u003C\u002Fli>\n\u003Cli style=\"font-weight: 400;\" aria-level=\"1\">\u003Ccode>\u003Cb>@position-try --bottom { ... }\u003C\u002Fb>\u003C\u002Fcode>\u003Cspan style=\"font-weight: 400;\">: Defines what should happen when the tooltip needs to be repositioned, moving it to the bottom of the trigger element with the same margin.\u003C\u002Fspan>\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cspan style=\"font-weight: 400;\">With some additional styling, the result looks like this:\u003C\u002Fspan>\u003C\u002Fp>",{"__typename":176,"id":232,"image":233,"caption":238,"fullWidth":149,"captionPosition":184},"JTX7JzarTxm5og6TNWSHMw",{"url":234,"alt":235,"width":236,"height":237},"https:\u002F\u002Fwww.datocms-assets.com\u002F6524\u002F1726231477-image3.gif","An animated GIF that shows the tooltip moving to the bottom of the element when it doesn't fit in the viewport anymore",774,398,"How the tooltip behaves when it overflows the viewport",{"__typename":167,"id":240,"title":169,"body":241},"cpMLZgWaSqKsYcCz_LOY9w","\u003Cp>Final result:\u003C\u002Fp>",{"__typename":243,"id":244,"url":245,"title":246,"caption":169,"previewType":247},"CodePenBlockRecord","DDB3EqMQQ3uF_wXW2zBHFw","https:\u002F\u002Fcodepen.io\u002Fsjoerdb\u002Fpen\u002FMWMGbmQ","Popover Demo","codepen",{"__typename":167,"id":249,"title":250,"body":251},"XNPLKU9qRiOOLMoc9KxWVA","Conclusion","\u003Cp>\u003Cspan style=\"font-weight: 400;\">The Popover API and new CSS features greatly simplify the process of creating and managing tooltips and popovers. It handles the complexities of managing popovers, ensuring they are accessible and properly positioned. The new CSS features, like \u003Ccode>anchor\u003C\u002Fcode> and \u003Ccode>@position-fallback\u003C\u002Fcode>, provide additional customisation options for fine-tuning the placement and behaviour of popovers.\u003C\u002Fspan>\u003C\u002Fp>\n\u003Cp>\u003Cspan style=\"font-weight: 400;\">However, it's important to check the browser support for these features, especially the CSS properties, as they may not be supported in all browsers yet. \u003C\u002Fspan>\u003Ca href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FCSS\u002Fposition-anchor\">\u003Cspan style=\"font-weight: 400;\">Please check MDN\u003C\u002Fspan>\u003C\u002Fa>\u003Cspan style=\"font-weight: 400;\"> for the latest information and consider using progressive enhancement techniques when necessary.\u003C\u002Fspan>\u003C\u002Fp>\n\u003Cp>\u003Cspan style=\"font-weight: 400;\">Overall, the Popover API and related CSS features are valuable tools for creating user-friendly and accessible tooltips and popovers. As browser support improves, we can expect to see more widespread adoption of these features. \u003C\u002Fspan>\u003Cspan style=\"font-weight: 400;\">Personally, I&rsquo;m excited to start using this and finally leave behind all those npm packages and custom workarounds!\u003C\u002Fspan>\u003C\u002Fp>",[],[],[],1776256139065]