【问题标题】:Can this be achieved without js?这可以不用js实现吗?
【发布时间】:2021-10-24 21:24:51
【问题描述】:

我有这个图片库,我想在没有 javascript 的情况下做。这可以在不使用javascript的情况下完成吗?只需要在鼠标悬停或类似的情况下更改全局即可。

function myFunction(imgs) {
  var expandImg = document.getElementById('expandedImg')
  var imgText = document.getElementById('imgtext')
  expandImg.src = imgs.src
  imgText.innerHTML = imgs.alt
  expandImg.parentElement.style.display = 'block'
}
* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: Arial;
}


/* The grid: Four equal columns that floats next to each other */

.column {
  float: left;
  width: 25%;
  padding: 10px;
}


/* Style the images inside the grid */

.column img {
  opacity: 0.8;
  cursor: pointer;
}

.column img:hover {
  opacity: 1;
}


/* Clear floats after the columns */

.row:after {
  content: '';
  display: table;
  clear: both;
}


/* The expanding image container */

.container {
  position: relative;
  display: none;
}


/* Expanding image text */

#imgtext {
  position: absolute;
  bottom: 15px;
  left: 15px;
  color: white;
  font-size: 20px;
}


/* Closable button inside the expanded image */

.closebtn {
  position: absolute;
  top: 10px;
  right: 15px;
  color: white;
  font-size: 35px;
  cursor: pointer;
}
<div style="text-align: center">
  <h2>Tabbed Image Gallery</h2>
  <p>Click on the images below:</p>
</div>

<!-- The four columns -->
<div class="row">
  <div class="column">
    <img src="img_nature.jpg" alt="Nature" style="width: 100%" onclick="myFunction(this);" />
  </div>
  <div class="column">
    <img src="img_snow.jpg" alt="Snow" style="width: 100%" onclick="myFunction(this);" />
  </div>
  <div class="column">
    <img src="img_mountains.jpg" alt="Mountains" style="width: 100%" onclick="myFunction(this);" />
  </div>
  <div class="column">
    <img src="img_lights.jpg" alt="Lights" style="width: 100%" onclick="myFunction(this);" />
  </div>
</div>

<div class="container">
  <span onclick="this.parentElement.style.display='none'" class="closebtn">&times;</span
  >
  <img id="expandedImg" style="width: 100%" />
  <div id="imgtext"></div>
</div>

感谢任何帮助。抱歉添加此文本,因为 StackOverflow 不允许我在不添加更多文本的情况下发布此文本。

提前致谢。

【问题讨论】:

  • 有可能。但即使不知道您的上下文也不知道为什么您不想使用 JavaScript 来实现它,我强烈建议您在这种情况下使用 Javascript,因为“非 JavaScript”实现将非常混乱且耗时/不必要。有一个美好的o7
  • 我想将此添加到 ebay 列表中,但他们不允许在列表模板中使用 javascript 代码。

标签: javascript css gallery


【解决方案1】:

前言

虽然并非不可能,但我仍然强烈推荐使用 JavaScript 而不是 CSS 来完成这项任务。您不应将此答案的以下内容视为 JavaScript 预期目的的替代方案,而应将此视为一个有趣的“解决方案”。

使用 JavaScript 代替 CSS 的另一大要点是:在此任务中使用 CSS 根本无法访问。您应该始终努力打造优质、易于使用且易于访问的网站。

出于上述原因,您应该尤其避免在商业环境中使用它。

纯 CSS 解决方案

必要的 HTML 更改

由于 CSS 是级联,因此图像预览需要位于大图像本身或其祖先之前。你可以这样想象:HTML 是一棵树,效果只传递到叶子,但不能影响相邻的分支,因为这需要在某些时候回溯。

在代码中,可能如下所示:

<!-- Either this (case 1): -->
<img class="img-preview">
<img class="big-img">

<!-- Or this (case 2): -->
<img class="img-preview">
<div>
  <img class="big-img"> <!-- May be nested deeper -->
