简体   繁体   English

使用 CSS 调整不断变化的图像以适应大小变化的屏幕

[英]Resize constantly-changing image to fit size-changing screen, using CSS

I have a slideshow of images.我有一张图片幻灯片。 It consists of several components:它由几个组件组成:

  • A black background黑色背景
  • A thin bar at the bottom of the screen which displays the current image's title (font size, and vertical dimensions in general, are not specified)屏幕底部的细条,显示当前图像的标题(一般未指定字体大小和垂直尺寸)
  • A button to fullscreen the slideshow, or exit fullscreen if it already is, placed on that bottom bar一个按钮,用于全屏幻灯片放映,或者如果已经是全屏显示,则放置在该底部栏上
  • A set of three images against the black background, taking up all available space while maintaining aspect ratio.黑色背景下的一组三张图像,在保持纵横比的同时占用所有可用空间。

The images are placed on top of each other, shuffling between each other the roles of 'front', 'middle', and 'back'.图像被放置在彼此的顶部,在彼此之间移动“前”、“中”和“后”的角色。 The 'middle' image has opacity 1, the others have opacity 0. Every several seconds, a Javascript function designates the current 'back' image as the new 'middle' and the 'middle' image as the new 'front', changing their opacities accordingly (a CSS transition elapses over the following second, fading them into each other). “中间”图像的不透明度为 1,其他图像的不透明度为 0。每隔几秒钟,Javascript 函数将当前的“后”图像指定为新的“中间”,将“中间”图像指定为新的“前”,从而改变它们相应地不透明度(CSS 过渡在接下来的一秒内消失,使它们相互淡化)。 The image that was formerly in 'front' is abandoned, and a new image is loaded into 'back' (via changing the src attribute directly).之前在 'front' 中的图像被放弃,一个新图像被加载到 'back'(通过直接更改src属性)。

I want these images to fill the entirety of the screen space available to them - everything but that bottom bar - while maintaining their aspect ratios .我希望这些图像填满它们可用的整个屏幕空间——除了底部栏之外的所有空间——同时保持它们的纵横比 Whichever dimension is the lower bound on the image's size determines how large the image gets.无论哪个维度是图像大小的下限,都决定了图像的大小。 In the meantime, the images need to be centered in whichever dimension they're not filling (so, horizontally centered for tall images, and vertically centered for wide images).同时,图像需要以它们未填充的任何维度居中(因此,高图像水平居中,宽图像垂直居中)。 Furthermore, the images need to adapt to changing screen size , preferably as the window size gets dragged.此外,图像需要适应不断变化的屏幕尺寸,最好随着窗口尺寸被拖动。

I'm currently using a lengthy Javascript function to (1) find the available space by subtracting the height of the bottom bar from the screen height, (2) calculating the aspect ratio of the image, (3) comparing which dimension is the limiting factor, and (4) resizing and repositioning the element accordingly.我目前正在使用一个冗长的 Javascript 函数来 (1) 通过从屏幕高度中减去底部栏的高度来找到可用空间,(2) 计算图像的纵横比,(3) 比较哪个尺寸是限制因子,以及 (4) 相应地调整元素的大小和位置。 This function gets triggered by the window.onresize event, and triggers manually whenever the image changes.此函数由window.onresize事件触发,并在图像更改时手动触发。 However, when clicking-and-dragging to change the window size, the function gets called over and over.但是,当单击并拖动以更改窗口大小时,该函数会被一遍又一遍地调用。 That's needlessly computationally intensive, and I'd like to have the size change in CSS instead if possible.这是不必要的计算密集型,如果可能的话,我希望在 CSS 中更改大小。

When I ran into this problem for the website that normally displays the images, my solution was calc() :当我为通常显示图像的网站遇到此问题时,我的解决方案是calc()

img.class {
    font-size:24pt; /* same font size as h1, which is the biggest title element. Used to calculate em */
    max-width: calc(100vw - 80px);  /* exactly enough to account for horizontal margins/padding */
    max-height: calc(100vh - 2em);  /* leave space for title but otherwise fill window */
}

The difference between that and this is that the only limiting factor was the screen size, and I knew exactly how large the other elements that were "supposed" to fit on screen were.这与这之间的区别在于,唯一的限制因素是屏幕尺寸,而我确切地知道“应该”适合屏幕的其他元素有多大。 The entire parent element was centered (and of course horizontal centering is easy), and since the screen was supposed to scroll, I didn't have to worry about vertical centering at all.整个父元素居中(当然水平居中很容易),而且由于屏幕应该滚动,我根本不必担心垂直居中。 So this solution is not reusable here, I don't think.所以这个解决方案不能在这里重用,我不认为。

The intuitive solution I tried was to put horizontal and vertical alignment in a parent <div> , and set max-width and max-height in terms of percentages (since I can't get a different element's height in CSS to do math with):我尝试的直观解决方案是将水平和垂直对齐放在父<div> ,并根据百分比设置max-widthmax-height (因为我无法在 CSS 中获得不同元素的高度来进行数学计算) :

#parent{
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    position: relative;
    padding: 0;
    margin: 0;
}

img {
    transition: opacity 1s;
    margin: auto;
    max-width: 100%;
    max-height: 100%;
}

But not only did this not center the images, it made them not appear at all!但这不仅没有使图像居中,还使它们根本不出现! Removing max-width and max-height from <img> makes the image appear but overflow the sides of the screen and the navigation bar beneath, which is also not what I want.<img>删除max-widthmax-height会使图像出现但溢出屏幕的两侧和下方的导航栏,这也不是我想要的。 How can I properly accomplish this task using CSS rather than lengthy JavaScript?如何使用 CSS 而不是冗长的 JavaScript 正确完成此任务?

I think this layout structure hits all of your requirements.我认为这种布局结构符合您的所有要求。 There are three images of varying size in here I took the opacity down so you can see how they all scale together.这里有三张不同大小的图像,我把不透明度降低了,这样你就可以看到它们是如何一起缩放的。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <style>

        body {
            margin: 0;
        }

        .images {
            position: relative;
            height: 100%;
        }
    .image {
        position: absolute; 

        background-size: contain;
        background-repeat: no-repeat;
        background-position: center center;

        width: 100%;
        height: 100%;

        opacity: 0.5;

    }
    .image-container {
        position: relative;
        width: 100%;
        height: 100%;
    }
.container {
    display: flex;
    flex-direction: column;
    height: 100vh;
}

.footer {
    background-color: black;
    color: white;
    height: 50px;
    width: 100%;
    margin-top: auto;
}
    </style>
</head>
<body>
    <div class="container">
        <div class="images">
            <div class="image-container">
                <div class="image" style="background-image: url(https://unsplash.it/1000/425)"></div>
                <div class="image" style="background-image: url(https://unsplash.it/640/1000)"></div>
                <div class="image" style="background-image: url(https://unsplash.it/800/800)"></div>
            </div>
        </div>
        <div class="footer">Content</div>
    </div>
</body>
</html>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM