图像顶部带有文本的滑动响应图像

Swiper Responsive images with Text on top of image

我正在使用 Swiper 创建一些图像滑块,我正在尝试将滑块封装在 2 个 flexbox 容器中,以便我的图像具有响应性。

我想在图片上方添​​加一些文字,与图片的左上角对齐,但这是出错的地方。

我相信我处理的 Flexbox "problem" 与 非常相似,在这种情况下父级 DIV 保持原始图像的宽度。问题是 post 中的修复在我将图像包装在 <div class="img-wrapper"> 中后似乎不起作用。事实上,我已经花了很多时间研究,但似乎没有什么能让它按我想要的方式工作。

这个问题是 CSS object-fit: contain; 的分支在布局中保持原始图像宽度

注意:在新 window 中打开下面的代码片段以查看问题。

var swiper = new Swiper('.swiper-container', {
  slidesPerView: 1,
  spaceBetween: 50,
  // init: false,
  pagination: {
    el: '.swiper-pagination',
    clickable: true,
  },
});
img {
  object-fit: contain;
  min-width: 0;
  height: 100%;
  max-width: 100%;
}

.img-num {
  float: left;
  position: absolute;
  padding-left: 10px;
  text-shadow: 1px 1px 2px black, 0 0 1em blue, 0 0 0.2em blue;
  color: white;
  font: 1.5em Georgia, serif;
}


.img-wrapper {
  border-style: solid;
  border-width: thin;
  height: 100%;
  object-fit: contain;
  min-width: 0;
}

html,
body {
  margin: 0;
  height: 100%;
}

body {
  background: #eee;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
  font-size: 14px;
  color: #000;
  margin: 0;
  padding: 0;
}

.page {
  height: 100%;
  display: flex;
}

.main-container {
  flex: 1 1 0;
  display: flex;
  min-width: 0;
  flex-direction: column;
}

.half-containers {
  flex: 0 1 50%;
  overflow: auto;
  box-sizing: border-box;
  border: 0.5px solid red;
  display: flex;
}

