I have a div with an image background (in React with Next.js, but that shouldn't matter).
import styles from './my-component.module.css';
import Background from '../../../public/assets/images/background-image.png';
// later
<div
style={{ backgroundImage: `url(${Background})` }}
className={`${styles['background-image']}`}
>
Here is the CSS I'm currently using:
.background-image {
border-radius: 8px;
background-size: cover;
background-repeat: no-repeat;
height: auto;
}
I can't get the image to take the full height. It should always take the display's width, but take as much height as it can without stretching or repeating. How can I do that?
Update: Yes, the container has more height than the element.
Update 2 Viira's solution almost works, but the image doesn't respect padding on the right side.
Maybe this can help.
Don't set it in background image try insert it in img tag
*{box-sizing: border-box;}
body {
margin: 0;
}
.background-image {
border-radius: 8px;
background-size: cover;
background-repeat: no-repeat;
height: auto;
}
.container {
display: table;
width: 100%;
}
.img {
display: table-cell;
width: 100%;
position: absolute;
z-index: -1;
}
.img img {
width: 100%;
}
.text {
display: table-cell;
padding: 30px;
width: 100%;
}
<div class="background-image">
<div class="container">
<div class="img">
<img src="https://image.shutterstock.com/image-photo/beautiful-water-drop-on-dandelion-260nw-789676552.jpg">
</div>
<div class="text">
<h1>Are you ready</h1>
<p>Click the link</p>
<button>Click Here</button>
</div>
</div>
</div>
NOTE: The image is stretched to full width because its resolution is low. you can set it's width to auto to display its original size.
Solution 2:
As the OP mentioned, padding is not respected by the image. I came up with a solution. Since the .container div is in display: table; padding isn't allowed there. So, by giving the padding to its parent .background-image this issue will be lifted.
*{box-sizing: border-box;}
body {
margin: 0;
}
.background-image {
border-radius: 8px;
padding: 15px 40px;
}
.container {
display: table;
width: 100%;
max-width: 100%;
position: relative;
}
.img {
display: table-cell;
width: 100%;
position: absolute;
z-index: -1;
}
.img img {
width: 100%;
}
.text {
display: table-cell;
padding: 30px;
width: 100%;
}
<div class="background-image">
<div class="container">
<div class="img">
<img src="https://image.shutterstock.com/image-photo/beautiful-water-drop-on-dandelion-260nw-789676552.jpg">
</div>
<div class="text">
<h1>Are you ready</h1>
<p>Click the link</p>
<button>Click Here</button>
</div>
</div>
</div>
Set padding for .background-image div so that the padding will apply.
So you want your image to determine the height of your div. That is not possible when using the image as background.
You need to load image into dom as an element which can then be used to determine the height of your div, if you want to show some content on top of the image in this case, you will have to overlay it on top of the image.
Here's a sample html structure you can use to achieve this
<div style="position:relative">
<img src="https://images.unsplash.com/photo-1573496528816-a104a722b3db?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1950&q=80" style="width:100%; height: auto;" />
<div style="position:absolute; top: 0; left: 0; width: 100%; height: 100%">
// YOUR CONTENT
</div>
</div>
Here is how I ended up solving it:
import PropTypes from 'prop-types';
import React from 'react';
import styles from './background-image-card.module.css';
function BackgroundImageCard({ alt, children, className, image }) {
return (
<div className={`${className} ${styles.container}`}>
<div className={styles.overlay} />
<img alt={alt} src={image} className={styles['background-image']} />
<div className={styles.content}>{children}</div>
</div>
);
}
BackgroundImageCard.propTypes = {
alt: PropTypes.string,
children: PropTypes.node,
className: PropTypes.string,
image: PropTypes.string,
};
export default BackgroundImageCard;
.container {
align-items: center;
display: flex;
justify-content: center;
position: relative;
width: 100%;
}
.overlay {
background: var(--gray-800);
border-radius: 8px;
height: 100%;
opacity: 0.8;
position: absolute;
width: 100%;
}
.background-image {
border-radius: 8px;
height: auto;
width: 100%;
z-index: -1;
}
.content {
position: absolute;
}
Related
I have an iframe that acts as page footer. This iframe shows a pop up (the iframe has a button and it contains the pop up) but when I use it on the page the pop-up gets behind the containing div.
How can I show part of the pop up in the parent.
Updated
Now with some code :
iframe has a pop up:
https://codepen.io/oscarryz/pen/MNdjGm
<div class="page">
<div class="footer">
<button id="showpopup">Show popup</button>
<div id="infobox" class="hidden">PopUp</div>
</div>
</div>
And content uses that iframe as pop up
https://codepen.io/oscarryz/pen/rXgvNM
<div class="page">
<div class="content">Content</div>
<div class="footer">
<iframe src="https://codepen.io/oscarryz/full/MNdjGm" style='border:0;width:100%;height:500px;overflow:hidden' frameborder="0"></iframe>
</div>
</div>
This is basically the same code in this answer but using a div as pop up inside the iframe
The keyword here is stacking context.
Look at this minified example of your question, which should work as expected:
(please run the snippets in full page mode)
document.getElementById('showpopup').addEventListener('click',function() {
document.getElementById('infobox').classList.remove('hidden');
});
body {
padding: 0;
margin: 0;
text-align: center;
}
.page {
height: 100vh;
width: 100vw;
display: flex;
flex-direction: column;
}
.content {
height: 80%;
width: 100%;
background: #eee;
}
.footer {
height: 20%;
width: 100%;
background: #444;
}
#showpopup {
margin: 3em;
}
#infobox {
height: 200px;
width: 80%;
position: absolute;
bottom: 15%;
left: 10%;
}
.hidden {
display: none;
}
<div class="page">
<div class="content">Page Content</div>
<div class="footer">
<button id="showpopup">Show iframe</button>
</div>
<iframe id="infobox" class="hidden" src="https://bing.com"></iframe>
</div>
Now, the difference to the page you have is either, that your page uses z-index for the main content, or absolute positioning of other elements and the iframe. If the iframe has a lower z-index or is added to the document before other absolutely positioned element, it will get hidden behind it:
document.getElementById('showpopup').addEventListener('click',function() {
document.getElementById('infobox').classList.remove('hidden');
});
body {
padding: 0;
margin: 0;
text-align: center;
}
.page {
height: 100vh;
width: 100vw;
display: flex;
flex-direction: column;
}
.content {
height: 80%;
width: 100%;
background: #eee;
z-index: 99; // PROBLEM CAUSE A
position: absolute; // PROBLEM CAUSE B
}
.footer {
height: 20%;
width: 100%;
background: #444;
position: absolute;
bottom: 0;
}
#showpopup {
margin: 3em;
}
#infobox {
height: 200px;
width: 80%;
position: absolute;
bottom: 15%;
left: 10%;
}
.hidden {
display: none;
}
<div class="page">
<div class="footer">
<button id="showpopup">Show iframe</button>
</div>
<iframe id="infobox" class="hidden" src="https://bing.com"></iframe>
<div class="content">Page Content</div>
</div>
To solve this, you either need to move your iframe down in the document, or give it a higher z-index itself.
I'm creating a simple web page using React.
I have an outer div with an <img /> tag and a <div /> tag with other divs and things like that inside of it.
The <img /> doesn't resize (so if I zoom in and out, it just stays the same size really). The <div /> tag does (the resizing gets kind of weird when I zoom in past 90% though).
I'm just curious as to why this is happening? There are 3 images within the <div /> and text overlaying each image. Then the <img /> tag is really just more of a large logo. Any advice? Beneath is the JSX
<div className='container'>
<img src="logo.png" alt='Logo Large' className='logo' />
<div className='container1'>
<div alt='cc' className='container2'>
<div className='cc'>
asd
</div>
</div>
<div alt='cc1' className='container3'>
<div className='cc1'>
asdddd
</div>
</div>
<div alt='cc2' className='container4'>
<div className='cc2'>
123124
</div>
</div>
</div>
</div>
Beneath this is the related CSS
html,
body,
#app {
height: 100%;
width: 100%;
}
body {
background: #2aa9e0;
user-select: none;
color: #fff;
overflow: hidden;
font-family: 'Courier New';
}
.container {
display: flex;
align-items: center;
height: 97%;
width: 100%;
}
.container1 {
display: flex;
flex-direction: column;
align-items: inherit;
height: 80%;
width: 50%;
}
.container1 .container2 {
background-image: url("...");
width: 628px;
height: 324px;
position: relative;
}
.container1 .container2 .cc {
font-size: 52px;
position: absolute;
width: 100%;
text-align: center;
top: 15%;
}
.container1 .container3 {
background-image: url("...");
width: 213px;
height: 139px;
position: relative;
}
.container1 .container3 .cc1 {
font-size: 52px;
position: absolute;
width: 100%;
text-align: center;
top: 30%;
}
.container1 .container4 {
background-image: url("...");
width: 628px;
height: 336px;
position: relative;
}
.container1 .container4 .cc2 {
font-size: 52px;
position: absolute;
width: 100%;
text-align: center;
bottom: 15%;
}
.container .logo {
height: 70%;
width: 50%;
}
Any help would be greatly appreciated. I started using flexbox in the beginning, but kind of moved away from it to get everything properly aligned and organized in container1
The <img /> doesnt resize, since its width is set to 50% of the WIDTH of the surrounding container. The container keeps its width on zoom in/out, so the logo does as well.
If you want the logo to change its size on zoom in/out, you could use sth like:
.container .logo {
width: 25em;
}
This way its using a width relative to pixel size (1em = 16px)
So I can't figure this out.
I'm trying to get a red vertical box to display in middle of page. I've set the div's margin to auto.
And then there's another div that holds a centered text.
Setting margin auto on both.
They are both stacking on top of eachother fine in middle of page.
However I want it to be responsive to all heights. Right now it's just responsive to the x-axis and not the height.
HTML & CSS:
.parentDiv {
position: relative;
width: 250px;
height: 450px;
margin: auto;
}
#RedBox {
width: 250px;
height: 450px;
background-color: #FF0000;
margin: auto;
}
#CSText {
position: absolute;
top: 45%;
width: 250px;
color: black;
text-align: center;
}
<div class="parentDiv" style="margin-top: auto;">
<div id="CSText" class="TextAlignCenter">
</div>
<div id="RedBox">
</div>
</div>
flexbox would be a great solution to this:
.container {
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.red-box {
background-color: red;
padding: 100px;
color: white;
}
<div class="container">
<div class="red-box">text</div>
</div>
I did this for you.
https://jsfiddle.net/95ssv6q1/
HTML
<div class="parentDiv">
<div class="inner">
<div id="RedBox">
</div>
</div>
</div>
CSS
.parentDiv {
display:table;
width: 100%;
height: 100%;
position: absolute;
}
.inner{
display: table-cell;
vertical-align:middle;
}
#RedBox {
width: 250px;
height: 450px;
background-color: #FF0000;
margin: auto;
}
I don't know how to explain this, but maybe in this case picture tells story instead of me:
Shortly if you cannot see it. I'm trying to place logo inside multiple areas (header, body, content) like a global image.
Is that possible with CSS, JavaScript, HTML, PHP?
And if it is, any guides or tips?
You can place your logo inside of the nav (in this case) section. The logo must be absolutely positioned, so that it doesn't mess up with other element's alignment, and your nav section must be relatively positioned, so the logo gets placed in relation to the nav container (even if it's absolute!).
You didn't provide any HTML/dimensions, so we're pretty much left to guess, but here's how it would look, picking arbitrary dimensions.
.nav {
position: relative;
height: 100px;
}
/* .logo is a child of .nav */
.logo {
position: absolute;
top: -50px;
height: 200px;
width: 200px;
left: 0;
}
Take a look:
body {
color: #fff;
text-align: center;
}
.header {
height: 100px;
background: red;
}
.nav {
position: relative;
height: 70px;
background: blue;
}
.logo {
position: absolute;
width: 200px;
height: 200px;
left: 0;
top: -50px;
}
.body {
height: 250px;
background: purple;
}
.footer {
height: 100px;
background: lightblue;
}
<div class="header"> Header </div>
<div class="nav">
<img src="http://www.udavinci.com/wp-content/uploads/2014/09/stackoverflow.png" class="logo"/>
Nav
</div>
<div class="body"> Body </div>
<div class="footer"> My Feet </div>
Alternatively, you may also place your logo outside of everything but inside of the body tag, and just use position: absolute, and tweak it's position (top, left, etc..), according to the dimensions of the relevant elements.
You can put your logo in header and position with :
.your-logo-class {
position: relative;
top: 100px; // Adjust this value
}
You could do it like this:
body { margin: 0; padding: 0; background-color: black;}
#top { background-color: red; width: 100%; height: 100px; }
#nav { background-color: blue; width: 100%; height: 50px; }
#content { background-color: green; width: 400px; height: 500px; margin: 0 auto;}
#footer { background-color: purple; width: 100%; height: 50px; }
<body>
<div id="top">
</div>
<div id="nav">
<img src="images/logo.png" style="padding: 10px;">
</div>
<div id="content">
</div>
<div id="footer">
</div>
</body>
Or you could add position: absolute; to the img style="" and then play around with the margin/padding.
Hmm, a logo is basically an <img> tag, you can place them where ever you like, just give all those <img> tags a class and style it the way you want.
Here is my tricky problem. I'm trying to do this:
http://www.hostingpics.net/viewer.php?id=767312test.gif
(More clear than an explication I think).
My structure :
<header></header>
<div class="section">
<div class="text"></div>
<div class="content"></div>
<div class="img"><img src="img1.png"/></div>
</div>
<div class="section">
<div class="text"></div>
<div class="content"></div>
<div class="img"><img src="img2.png"/></div>
</div>
<div class="section">
<div class="text"></div>
<div class="content"></div>
<div class="img"><img src="img3.png"/></div>
</div>
<footer></footer>
Important informations :
"Header" is fix
"Content" fit to the screen less the height of header
Every "section" are the same but with different content
When the image comes to an end, the "content" div is unfixed.
I am using "section" for implementing a next and previous button in the header (with anchors).
My problem is the scrolling part. I am really lost when I try to fix the "content" div. I don't know how to fix everything except the scroll of the image in the active "img" div when the active "content" div hits the header. (Everyone follows? Look here : http://www.hostingpics.net/viewer.php?id=767312test.gif
For the scrolling part in the "img" div, I was thinking use a sort of "overflow:scroll" but the scrollbar is really awful.
I don't know if it's enough clear. If there is any problem I can complete my problem. I am not very comfortable with complex structures in html with JS.
Thanks for your help!
This is pretty close to what you're asking for (using CSS only).
This relies on the fact that the backgrounds are solid colors. It uses various specifically-defined height properties as well that match some padding properties.
The .top-bar and .bottom-bar elements can probably be changed to pseudo elements if you don't want the extra HTML.
HTML:
<header>Header</header>
<div class="top-bar"></div>
<div class="bottom-bar"></div>
<div class="section">
<div class="text">Section 1 Text</div>
<div class="content">
<div class="img"><img src="http://placekitten.com/100/1000"/></div>
</div>
</div>
<div class="section">
<div class="text">Section 2 Text</div>
<div class="content">
<div class="img"><img src="http://placekitten.com/200/2000"/></div>
</div>
</div>
<div class="section">
<div class="text">Section 3 Text</div>
<div class="content">
<div class="img"><img src="http://placekitten.com/300/3000"/></div>
</div>
</div>
<footer>Footer</footer>
CSS:
body {
margin: 0;
padding: 100px 0 0;
}
header {
background-color: red;
height: 100px;
position: fixed;
top: 0;
width: 100%;
z-index: 10;
}
footer {
background-color: blue;
height: 100px;
}
.section {
min-height: 400px;
}
.text {
background-color: aqua;
height: 50px;
}
.content {
background-color: green;
min-height: 100%;
padding: 40px 0;
position: relative;
}
.img {
background-color: yellow;
min-height: 70%;
margin: 0 auto;
padding: 40px 0;
text-align: center;
width: 80%;
}
.img > img {
vertical-align: middle;
}
.top-bar, .bottom-bar {
background-color: green;
height: 40px;
position: fixed;
width: 100%;
z-index: 5;
}
.top-bar {
top: 100px;
}
.bottom-bar {
bottom: 0;
}
footer, .text {
position: relative;
z-index: 6;
}
JSFiddle here.
For an almost completely correct solution, here is one with some jQuery involved.
New CSS:
body {
margin: 0;
padding: 100px 0 0;
}
header {
background-color: red;
height: 100px;
position: fixed;
top: 0;
width: 100%;
z-index: 10;
}
footer {
background-color: blue;
height: 100px;
}
.section {
min-height: 400px;
}
.text {
background-color: aqua;
height: 50px;
}
.content {
background-color: green;
min-height: 100%;
padding: 40px 0;
position: relative;
}
.img {
background-color: yellow;
min-height: 70%;
margin: 0 auto;
padding: 40px 0;
text-align: center;
width: 80%;
}
.img > img {
vertical-align: middle;
}
.top-bar, .bottom-bar {
background-color: green;
height: 40px;
position: fixed;
width: 100%;
}
.top-bar {
top: 100px;
z-index: 5;
}
.bottom-bar {
bottom: 0;
z-index: 7;
}
footer, .text {
position: relative;
z-index: 8;
}
.img-fix {
bottom: 40px;
height: 400px;
overflow: hidden;
position: absolute;
width: 100%;
z-index: 6;
}
jQuery:
$(document).ready(function(){
$(".content").each(function(){
$(this).append($(this).html());
$(this).find(".img + .img").wrap("<div class='img-fix'></div>");
});
$(window).resize(function() {
resizeImgFix();
});
resizeImgFix();
});
function resizeImgFix() {
$(".img-fix").height($(window).height() - $("header").height() - $(".top-bar").height() - $(".bottom-bar").height());
$(".img-fix").each(function(){
$(this).scrollTop($(this).prop("scrollHeight"));
});
}
JSFiddle here.
Note: It duplicates the .img element and its children. This could be memory intensive depending. However, it does make it work as intended without any visual lag or artifacts.