如何使用CSS相对于外部容器定位工具提示和箭头

huangapple go评论48阅读模式
英文:

How to position tooltip and arrow relative to outer container with CSS

问题

I have a document split into three columns. I have images inside A or SPAN in the left and right columns, and text in the middle column. I have classes L and R for the outer columns.

我有一个文档分成三列。左列和右列中有包含在A或SPAN中的图像,中间列中有文本。外部列具有类别L和R。

I want tooltips in the left column to be flush with the left edges of the images, with the arrows centered above the images.

我希望左列中的工具提示与图像的左边缘对齐,并且箭头位于图像正上方。

I want tooltips in the center column to be centered on the A, DIV, or SPAN, with the arrow centered on the text.

我希望中间列中的工具提示居中于A、DIV或SPAN上,箭头位于文本的中心。

I want tooltips in the right column to be flush with the right edges of the images, with the arrows centered above the images.

我希望右列中的工具提示与图像的右边缘对齐,并且箭头位于图像正上方。

The positioning of the arrow is relative to its immediate container, but I need to make it relative to the grandfather rather than the father. I thought of using calc(), but I don't know how to capture the absolute container boundaries. Is there a way to do this in CSS?

箭头的定位是相对于其直接容器的,但我需要使其相对于祖父而不是父级。我考虑使用calc(),但我不知道如何捕捉绝对容器边界。CSS 中是否有方法可以实现这一点?

英文:

I have a document split into three columns. I have images inside A or SPAN in the left and right columns, and text in the middle column. I have classes L and R for the outer columns.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

&lt;!DOCTYPE HTML&gt;
&lt;html lang=en&gt;
&lt;head&gt;
        &lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=utf-8&quot;&gt;
        &lt;TITLE&gt;favorite things&lt;/TITLE&gt;
        &lt;META name=&quot;KEYWORDS&quot; CONTENT=&quot;filk&quot;&gt;
        &lt;style&gt;
            p        {
                       left:20%;
                       position:relative;
                       right:-20%;
                       margin-left:2em;
                       width:60%;
                     }

            p.drop   {
                       margin-left:2em;
                     }

            p.drop::first-letter  {
                       font-size:2em;
                       margin-left:-2em;
                     }

            a.L,div.L,span.L {
                       display:inline;
                       --width:14%;
                       width:var(--width);
                       position:absolute;
                       left:-20%;
                     }

            a.R,div.R,span.R {
                       display:inline;
                       --width:14%;
                       width:var(--width);
                       position:absolute;
                       right:00%;
                     }

            h1       {
                       text-align:center;
                       font-size:4em;
                     }

            img.V    {
                       display:block;
                       height:auto;
                       margin:10% 10% 10% 10%;
                       max-width:90%;
                       width:100%;
                     }

           /* Tooltip container */
          .tooltip {
            position: relative;
            display: inline-block;
            border-bottom: 1px dotted black; /* If you want dots under the hoverable text */
          }

          /* Tooltip text */
          .tooltip .tooltiptext {
            visibility: hidden;
            width: 120px;
            background-color: #555;
            color: #fff;
            text-align: center;
            padding: 5px 0;
            border-radius: 6px;

            /* Position the tooltip text */
            position: absolute;
            z-index: 1;
            bottom: 102%;
            left: -25%;
            margin-left: -40%;
            Min-width: 20em;
            max-width: 70em;

            /* Fade in tooltip */
            opacity: 0;
            transition: opacity 0.3s;
          }

          .L .tooltiptext {
            left:  -25%;
            text-align: left;
          }

          .R  .tooltiptext {
            right: 0%;
            text-align: left;
          }

          /* Tooltip arrow */
          .tooltip .tooltiptext::after {
            content: &quot;&quot;;
            position: absolute;
            top: 100%;
            left: 50%;
            margin-left: -5px;
            border-width: 5px;
            border-style: solid;
            border-color: #555 transparent transparent transparent;
            width: 1px;
          }

          .L .tooltiptext::after {
            left: calc(--width * (2/3));
          }

          .R .tooltiptext::after {
            left: 30%;
          }

          /* Show the tooltip text when you mouse over the tooltip container */
          .tooltip:hover .tooltiptext {
            visibility: visible;
            opacity: 1;
          }

          .verse     {
            font-size: 2em;
            text-align: center;
            width:60%
          }
        &lt;/style&gt;
&lt;/head&gt;
&lt;BODY LANG=&quot;en-US&quot; DIR=&quot;LTR&quot;&gt;
&lt;H1&gt;My favorite things&lt;/H1&gt;