.page-header {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

.page-footer {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

.swiper-container {
  width: 100%;
  height: 100%;
}

.swiper-slide {
  text-align: center;
  font-size: 18px;
  background: #fff;
  /* Center slide text vertically */
  display: -webkit-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  -webkit-justify-content: center;
  justify-content: center;
  -webkit-box-align: center;
  -ms-flex-align: center;
  -webkit-align-items: center;
  align-items: center;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" />

<link href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.6/css/swiper.css" rel="stylesheet" />
<div class="page">
  <div class="main-container">
    <div class="page-header">
      This is a header
    </div>
    <div class="half-containers">
      <!-- Swiper -->
      <div class="swiper-container">
        <div class="swiper-wrapper">
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">1</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">2</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="half-containers">
      <!-- Swiper -->
      <div class="swiper-container">
        <div class="swiper-wrapper">
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">3</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">4</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="page-footer">
      This is a footer
    </div>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.6/js/swiper.js"></script>

首先,当应用于 div 而不是图像时 object-fit 的使用是无用的1.在这种情况下,即使在图像中使用它也是无用的,因为图像没有失真。 object-fit 仅在比例丢失时适用,以便再次恢复。

所以如果没有:

你也会遇到同样的问题

var swiper = new Swiper('.swiper-container', {
  slidesPerView: 1,
  spaceBetween: 50,
  // init: false,
  pagination: {
    el: '.swiper-pagination',
    clickable: true,
  },
});
img {
  height: 100%;
  max-width: 100%;
}

.img-num {
  float: left;
  position: absolute;
  padding-left: 10px;
  text-shadow: 1px 1px 2px black, 0 0 1em blue, 0 0 0.2em blue;
  color: white;
  font: 1.5em Georgia, serif;
}


.img-wrapper {
  border-style: solid;
  border-width: thin;
  height: 100%;
}

html,
body {
  margin: 0;
  height: 100%;
}

body {
  background: #eee;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
  font-size: 14px;
  color: #000;
  margin: 0;
  padding: 0;
}

.page {
  height: 100%;
  display: flex;
}

.main-container {
  flex: 1 1 0;
  display: flex;
  min-width: 0;
  flex-direction: column;
}

.half-containers {
  flex: 0 1 50%;
  overflow: auto;
  box-sizing: border-box;
  border: 0.5px solid red;
  display: flex;
}

.page-header {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

.page-footer {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

.swiper-container {
  width: 100%;
  height: 100%;
}

.swiper-slide {
  text-align: center;
  font-size: 18px;
  background: #fff;
  /* Center slide text vertically */
  display: flex;
  justify-content: center;
  align-items: center;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" />

<link href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.6/css/swiper.css" rel="stylesheet" />
<div class="page">
  <div class="main-container">
    <div class="page-header">
      This is a header
    </div>
    <div class="half-containers">
      <!-- Swiper -->
      <div class="swiper-container">
        <div class="swiper-wrapper">
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">1</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">2</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="half-containers">
      <!-- Swiper -->
      <div class="swiper-container">
        <div class="swiper-wrapper">
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">3</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">4</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="page-footer">
      This is a footer
    </div>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.6/js/swiper.js"></script>

现在您面临的问题是,首先考虑图像宽度来调整图像包装器的大小,然后在该包装器内调整图像的大小。它有点复杂,但是如果你从图像中删除 height:100% 你会得到这个:

var swiper = new Swiper('.swiper-container', {
  slidesPerView: 1,
  spaceBetween: 50,
  // init: false,
  pagination: {
    el: '.swiper-pagination',
    clickable: true,
  },
});
img {
  /*height: 100%;*/
  max-width: 100%;
}

.img-num {
  float: left;
  position: absolute;
  padding-left: 10px;
  text-shadow: 1px 1px 2px black, 0 0 1em blue, 0 0 0.2em blue;
  color: white;
  font: 1.5em Georgia, serif;
}


.img-wrapper {
  border-style: solid;
  border-width: thin;
  height: 100%;
}

html,
body {
  margin: 0;
  height: 100%;
}

body {
  background: #eee;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
  font-size: 14px;
  color: #000;
  margin: 0;
  padding: 0;
}

.page {
  height: 100%;
  display: flex;
}

.main-container {
  flex: 1 1 0;
  display: flex;
  min-width: 0;
  flex-direction: column;
}

.half-containers {
  flex: 0 1 50%;
  overflow: auto;
  box-sizing: border-box;
  border: 0.5px solid red;
  display: flex;
}

.page-header {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

.page-footer {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

.swiper-container {
  width: 100%;
  height: 100%;
}

.swiper-slide {
  text-align: center;
  font-size: 18px;
  background: #fff;
  /* Center slide text vertically */
  display: flex;
  justify-content: center;
  align-items: center;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" />

<link href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.6/css/swiper.css" rel="stylesheet" />
<div class="page">
  <div class="main-container">
    <div class="page-header">
      This is a header
    </div>
    <div class="half-containers">
      <!-- Swiper -->
      <div class="swiper-container">
        <div class="swiper-wrapper">
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">1</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">2</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="half-containers">
      <!-- Swiper -->
      <div class="swiper-container">
        <div class="swiper-wrapper">
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">3</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">4</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="page-footer">
      This is a footer
    </div>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.6/js/swiper.js"></script>

考虑到宽度,这实际上是您想要的,但高度太大,因此图像溢出。通过添加 height:100%,您将降低高度和宽度,因为 the image will try to keep its ratio。当然,包装器不会再次调整大小,因为会有一个循环,因此它会停留在那个大小。

一个简单的解决方法是简单地制作图像包装器 position: absolute;。它的高度已经定义为 100%,它的宽度将缩小以适合图像宽度。无需调整 top/left 因为它已经居中而不使用 absolute 因此它将保持居中:

var swiper = new Swiper('.swiper-container', {
  slidesPerView: 1,
  spaceBetween: 50,
  // init: false,
  pagination: {
    el: '.swiper-pagination',
    clickable: true,
  },
});
img {
  height: 100%;
  max-width: 100%;
}

.img-num {
  top:0;
  left:0;
  position: absolute;
  padding-left: 10px;
  text-shadow: 1px 1px 2px black, 0 0 1em blue, 0 0 0.2em blue;
  color: white;
  font: 1.5em Georgia, serif;
}


.img-wrapper {
  border-style: solid;
  border-width: thin;
  height: 100%;
  position: absolute;
}

html,
body {
  margin: 0;
  height: 100%;
}

body {
  background: #eee;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
  font-size: 14px;
  color: #000;
  margin: 0;
  padding: 0;
}

.page {
  height: 100%;
  display: flex;
}

.main-container {
  flex: 1 1 0;
  display: flex;
  min-width: 0;
  flex-direction: column;
}

.half-containers {
  flex: 0 1 50%;
  overflow: auto;
  box-sizing: border-box;
  border: 0.5px solid red;
  display: flex;
}

.page-header {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

.page-footer {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

.swiper-container {
  width: 100%;
  height: 100%;
}

.swiper-slide {
  text-align: center;
  font-size: 18px;
  background: #fff;
  /* Center slide text vertically */
  display: flex;
  justify-content: center;
  align-items: center;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" />

<link href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.6/css/swiper.css" rel="stylesheet" />
<div class="page">
  <div class="main-container">
    <div class="page-header">
      This is a header
    </div>
    <div class="half-containers">
      <!-- Swiper -->
      <div class="swiper-container">
        <div class="swiper-wrapper">
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">1</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">2</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="half-containers">
      <!-- Swiper -->
      <div class="swiper-container">
        <div class="swiper-wrapper">
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">3</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">4</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="page-footer">
      This is a footer
    </div>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.6/js/swiper.js"></script>


1The object-fit property specifies how the contents of a replaced element should be fitted to the box established by its used height and width.ref

A div 不是替换元素。被替换的元素是 canvasimgiframe 等元素 (https://html.spec.whatwg.org/multipage/rendering.html#replaced-elements)

更新

以上似乎只适用于 Chrome 所以我会考虑一个小的 JS hack 来纠正其他浏览器上元素的宽度:

var swiper = new Swiper('.swiper-container', {
  slidesPerView: 1,
  spaceBetween: 50,
  // init: false,
  pagination: {
    el: '.swiper-pagination',
    clickable: true,
  },
});
$('.img-wrapper').each(function() {
  $(this).width($(this).find('img').width())
})
$( window ).resize(function() {
  $('.img-wrapper').each(function() {
    $(this).css('width','100%').width($(this).find('img').width())
  })
});
img {
  height: 100%;
  max-width: 100%;
  object-fit:cover;
}

.img-num {
  top:0;
  left:0;
  position: absolute;
  padding-left: 10px;
  text-shadow: 1px 1px 2px black, 0 0 1em blue, 0 0 0.2em blue;
  color: white;
  font: 1.5em Georgia, serif;
}


.img-wrapper {
  border-style: solid;
  border-width: thin;
  height: 100%;
  position: absolute;
  max-width:100%;
}

html,
body {
  margin: 0;
  height: 100%;
}

body {
  background: #eee;
  font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
  font-size: 14px;
  color: #000;
  margin: 0;
  padding: 0;
}

.page {
  height: 100%;
  display: flex;
}

.main-container {
  flex: 1 1 0;
  display: flex;
  min-width: 0;
  flex-direction: column;
}

.half-containers {
  flex: 0 1 50%;
  overflow: auto;
  box-sizing: border-box;
  border: 0.5px solid red;
  display: flex;
}

.page-header {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

.page-footer {
  flex: 0 0 auto;
  background-color: #dcdcdc;
}

.swiper-container {
  width: 100%;
  height: 100%;
}

.swiper-slide {
  text-align: center;
  font-size: 18px;
  background: #fff;
  /* Center slide text vertically */
  display: flex;
  justify-content: center;
  align-items: center;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" />

<link href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.6/css/swiper.css" rel="stylesheet" />
<div class="page">
  <div class="main-container">
    <div class="page-header">
      This is a header
    </div>
    <div class="half-containers">
      <!-- Swiper -->
      <div class="swiper-container">
        <div class="swiper-wrapper">
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">1</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">2</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="half-containers">
      <!-- Swiper -->
      <div class="swiper-container">
        <div class="swiper-wrapper">
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">3</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
          <div class="swiper-slide">
            <div class="img-wrapper">
              <div class="img-num">4</div>
              <img src='https://i.imgur.com/mSPw98T.jpg' />
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="page-footer">
      This is a footer
    </div>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.6/js/swiper.js"></script>