如何避免在::after的bottom属性中使用特定的像素值

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

How to avoid using specific pixel value on bottom property for ::after

问题

I've got a banner that when hovered on displays an "underline" at the bottom of the container. Currently it's achieved using ::after and the functionality is perfect, but I don't like having to be so specific with the bottom: -65px, it feels a bit hacky and not truly responsive.

Is there a way I can avoid using specific px values for bottom in this use case?

body {
  margin: 0;
}

.banner {
  height: 150px;
  background-color: lightpink;
  display: flex;
  justify-content: center;
  align-items: center;
}

ul {
  display: flex;
  align-items: center;
  gap: 25px;
}

ul li {
  list-style: none;
}

ul li a {
  position: relative;
  text-decoration: none;
}

ul li a::after {
  position: absolute;
  bottom: -65px;
  left: 0;
  right: 0;
  width: 0%;
  content: '';
  color: transparent;
  background: black;
  height: 3px;
}

ul li a:hover::after,
ul li a:active::after {
  transition: all 0.2s;
  width: 100%;
}
<div class="banner">
  <ul>
    <li><a href="">Option 1</a></li>
    <li><a href="">Option 1</a></li>
    <li><a href="">Option 1</a></li>
  </ul>
</div>
英文:

I've got a banner that when hovered on displays an "underline" at the bottom of the container. Currently it's achieved using ::after and the functionality is perfect, but I don't like having to be so specific with the bottom: -65px, it feels a bit hacky and not truly responsive.

For example, if the banner was not exactly 150px, then the underline would be off.

Is there a way I can avoid using specific px values for bottom in this use case?

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

<!-- language: lang-css -->

body {
  margin: 0;
}

.banner {
  height: 150px;
  background-color: lightpink;
  display: flex;
  justify-content: center;
  align-items: center;
}

ul {
  display: flex;
  align-items: center;
  gap: 25px;
}

ul li {
  list-style: none;
}

ul li a {
  position: relative;
  text-decoration: none;
}

ul li a::after {
  position: absolute;
  bottom: -65px;
  left: 0;
  right: 0;
  width: 0%;
  content: &#39;&#39;;
  color: transparent;
  background: black;
  height: 3px;
}

ul li a:hover::after,
ul li a:active::after {
  transition: all 0.2s;
  width: 100%;
}

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

&lt;div class=&quot;banner&quot;&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;&quot;&gt;Option 1&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;&quot;&gt;Option 1&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;&quot;&gt;Option 1&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;

<!-- end snippet -->

答案1

得分: 1

以下是您要翻译的内容:

One possible approach would be to make the `a` elements take all the available height so you can specify `bottom: 0;` on the pseudo element like this:

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

<!-- language: lang-css -->
body {
  margin: 0;
}

.banner {
  height: 150px;
  background-color: lightpink;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: 10px;
}
.height-80 {
height: 80px;
}

ul {
  display: flex;
  align-items: stretch;
  gap: 25px;
  height: 100%;
  margin: 0;
}

ul li {
  list-style: none;
}

ul li a {
  display: block;
  height: 100%;
  position: relative;
  display: flex;
  align-items: center;
}

ul li a::after {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  width: 0%;
  content: &#39;&#39;;
  color: transparent;
  background: black;
  height: 3px;
}

ul li a:hover::after,
ul li a:active::after {
  transition: all 0.2s;
  width: 100%;
}

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

<div class="banner">
  <ul>
    <li><a href="">Option 1</a></li>
    <li><a href="">Option 1</a></li>
    <li><a href="">Option 1</a></li>
  </ul>
</div>

<div class="banner height-80">
  <ul>
    <li><a href="">Option 1</a></li>
    <li><a href="">Option 1</a></li>
    <li><a href="">Option 1</a></li>
  </ul>
</div>

<!-- end snippet -->

另一种方法是使用CSS变量来指定标题的高度,并相应地调整伪元素的位置。在以下示例中,您可以通过更改--banner-height: 150px;的值来更改横幅的高度,伪元素的定位也将相应地调整为margin-bottom: calc(var(--banner-height) / -2);(请注意,我还将bottom的值更改为50%)。

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

<!-- language: lang-css -->
:root {
  --banner-height: 150px;
}

body {
  margin: 0;
}

.banner {
  height: var(--banner-height);
  background-color: lightpink;
  display: flex;
  justify-content: center;
  align-items: center;
}

ul {
  display: flex;
  align-items: center;
  gap: 25px;
}

ul li {
  list-style: none;
}

ul li a {
  position: relative;
  text-decoration: none;
}

ul li a::after {
  position: absolute;
  bottom: 50%;
  left: 0;
  right: 0;
  width: 0%;
  margin-bottom: calc(var(--banner-height) / -2);
  content: &#39;&#39;;
  color: transparent;
  background: black;
  height: 3px;
}

ul li a:hover::after,
ul li a:active::after {
  transition: all 0.2s;
  width: 100%;
}

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