&lt;p&gt;
[Verse]
&lt;/p&gt;
&lt;p class=&quot;drop verse&quot;&gt;
Gardening
&lt;a class=tooltip href=&quot;https://en.wikipedia.org/wiki/Ungoliant&quot;&gt;
   spiders
   &lt;span class=tooltiptext&gt;
     Ungoliant, who took the form of a giant spider and, along with Dark Lord Melkor, destroyed the Two Trees of Valinor
   &lt;/span&gt;
&lt;/a&gt;
&lt;a class=L href=&quot;https://en.wikipedia.org/wiki/The_Silmarillion&quot;&gt;
&lt;img class=V src=&quot;../Images/Silmarillion.png&quot;
             alt=&quot;The Silmarillion&quot;&gt;
&lt;/a&gt;
&lt;br&gt;
&lt;a class=&quot;R tooltip&quot; href=&quot;https://en.wikipedia.org/wiki/The_Fellowship_of_the_Ring&quot;&gt;
  &lt;img class=V src=&quot;https://upload.wikimedia.org/wikipedia/en/8/8e/The_Fellowship_of_the_Ring_cover.gif&quot;
               alt=&quot;The Fellowship of the Ring&quot;&gt;
  &lt;span class=tooltiptext&gt;
     Elendil&amp;apos;s sword Narsil, called &lt;q&gt;The Sword that was Broken&lt;/q&gt; after
     its damage in a battle against Sauron, and later caried by
     Aragorn (&lt;q&gt;Strider&lt;/q&gt;).
  &lt;/span&gt;
&lt;/a&gt;
And
&lt;a class=tooltip href=&quot;https://en.wikipedia.org/wiki/Middle-earth_weapons_and_armour#Narsil&quot;&gt;
  swords that are broken
  &lt;span class=tooltiptext&gt;
     Elendil&amp;apos;s sword Narsil, called &lt;q&gt;The Sword that was Broken&lt;/q&gt; after
     its damage in a battle against Sauron, and later caried by
     Aragorn (&lt;q&gt;Strider&lt;/q&gt;).
  &lt;/span&gt;
&lt;/a&gt;
&lt;br&gt;
Words in the
&lt;a class=tooltip href=&quot;https://en.wikipedia.org/wiki/Black_Speech&quot;&gt;
  Black Speech
  &lt;span class=tooltiptext&gt;
    The Black Speech of Mordor is a language constructed by Sauron.
  &lt;/span&gt;
&lt;/a&gt;
&lt;br&gt;
That must not be spoken
&lt;br&gt;
&lt;a class=tooltip href=&quot;https://en.wikipedia.org/wiki/Denethor&quot;&gt;
  Unfaithful stewards
  &lt;span class=tooltiptext&gt;
    Denethor, the 26th ruling Steward of Gondor.
  &lt;/span&gt;
&lt;/a&gt;
&lt;br&gt;
&lt;a class=&quot;L tooltip&quot; href=&quot;https://en.wikipedia.org/wiki/The_Return_of_the_King&quot;&gt;
  &lt;img class=V src=&quot;../Images/81UzbZbGPUL._SL1500_.jpg&quot;
               alt=&quot;The Return of the King&quot;&gt;
  &lt;span class=tooltiptext&gt;
    Denethor, the 26th ruling Steward of Gondor.
  &lt;/span&gt;
&lt;/a&gt;
Who don&#39;t want their kings
&lt;br&gt;
These are a few of
&lt;br&gt;
My favorite things.
&lt;/p&gt;
&lt;/BODY&gt;
&lt;/HTML&gt;

<!-- end snippet -->

I want tooltips in the left column to be flush with the left edges of the images, with the arrows centered above the images.

I want tooltips in the center column to be centered on the A, DIV or SPAN, with the arrow centered on the text.

I want tooltips in the right column to be flush with the right edges of the images, with the arrows centered above the images.

The positioning of the arrow is relative to its immediate container, but I need to make it relative to the grandfather rather than the father. I thought of using calc(), but I don't know how to capture the absolute container boundaries. Is there a way to do this in CSS?

答案1

得分: 1

为了将工具提示和指针居中在元素上方,我认为您需要使用JavaScript来获取元素的宽度,并相应地应用定位声明。

在发布了我的答案后,我偶然读到了一篇关于 CSS容器查询 的文章,想知道它是否可以用于此目的。事实上,我成功地实现了它,甚至不需要使用 @container at-rule。

要使工具提示和指针居中在中心列的元素上方,请计算工具提示宽度的一半与包含元素宽度的一半的负值,对于这种情况,可以使用 left: calc(-10em + 50%);

