问题
What I want to achieve is to put an image in the header, big one, that scales down. I managed how to do it. But also I want content on it - logo, menu, some information. Those elements are in grid boxes. The problem is that image is scaling down but not the content. I want a theme to somehow scale together at the same rate. I want to do it without using the media query. Is it possible or maybe it's a bad practice? Below is the example. I put borders to show what I mean. I set the height to a fixed value and that's why it's not scaling right but I had to set it otherwise it wouldn't display properly.
<div class="wrapper">
<div class="first">Lorem ipsum dolor</div>
<div class="second">consectetur adipiscing elit</div>
<div class="third">Vestibulum posuere vehicula massa vitae lacinia. Etiam auctor posuere lectus, eget pharetra lorem porttitor at. Etiam turpis arcu, iaculis et malesuada ac, porttitor ac quam.</div>
</div>
.wrapper {
background-color: rgb(254, 254, 254);
max-width: 1000px;
margin: 0 auto;
background-image: url('http://via.placeholder.com/1000x300');
height: 300px;
background-size: contain;
background-repeat: no-repeat;
z-index: -1;
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(3, 1fr);
}
.first {
grid-column: span 6;
grid-row: 1;
border: 1px solid black;
}
.second {
grid-column: span 6;
grid-row: 2;
border: 1px solid black;
}
.third {
grid-column: span 6;
grid-row: 3;
border: 1px solid black;
}
https://codepen.io/Eleuth/pen/vpEpMe
回答1:
It's clearly bad practice, as on small devices it will become unreadable.
But, than again, this is web. Virtual space. Anything is possible. So, if you asked for it, here's how i'd tackle it:
- add a wrapper to your element, with
position:relative
. The main purpose of this element is to keep content after your zoomed element from rendering under the zoomed element (as you'll useposition:absolute
for the zoomed element. It's also the element you want to apply thebackground-image
to, in one form or another. - give zoomed element
position:absolute;
and change its width to the base width (the width where you want it to have normal size). - calculate the ratio between base width and the parent width
- apply the ratio to the zoomed element using
transform: scale(ratio)
- set wrapper's height according to transformed content height.
Here's what i'm talking about:
function updateZoom(index, el) {
let zoomer = $('zoom-content', $(el)),
baseWidth = zoomer.data('base-width'),
zoomFactor = $(el).width() / baseWidth;
zoomer.css({
width: baseWidth + 'px',
transform: 'scale(' + zoomFactor + ')'
});
$(el).height(zoomer.height() * zoomFactor + 'px');
}
$(window).on('load resize', function() {
$('zoom-wrapper').each(updateZoom);
})
/* your initial styles */
.wrapper {
color: black;
background-color: rgb(254, 254, 254);
max-width: 1000px;
margin: 0 auto;
background-image: url('http://via.placeholder.com/1000x300');
height: 300px;
background-size: contain;
background-repeat: no-repeat;
z-index: -1;
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(3, 1fr);
}
.first {
grid-column: span 6;
grid-row: 1;
border: 1px solid black;
}
.second {
grid-column: span 6;
grid-row: 2;
border: 1px solid black;
}
.third {
grid-column: span 6;
grid-row: 3;
border: 1px solid black;
}
/* must have styles required for zoom to work: */
zoom-wrapper, zoom-content {
display: block;
box-sizing: border-box;
}
zoom-wrapper {
position: relative;
overflow: hidden;
}
zoom-content {
position: absolute;
left: 0;
top: 0;
transform-origin: 0 0;
}
/* cosmetic styles (added only for this example): */
zoom-wrapper::before {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
background-color: rgba(0,0,0,.42);
z-index: 1;
pointer-events: none;
content: '';
}
zoom-content {
color: white;
z-index: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<zoom-wrapper style="background: url(https://picsum.photos/1000/119) no-repeat 50% 50% /cover">
<zoom-content data-base-width="1000">
<div style="padding: 0 1em">
<h2>Zoomed. [base-width: 1000px]</h2>
<p> Lorem ipsum dolor amet listicle tote bag marfa hexagon letterpress, green juice normcore pinterest. Trust fund gastropub hexagon biodiesel, four dollar toast mumblecore literally. Pickled stumptown truffaut, paleo DIY flannel craft beer subway tile keffiyeh neutra mi</p>
</div>
</zoom-content>
</zoom-wrapper>
<h2>Not zoomed</h2>
<p>Artisan salvia scenester 8-bit 90's. Brunch af 3 wolf moon artisan. Pickled sartorial bushwick poutine ethical, narwhal migas asymmetrical cardigan squid synth. Kinfolk health goth prism, taiyaki la croix ethical VHS yr celiac master cleanse etsy tattooed
meh disrupt.</p>
<zoom-wrapper style="background: url(https://dummyimage.com/650x137/000/fff) no-repeat 50% 50% /cover">
<zoom-content data-base-width="650">
<div style="padding: 0 1em">
<h2>Zoomed. [base-width: 650px]</h2>
<p>Artisan salvia scenester 8-bit 90's. Brunch af 3 wolf moon artisan. Pickled sartorial bushwick poutine ethical, narwhal migas asymmetrical cardigan squid synth. Kinfolk health goth prism, taiyaki la croix ethical VHS yr celiac master cleanse etsy tattooed meh disrupt.</p>
</div>
</zoom-content>
</zoom-wrapper>
<zoom-wrapper style="background: white;">
<zoom-content data-base-width="1000">
<div class="wrapper">
<div class="first">And this is yoru example</div>
<div class="second">consectetur adipiscing elit</div>
<div class="third">Vestibulum posuere vehicula massa vitae lacinia. Etiam auctor posuere lectus, eget pharetra lorem porttitor at. Etiam turpis arcu, iaculis et malesuada ac, porttitor ac quam.</div>
</div>
</zoom-content>
</zoom-wrapper>
If you resize the browser window you'll notice the zoomed elements never change proportion, never wrap differently. They just scale according to the ratio between base-width and current width. Which means they scale exactly like background-image
does.
来源:https://stackoverflow.com/questions/47801001/scaling-background-image-with-content-on-it