<div class="banner">
  <ul>
    <li><a href="">Option 1</a></li>
    <li><a href="">Option 1</a></li>
    <li><a href="">Option 1</a></li>
  </ul>
</div>

<!-- end snippet -->

希望这些翻译对您有所帮助!

英文:

One possible approach would be to make the a elements take all the available height so you can specify bottom: 0; on the pseudo element like this :

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

<!-- language: lang-css -->

body {
  margin: 0;
}

.banner {
  height: 150px;
  background-color: lightpink;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: 10px;
}
.height-80 {
height: 80px;
}

ul {
  display: flex;
  align-items: stretch;
  gap: 25px;
  height: 100%;
  margin: 0;
}

ul li {
  list-style: none;
}

ul li a {
  display: block;
  height: 100%;
  position: relative;
  display: flex; 
  align-items: center;
}

ul li a::after {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  width: 0%;
  content: &#39;&#39;;
  color: transparent;
  background: black;
  height: 3px;
}

ul li a:hover::after,
ul li a:active::after {
  transition: all 0.2s;
  width: 100%;
}

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

&lt;div class=&quot;banner&quot;&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;&quot;&gt;Option 1&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;&quot;&gt;Option 1&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;&quot;&gt;Option 1&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;

&lt;div class=&quot;banner height-80&quot;&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;&quot;&gt;Option 1&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;&quot;&gt;Option 1&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;&quot;&gt;Option 1&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;

<!-- end snippet -->

Another approach could be to use CSS variables to specify the height of the header and adapt the positioning of the pseudo element accordingly.

In the following example, you can change the height of the banner by changing the value of --banner-height: 150px; and the positioning of the pseudo element will adapt with margin-bottom: calc(var(--banner-height) / -2); (note that y also changed the value of bottom to 50%).

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

<!-- language: lang-css -->

:root {
  --banner-height: 150px;
}

body {
  margin: 0;
}

.banner {
  height: var(--banner-height);
  background-color: lightpink;
  display: flex;
  justify-content: center;
  align-items: center;
}

ul {
  display: flex;
  align-items: center;
  gap: 25px;
}

ul li {
  list-style: none;
}

ul li a {
  position: relative;
  text-decoration: none;
}

ul li a::after {
  position: absolute;
  bottom: 50%;
  left: 0;
  right: 0;
  width: 0%;
  margin-bottom: calc(var(--banner-height) / -2);
  content: &#39;&#39;;
  color: transparent;
  background: black;
  height: 3px;
}

ul li a:hover::after,
ul li a:active::after {
  transition: all 0.2s;
  width: 100%;
  width: 100%;
}

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

&lt;div class=&quot;banner&quot;&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;&quot;&gt;Option 1&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;&quot;&gt;Option 1&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;&quot;&gt;Option 1&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;

<!-- end snippet -->

答案2

得分: -3

以下是翻译好的内容:

整个 ::after 部分是不必要的。

您可以使用 border-bottom 声明:

body {
  margin: 0;
}

.banner {
  height: 150px;
  background-color: lightpink;
  display: flex;
  justify-content: center;
  align-items: center;
}

ul {
  display: flex;
  align-items: center;
  gap: 25px;
}

ul li {
  list-style: none;
}

ul li a {
  position: relative;
  text-decoration: none;
  border-bottom: solid 3px #00000000;
}

ul li a:hover {
  transition: all 0.2s;
  border-bottom: solid 3px black;
}

如您所见,结果会有所不同。您可以通过编辑 a 的高度来更改垂直位置。

这可能不是您寻找的,因为下划线不会滑出,而只会“出现”。

英文:

The whole ::after isn't nessecary.

You can use the border-bottom declaration:

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

<!-- language: lang-css -->

body {
  margin: 0;
}

.banner {
  height: 150px;
  background-color: lightpink;
  display: flex;
  justify-content: center;
  align-items: center;
}

ul {
  display: flex;
  align-items: center;
  gap: 25px;
}

ul li {
  list-style: none;
}

ul li a {
  position: relative;
  text-decoration: none;
  border-bottom: solid 3px #00000000;
}


ul li a:hover {
  transition: all 0.2s;
  border-bottom: solid 3px black;
}

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

&lt;div class=&quot;banner&quot;&gt;
  &lt;ul&gt;
    &lt;li&gt;
      &lt;a href=&quot;&quot;&gt;Option 1&lt;/a&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;a href=&quot;&quot;&gt;Option 2&lt;/a&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;a href=&quot;&quot;&gt;Option 3&lt;/a&gt;
    &lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;

<!-- end snippet -->

As you can see, the results will differ. You can change the vertical position by editing a's height.

This may be not what you're looking for, as the underline won't slide out, it will just "appear".

huangapple
  • 本文由 发表于 2023年5月11日 20:09:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76227517.html
匿名

发表评论

匿名网友

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

确定