Currently, I am trying to fit (crop) image on the mobile version of the website, but, with no results...
How it looks on a desktop -
How it looks on a mobile -
Image crops on mobile because position: absolute; margin-left: 50%;, but..., this page has a scroll to the left, like this -
I've tried object-fit, different positions, so on, and no success.
How should it be done?
No image is going to be able to cope with all random viewport aspect ratios.
In this particular design it seems important that the figure is looking at/moving towards the text on the left, so the common method of dealing with narrow portrait viewports by putting one half of the 'header' below the other won't make sense in this case.
One suggestion therefore is to separate out the figure from the background and position and size it in relation to the aspect ratio/size of the viewport. Bearing in mind that the text on the left has to have a certain minimal physical size in order to be readable, this snippet sets a minimum absolute width and also the percentage across the viewport that the figure will stand.
Obviously you will want to alter the actual numbers here to get the layout that is required for narrow as well as wide devices so treat the numbers used here as being just for the demo.
Also, the colored background could be a real image as stretching to use cover would work given its design, but in this snippet it is roughly drawn using CSS just to give the idea. The figure has been roughly cut out of the given image in the question and of course would need to be a better done for a published environment.
* {
padding: 0;
margin: 0;
}
.bg {
--minw: 256px;
/* minimum width we allow the left hand side (with the text) to go */
--textw: max(var(--minw), 50vw);
position: fixed;
top: 0;
left: 0;
height: 100vh;
width: 100vw;
display: inline-block;
}
.bg::before,
.bg::after {
display: inline-block;
position: absolute;
top: 0;
left: 0;
content: '';
background-repeat: no-repeat no-repeat;
}
.bg::before {
width: 100vw;
height: 100vh;
background-image: radial-gradient(circle, rgba(160, 32, 240, .8), transparent), linear-gradient(to right, rgba(0, 0, 0, 0), #00B7EB), linear-gradient(to right, rgba(255, 0, 255, .6), rgba(160, 32, 240, .8));
background-position: center center;
}
.bg::after {
background-image: url(https://i.stack.imgur.com/655zI.png);
background-size: contain;
--pc: 80%;
background-position: var(--pc) center;
--w: calc(100vw - var(--textw));
width: var(--w);
left: calc(100vw - var(--w));
margin: 5% 0;
height: calc(100vh - 10%);
}
.text {
height: 200px;
width: var(--textw);
position: relative;
top: 0;
left: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.innertext {
border: solid white 2px;
color: white;
padding: 5%;
}
#media screen and (max-aspect-ratio: 1 /1) {
body::after {
--pc: 90%;
}
}
<div class="bg">
<div class="text">
<div class="innertext">HERE IS SOME TEXT</div>
</div>
</div>
Additional note: background-attachment: fixed is not fully implemented on all browsers at the moment so the backgrounds are added to pseudo elements on a div which is given position fixed.
Use two different versions based upon the screen size in picture element, or use object-fit in the css for mobile media query.
You are getting a horizontal scroll bar because of the absolute position plus the margin, this would push the image to the right of the screen(assuming 100% wide image). If you wanna keep it this way, use overflow-x: hidden on the html and body tags.
Related
I want to create something like this for the top section of my one-page website.
repeating background image with a gradient
I have figured out how to repeat a background image, but I was wondering if there is a way I can specify opacity for each time the image gets repeated.
This is the CSS code I've used for the section:
section{
width: 100%;
float: left;
height: 100vh;
background-image: url("img/bgflower.jpg");
background-repeat: repeat-x;
background-size: contain;
}
Please suggest any methods I can use to achieve the same, thank you!
If you want to have true gradient instead of visible opacity regions, you can do something like my code below. Unfortunately this does not really apply opacity to your image and works only with one color (like in your example picture you have white).
#background {
/* place at the top of your page */
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
/* set background image */
background: url(https://pyry.info/stackoverflow/flower.png);
background-repeat: repeat-x;
background-size: contain;
}
/* create the white gradient */
#gradientLayer {
width: 100%;
height: 100%;
background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));
}
<!-- place this below everything else -->
<div id="background">
<div id="gradientLayer"></div>
</div>
I'm not sure if the section you made is responsive or if it sits within another container that has a fixed width. With the codes below, a fixed width will render a better result. However, I made something up in codepen to help you move along. https://codepen.io/jennift/pen/qBRJOYd?editors=1100. I've included some comments in the code below:
<section>
<div class="extended">
<div class="first">first</div>
<div class="second">second</div>
<div class="third">third</div>
<div class="fourth">4th</div>
</div>
</section>
section {
width: 100%;
height: 100vh;
background-image: url("https://placeimg.com/200/480/nature");
background-repeat: repeat-x;
background-size: contain;
}
/* again I'm not sure if you will use the same image bg. However, if you intend to change, remember to change the aspect ratio here as well so that the white layers on top will lay somewhat nicely aligned with the bg */
:root {
--aspectratio: 0.416; /* divide bg image width with bg image height of bg image > 200 / 480 */
}
.extended { /*this extends the container box so the divs stays in a row instead of breaking into a new line as the screen gets resized to something smaller */
width:500%;
height: 100vh;
overflow:hidden;
}
.first, .second, .third, .fourth {
background-color: #fff;
height: 100vh;
float: left;
width: calc(100vh * var(--aspectratio)); /*using the aspect ratio, you can then calculate the width of each white section
}
.first {
opacity:0;
}
.second {
opacity: 0.3;
}
.third {
opacity: 0.6;
}
.fourth {
opacity: 0.9;
}
With the codes above, if your section gets wider than this, you probably need to put in a fifth div, and probably javascript will be easier solution to auto-create divs as the screen gets wider/smaller. But if your width is fixed, this way works well.
So I'm trying to make it so that a full page image shows in the page, and resizes responsively on different screens so that it always takes up the whole screen. I looked it up on w3schools and other questions on Stack, but it seems that no matter what I do it never works, I checked if something is overriding my CSS in the browser developer tools but it seems there is nothing wrong, it just simply doesnt work. I'm using bootstrap and the div which background image should be full page is a col-12, would that cause the problem? This is my css:
body, html {
height: 100%;
}
#image-div {
background-image: url("paper.jpeg");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
height: 100%;
color: white;
background-color: rgba(0,0,0,0.5);
background-blend-mode:darken !important;
font-size: 20px;
}
and the html:
<div className="row" id="calculator-row">
<div className="col-12" id="image-div">
<div className="over-image">
<p class="try-calculator">
Calculate the possible return of investments
</p>
</div>
</div>
<div className="col-12" id="calculator-div">
<h1>Return of Investments</h1>
<BenefitCalculator />
<strong>*The average conversion percent is 4, but enter yours in case you know it</strong>
</div>
</div>
EDIT: Forgot to mention I am also using REACTJS
Try backgound-size: cover, contain;
If this does not work send an example of you code. Also height in percentage is always a bad idea. If this is for the element to be as tall as the page use 100vh or some other method. Also note that you will probably need a media query for portrait and landscape orientation.
Try this snippit:
body,
html {
height: 100%;
margin: 0;
padding: 0;
}
.row {
display: flex;
flex-wrap: wrap;
margin-right: -15px;
margin-left: -15px;
}
.row-fw {
width: 100vw;
height: 100vh;
}
.col-12 {
flex: 0 0 100%;
max-width: 100%;
}
#image-div {
background-image: url("https://placekitten.com/g/1920/1080");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
height: 100%;
display: block;
width: 100%;
color: white;
background-color: rgba(0, 0, 0, 0.5);
background-blend-mode: darken !important;
font-size: 20px;
}
<html>
<body>
<div class="row row-fw">
<div id="image-div"></div>
</div>
</body>
</html>
You could also be using height: 100vh; & width: 100vw; (vw = viewport width, vh = viewport height).
If the parent gets bigger than the size of your screen, so will the background. 100vw & 100vh will only use the viewport width & height.
just add below class to the parent div of image, it will scale itself as per screen sizes.
.img-responsive -> Makes an image responsive (will scale nicely to the parent element).
I am using a gradient background to display an alternating background for absolute positioned rows.
When zooming out in Chrome the layout gets messed up.
The calculation of the gradient background size seems to be different to the calculation of the top margins.
I have created a JSFiddle to illustrate the problem: http://jsfiddle.net/4y3k2/4/. When zooming out to e.g. 75% an offset appears between the foreground and background. The offset sums up more and more so that the layout looks completely broken for the last rows.
Here is my code:
#container {
position: absolute;
height: 2000px;
width: 100px;
background: linear-gradient(red 50%, green 50%, green);
background-size: 40px 40px;
}
.row {
position: absolute;
}
<div id="container">
<div class="row" style="top: 920px;"></div>
</div>
Everything works fine on IE and Firefox.
You can do this without calculating top every single time
for each row.
Instead set the parent div to be a block and use
predefined height and width for each row while floating them to the left:
#container {
position: absolute;
height: 2000px;
width: 100px;
background: linear-gradient(red 50%, green 50%, green);
background-size: 40px 40px;
display: block;
}
.row {
float: left;
width: 100px;
height: 20px;
}
http://jsfiddle.net/4y3k2/11/
I'm trying to fade a div's content out at the edges using a couple of absolutely positioned overlay divs at either side. However, I need the background of the page to be viewable once the fade is finished, and throughout - effectively masking the content of one div using 2 others with linear 'fade' gradients. See the diagram below for a better explanation...
I have tried the following:
Use -webkit-mask property with a linear gradient. This works in Webkit, but nothing else. Also, the linear gradient is rather choppy and stacatto when used with the mask property. Not ideal.
Use SVG gradient mask (e.g. in the Firefox / MDN demo). Works, but only in Firefox. Not anywhere near as poor a gradient as -webkit-mask / linear-gradient in Chrome though
Using a transparent masking GIF or PNG. However, in the example I used the masking colour shows through (see this SO question).
I'm hoping there might be another way that I've not thought of, or perhaps an alternative layout I could use to achieve the same aim. Any thoughts?
I would think that the transparent PNG would be the best bet, make it absolute with a higher z index and make it inside a container div. This container div would float over the background sliding image? I would use a very small 2 px slice and just repeat it along the y axis, but I might not be seeing your problem correctly.
I tried it with a very small slice of the radiant that I repeated down (y) and the underlying image did scroll through the top transparent images. If I follow what you are trying to do. It worked in chrome, firefox and safari: here is the css
#container {
background-attachment: scroll;
background-image: url(Untitled-1.jpg);
background-repeat: repeat-x;
clear: both;
float: left;
height: 768px;
width: 80000px;
position: relative;
}
#container #info {
float: left;
width: 630px;
margin-right: 20%;
margin-left: 20%;
position: fixed;
margin-top: 100px;
height: 519px;
clear: both;
clip: rect(100px,auto,auto,auto);
}
#container #info #l_side {
background-image: url(left_.png);
background-repeat: repeat-y;
float: left;
height: 519px;
width: 165px;
position: relative;
margin-right: -2px;
}
#container #info #content {
background-color: rgba(0, 0, 255, 0.56);
color: rgba(0, 0, 255, 0.56);
float: left;
height: 519px;
width: 300px;
position: relative;
}
#container #info #r_side {
background-image: url(Right.png);
background-repeat: repeat-y;
float: left;
height: 519px;
width: 165px;
position: relative;
margin-left: -1px;
}
I am building a customization script where a user can upload an image and drag it around a template image to get a desired result. The problem is the template image is over 1000px tall and wide, so I put it inside a container limiting it's height/width.
How do I make it so the uploaded image is scaled exactly the same so when I create the image via PHP I can take the left: and top: CSS values and apply them to the much larger template image and uploaded image?
Current CSS:
#template {
position: relative;
padding: 0;
width: 500px;
height: 500px;
z-index: 1;
}
#uploaded {
position: absolute;
top: 0;
left: 0;
z-index: 2;
}
I'm not quite sure if that is what you are asking for … anyway:
The CSS3 property background-size: 100% lets you specify that the background image of should fill out the container's size and stretch proportionally. Together with background-repeat: no-repeat it might be what you are looking for:
#uploaded {
height: 500px;
width: 500px;
background-image: url(...);
background-size: 100%;
background-repeat: no-repeat;
}
Demo: http://jsfiddle.net/pu76s/3/