</div>

CSS

CSS 应该相对简单。唯一的问题是,对于每个图像预览,都需要添加一个新的 CSS 规则。这使得在未来添加新的图像预览变得更加困难,但更重要的是:它会让你的 CSS 充满不必要的规则!这可能会导致未使用的 CSS 规则,以防您重写一些内容,并且会严重影响维护和可读性。

友情提示:最好用JavaScript来完成!

CSS':hover-pseudo-class 与 JS'mouseover 实际上相同。使用这个和general sibling-combinator ~(可能还有descendant combinator ),我们可以根据悬停的图像预览覆盖大图像的background-image属性:

/* Either this (case 1): */
.img-preview:hover~.big-img {/* ... */}

/* Or this (case 2): */
.img-preview:hover~* .big-img {/* ... */}

正如我已经提到的,每个图像预览都需要自己的 CSS 规则。这是因为 CSS 不能为其属性使用 HTML 属性(我认为 pseudo-elements 和它们的 content-property 除外)。

这意味着,当前 HTML 的 CSS 可能如下所示:

/* The CSS */
.img-preview[data-src="https://picsum.photos/id/10/64/64"]:hover~.big-img {
  background-image: url("https://picsum.photos/id/10/64/64");
}
.img-preview[data-src="https://picsum.photos/id/1002/64/64"]:hover~.big-img {
  background-image: url("https://picsum.photos/id/1002/64/64");
}
/* etc. */

/* Ignore; for styling only */
img {border: 1px solid black}
.img-preview {
  width: 2rem;
  height: 2rem;
}
.big-img {
  width: 4rem;
  height: 4rem;
}
<img class="img-preview"
     src="https://picsum.photos/id/10/32/32"
     data-src="https://picsum.photos/id/10/64/64">
<img class="img-preview"
     src="https://picsum.photos/id/1002/32/32"
     data-src="https://picsum.photos/id/1002/64/64">
<!-- etc. -->

<img class="big-img">

(旁注:我在这里使用了attribute-selectors,但同样的事情可以使用 ID 或类似的东西来完成,只要每个图像预览都可以单独选择。)

尾注

在悬停时添加文本描述可能会以类似的方式解决,但留作任务。


很遗憾,使用这种方法时大图像不会保留。如果你想让它留下来,你应该看看Abd Elbeltaji's answer。他们使用 &lt;input&gt;- 和 &lt;label&gt;-tags 以及 CSS 的 :checked-pseudo-class 来实现这一点。

尽管看起来如此,但如图所示更改 HTML 并不会限制您如何设置元素的样式,尤其是在使用 FlexBoxCSS Grid 时。它们不仅使样式更容易,而且还可以轻松地使网站具有响应性。

辅助功能

再次重申:这不是一个可访问的解决方案!整个任务当然应该由 JavaScript 来处理。

如果这是一个公共网站,那么我建议为每张图片添加alt-descriptions,甚至是预览。不幸的是,无法通过 CSS 更新大图像的 alt-attribute,使其无法访问,进而损害您的 SEO。话虽如此,我赞扬您在原始代码中显示图像的alt-attribute 所做的努力,尽管并不完美。你可能想看看&lt;figure&gt;

虽然我们正在这样做:我还建议学习一些语义 HTML 标记以实现可访问性。

伪元素(::after::before 等)无法访问。您不应使用它们来包含任何相关信息/文本。尽管它们可以以各种可以想象的方式用于样式目的。

【讨论】:

  • 感谢您的详细描述。我会玩这个。 :)
【解决方案2】:

是的,您可以在不使用 javascript 的情况下实现相同的行为,您可以使用输入元素的概念(单个切换值的复选框,多个选择值的单选)作为您的元素的相邻兄弟,它们应该是受输入的影响,并且通过在css 中使用:checked 伪选择器作为输入,与相邻的兄弟选择器~ 结合使用,您可以在检查输入时影响所需的元素。您还可以使用labels,这将允许您隐藏输入并使用标签内的任何内容触发它们的值。