要将工具提示定位在左侧或右侧边缘,您只需要相应的左侧和/或右侧声明(在这种情况下,用于覆盖现有声明)。left: 0; / left: auto; right: 0;

要将指针居中在左侧和右侧列的元素上方,请为包含元素声明一个容器上下文,并使用容器查询长度单位来定位指针。50cqw 是查询容器宽度的50%。left: 50cqw;(请记住,容器的宽度包括容器内部元素的边距、填充和边框,即子元素)。

我修改了您的CSS以帮助您朝着正确的方向前进。我的修改使用了 /* <- */ 进行标注。

英文:

To center the tooltip and the pointer above the element, <strike>I think you'll need to use JavaScript to get the element's width and apply positioning declarations accordingly.</strike>

After posting my answer, I happened to read an article about CSS container queries and wondered if it could be used for this purpose. Indeed, I was successful in implementing it without even needing to use the @container at-rule.<hr>

To center the tooltip and the pointer above the elements in the center column, calculate a negative value of half the width of the tooltip plus half the width of the containing element, which in this case is left: calc(-10em + 50%);.

To position the tooltip to be flush with the left or right edge, you just need the appropriate left and/or right declarations (in this case, to overwrite the existing declarations.) left: 0; / left: auto; right: 0;

To center the pointer above the elements in the left and right columns, declare a containment context with container-type: inline-size; for the containing elements and then position the pointer using container query length units. 50cqw is 50% of the query container's width. left: 50cqw; (Keep in mind that the width of the container includes margin, padding, and borders on the elements inside the container, i.e. child elements.)

I altered your CSS to help get you going in the right direction. My modifications are indicated with /* &lt;- */

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

&lt;!DOCTYPE HTML&gt;
&lt;html lang=en&gt;
&lt;head&gt;
        &lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=utf-8&quot;&gt;
        &lt;TITLE&gt;favorite things&lt;/TITLE&gt;
        &lt;META name=&quot;KEYWORDS&quot; CONTENT=&quot;filk&quot;&gt;
        &lt;style&gt;
            p        {
                       left:20%;
                       position:relative;
                       right:-20%;
                       margin-left:2em;
                       width:60%;
                     }

            p.drop   {
                       margin-left:2em;
                     }

            p.drop::first-letter  {
                       font-size:2em;
                       margin-left:-2em;
                     }

            a.L,div.L,span.L,a.R,div.R,span.R { /* &lt;- */
                       display:inline;
                       --width:14%;
                       width:var(--width);
                       position:absolute;
                       container-type: inline-size; /* &lt;- */
                     }

            a.L,div.L,span.L { /* &lt;- */
                       left:-20%;
                     }

            a.R,div.R,span.R { /* &lt;- */
                       right:0;
                     }

            h1       {
                       text-align:center;
                       font-size:4em;
                     }

            img.V    {
                       display:block;
                       height:auto;
                       /* margin:10% 10% 10% 10%; */ /* &lt;- */
                       /* max-width:90%; */ /* &lt;- */
                       width:100%;
                       margin-top: 10%; /* &lt;- */
                     }

           /* Tooltip container */
          .tooltip {
            position: relative;
            display: inline-block;
            border-bottom: 1px dotted black; /* If you want dots under the hoverable text */
          }

          /* Tooltip text */
          .tooltip .tooltiptext {
            visibility: hidden;
            /* width: 120px; */ /* &lt;- */
            width: 20em; /* &lt;- */
            background-color: #555;
            color: #fff;
            text-align: center;
            padding: 5px 0;
            border-radius: 6px;

            /* Position the tooltip text */
            position: absolute;
            z-index: 1;
            bottom: 102%;
            left: calc(-10em + 50%); /* &lt;- */
            /* left: -25%; */ /* &lt;- */
            /* margin-left: -40%; */ /* &lt;- */
            /* Min-width: 20em; */ /* &lt;- */
            /* max-width: 70em; */ /* &lt;- */

            /* Fade in tooltip */
            opacity: 0;
            transition: opacity 0.3s;
          }

          .L .tooltiptext {
            left: 0; /* &lt;- */
            /* left:  -25%; */ /* &lt;- */
            text-align: left;
          }

          .R  .tooltiptext {
            left: auto; /* &lt;- */
            right: 0%;
            text-align: left;
          }

          /* Tooltip arrow */
          .tooltip .tooltiptext::after {
            content: &quot;&quot;;
            position: absolute;
            top: 100%;
            left: 50%;
            margin-left: -5px;
            border-width: 5px;
            border-style: solid;
            border-color: #555 transparent transparent transparent;
            width: 1px;
          }

          .L .tooltiptext::after {
            /* left: calc(--width * (2/3)); */ /* &lt;- */
            left: 50cqw; /* &lt;- */
          }

          .R .tooltiptext::after {
            /* left: 30%; */ /* &lt;- */
            left: auto; /* &lt;- */
            right: 50cqw; /* &lt;- */
          }

          /* Show the tooltip text when you mouse over the tooltip container */
          .tooltip:hover .tooltiptext {
            visibility: visible;
            opacity: 1;
          }

          .verse     {
            font-size: 2em;
            text-align: center;
            width:60%
          }
        &lt;/style&gt;