// No JS!
* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: Arial;
}

/* The grid: Four equal columns that floats next to each other */
.column {
  float: left;
  width: 25%;
  padding: 10px;
}

/* Style the images inside the grid */
.column img {
  opacity: 0.8;
  cursor: pointer;
}

.column img:hover {
  opacity: 1;
}

/* Clear floats after the columns */
.row:after {
  content: "";
  display: table;
  clear: both;
}

/* The expanding image container */
.container {
  position: relative;
}

/* Expanding image text */
#imgtext::after {
  position: absolute;
  bottom: 15px;
  left: 15px;
  color: white;
  font-size: 20px;
}

/* Closable button inside the expanded image */
.closebtn {
  position: absolute;
  top: 10px;
  right: 15px;
  color: white;
  font-size: 35px;
  cursor: pointer;
}

.container .img {
  height: 500px;
  width: 100%;
  background-image: url(https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
  background-size: cover;
}

/* Tab select */
input[name=tabSelect],
#hideImage {
  display: none;
}

#tabSelect1:checked~div.container .img {
  background-image: url(https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
}

#tabSelect2:checked~div.container .img {
  background-image: url(https://images.pexels.com/photos/869258/pexels-photo-869258.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
}

#tabSelect3:checked~div.container .img {
  background-image: url(https://images.pexels.com/photos/1183021/pexels-photo-1183021.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
}

#tabSelect4:checked~div.container .img {
  background-image: url(https://images.pexels.com/photos/1124960/pexels-photo-1124960.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
}

#tabSelect1:checked~div.container #imgtext::after {
  content: "Nature";
}

#tabSelect2:checked~div.container #imgtext::after {
  content: "Snow";
}

#tabSelect3:checked~div.container #imgtext::after {
  content: "Mountains";
}

#tabSelect4:checked~div.container #imgtext::after {
  content: "Lights";
}

/* image hide btn */
#hideImage:checked~div.container {
  display: none;
}
<div style="text-align:center">
  <h2>Tabbed Image Gallery</h2>
  <p>Click on the images below:</p>
</div>

<input type="radio" name="tabSelect" id="tabSelect1">
<input type="radio" name="tabSelect" id="tabSelect2">
<input type="radio" name="tabSelect" id="tabSelect3">
<input type="radio" name="tabSelect" id="tabSelect4">
<!-- The four columns -->
<div class="row">
  <div class="column">
    <label for="tabSelect1">
      <img src="https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Nature" style="width:100%">
    </label>
  </div>
  <div class="column">
    <label for="tabSelect2">
      <img src="https://images.pexels.com/photos/869258/pexels-photo-869258.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Snow" style="width:100%">
    </label>
  </div>
  <div class="column">
    <label for="tabSelect3">
      <img src="https://images.pexels.com/photos/1183021/pexels-photo-1183021.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Mountains" style="width:100%">
    </label>
  </div>
  <div class="column">
    <label for="tabSelect4">
      <img src="https://images.pexels.com/photos/1124960/pexels-photo-1124960.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Lights" style="width:100%">
    </label>
  </div>
</div>

<input type="checkbox" id="hideImage">
<div class="container">
  <label for="hideImage" class="closebtn">&times;</label>
  <div class="img"></div>
  <div id="imgtext"></div>
</div>
这是一个工作示例:JSFiddle

注意!这种方法不是最优的,如果您需要添加更多值,扩展起来会很棘手。

PS:我不得不更改图像,因为您的代码中提供的图像不存在。

【讨论】:

    猜你喜欢
    • 2020-03-14
    • 2010-09-22
    • 1970-01-01
    • 1970-01-01
    • 2016-08-08
    • 2011-10-31
    • 1970-01-01
    • 2021-02-03
    • 1970-01-01
    相关资源
    最近更新 更多