&lt;/head&gt;
&lt;BODY LANG=&quot;en-US&quot; DIR=&quot;LTR&quot;&gt;
&lt;H1&gt;My favorite things&lt;/H1&gt;

&lt;p&gt;
[Verse]
&lt;/p&gt;
&lt;p class=&quot;drop verse&quot;&gt;
Gardening
&lt;a class=tooltip href=&quot;https://en.wikipedia.org/wiki/Ungoliant&quot;&gt;
   spiders
   &lt;span class=tooltiptext&gt;
     Ungoliant, who took the form of a giant spider and, along with Dark Lord Melkor, destroyed the Two Trees of Valinor
   &lt;/span&gt;
&lt;/a&gt;
&lt;a class=L href=&quot;https://en.wikipedia.org/wiki/The_Silmarillion&quot;&gt;
&lt;img class=V src=&quot;https://upload.wikimedia.org/wikipedia/en/thumb/d/db/Silmarillion.png/220px-Silmarillion.png&quot;
             alt=&quot;The Silmarillion&quot;&gt;
&lt;/a&gt;
&lt;br&gt;
&lt;a class=&quot;R tooltip&quot; href=&quot;https://en.wikipedia.org/wiki/The_Fellowship_of_the_Ring&quot;&gt;
  &lt;img class=V src=&quot;https://upload.wikimedia.org/wikipedia/en/8/8e/The_Fellowship_of_the_Ring_cover.gif&quot;
               alt=&quot;The Fellowship of the Ring&quot;&gt;
  &lt;span class=tooltiptext&gt;
     Elendil&amp;apos;s sword Narsil, called &lt;q&gt;The Sword that was Broken&lt;/q&gt; after
     its damage in a battle against Sauron, and later caried by
     Aragorn (&lt;q&gt;Strider&lt;/q&gt;).
  &lt;/span&gt;
&lt;/a&gt;
And
&lt;a class=tooltip href=&quot;https://en.wikipedia.org/wiki/Middle-earth_weapons_and_armour#Narsil&quot;&gt;
  swords that are broken
  &lt;span class=tooltiptext&gt;
     Elendil&amp;apos;s sword Narsil, called &lt;q&gt;The Sword that was Broken&lt;/q&gt; after
     its damage in a battle against Sauron, and later caried by
     Aragorn (&lt;q&gt;Strider&lt;/q&gt;).
  &lt;/span&gt;
&lt;/a&gt;
&lt;br&gt;
Words in the
&lt;a class=tooltip href=&quot;https://en.wikipedia.org/wiki/Black_Speech&quot;&gt;
  Black Speech
  &lt;span class=tooltiptext&gt;
    The Black Speech of Mordor is a language constructed by Sauron.
  &lt;/span&gt;
&lt;/a&gt;
&lt;br&gt;
That must not be spoken
&lt;br&gt;
&lt;a class=tooltip href=&quot;https://en.wikipedia.org/wiki/Denethor&quot;&gt;
  Unfaithful stewards
  &lt;span class=tooltiptext&gt;
    Denethor, the 26th ruling Steward of Gondor.
  &lt;/span&gt;
&lt;/a&gt;
&lt;br&gt;
&lt;a class=&quot;L tooltip&quot; href=&quot;https://en.wikipedia.org/wiki/The_Return_of_the_King&quot;&gt;
  &lt;img class=V src=&quot;https://upload.wikimedia.org/wikipedia/en/thumb/1/11/The_Return_of_the_King_cover.gif/220px-The_Return_of_the_King_cover.gif&quot;
               alt=&quot;The Return of the King&quot;&gt;
  &lt;span class=tooltiptext&gt;
    Denethor, the 26th ruling Steward of Gondor.
  &lt;/span&gt;
&lt;/a&gt;
Who don&#39;t want their kings
&lt;br&gt;
These are a few of
&lt;br&gt;
My favorite things.
&lt;/p&gt;
&lt;/BODY&gt;
&lt;/HTML&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年5月30日 01:28:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76359269.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定