Why background-attachment: fixed makes the gradient to appear on entire page? - html

I have studied 5 SO questions but they all talk about how to do it.
One question also talked about why background have special behavior on body and html tags.
But my question is: Why fixed attachment makes the gradient to appear on entire page?
I mean, lets take a 200 x 200 px image as a background. It will remain fixed even when we scroll the page. (assuming background-attachment: fixed; property is applied).
But when we add gradient as a background on body tag, it stretches to entire page. Now I have studied that gradients are supposed to work like that. OK I understand. But it does not appear on entire page when background-attachment: fixed; is not specified. It repeats instead.
Why does background-attachment: fixed makes the gradient to stretch on entire page? This doesn't happen when we use a plain image.
So my question is: why this behavior comes when we apply background-attachment: fixed property?
The ONLY behavior which should come is that the gradient should remain fixed. That's it. Because that's what the use of this property.
<style>
body
{
background: linear-gradient(skyblue, orange);
background-attachment: fixed;
}
</style>

When you say:
"...But when we add gradient as a background on body tag, it stretches
to entire page. Now I have studied that gradients are supposed to work
like that. ..."
You are wrong. Gradients are not supposed to work like that. A gradient is just a background-image. That's it. They behave like background images because they are background images.
The reason, you see that behaviour is not because they are supposed to work like that. The reason the work like that is because they are images. But, you haven't defined the size explicitly. So, without an explicit size, they can't have an intrinsic size. Which is why they match size of the element they are in.
From this Ref: https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient
.. Like any other gradient, a CSS linear gradient is not a CSS
color but an image with no intrinsic dimensions; that is, it has
neither natural or preferred size, nor ratio. Its concrete size will
match the one of the element it applies to...
In order to achieve what you want, you need to apply all properties relating to background-image. Specifically, the background-size, background-position. Once that is done, you need to define your gradient.
Demo Fiddle: http://jsfiddle.net/abhitalks/comsxw8m/
Snippet with relevant CSS:
body {
background-image: linear-gradient(to bottom, #fff 0%, #00f 100%);
background-repeat: no-repeat;
background-size: 120px 120px;
background-position: top center;
background-attachment: fixed;
}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
Example 2:
See this fiddle: http://jsfiddle.net/abhitalks/comsxw8m/1/
Here the gradient is applied to body with a fixed size and is repeated. Another gradient is applied to a div which is fixed. Hope now you get the idea clearer.
Snippet 2:
body {
background-image: linear-gradient(to bottom, #fff 0%, #0ff 100%);
background-repeat: repeat;
background-size: 64px 64px;
}
div {
width: 240px; height: 240px;
margin: 32px auto;
overflow: auto;
background-image: linear-gradient(to bottom, #fff 0%, #00f 100%);
background-repeat: no-repeat;
background-size: 120px 120px;
background-position: center center;
background-attachment: fixed;
}
<div><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p></div>

Related

Pre tag is not scrolling horizontal

<pre style="overflow-x: auto; width:100%">
Will never scroll.
</pre>
<pre style="overflow-x: auto; width:500px">
Will scroll but is not of responsive design.
</pre>
I want to have a pre-element that will be more responsive in direct relation to the parent element, but the parent element has no fixed width. Using width:100vw or even something like width: calc(100vw - 300px) is not an option because the site has too many dynamic elements. I would like to accomplish this with CSS alone. Is this an issue I am only going to be able to resolve with JavaScript?
Update:
It appears that overflow-x: auto does not work unless you use a static width. In my case everything (including parent elements) is responsive, nothing is set to a static width. I solved the problem by just using overflow-x: scroll
The question in incorrect in stating that width: 100% will result in never scrolling, as can be seen in the following examples. All of the pre tags have width: 100%.
You may have had an issue with width: 100vw because 100vw is not the same as 100%. 100vw is equal to the width of the viewport, but 100% width is the width of the nearest parent element. In the bottom two examples, 100% width is the width of their respective divs, and will be responsive.
pre {
overflow-x: auto;
width: 100%;
}
#medium-container {
padding: 10px;
width: 500px;
border: 1px dotted red;
}
#small-container {
padding: 10px;
width: 250px;
border: 1px dotted blue;
}
<pre>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</pre>
<div id="medium-container">
<pre>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</pre>
</div>
<div id="small-container">
<pre>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</pre>
</div>

How to set the background image to fit the browser window when it is resize?

I'm building a small responsive page.
On a page there is a background image with many buttons over it.
I added the following css to set the background image
.background{
height: 100vh;
width: 100%;
background: url('https://images.pexels.com/photos/1563564/pexels-photo-1563564.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260') no-repeat;
background-size: cover;
}
My problem is that when I resize the browser window, the buttons get stacked vertically and then the user can navigate to the bottom where the background image ends and then the user can see a big white space.
I'd like the background image to resize to fit the browser window when it is resized.
Any idea?
EDIT:
I tried your suggestion with no help. I put my code in a StackBlitz page:
https://stackblitz.com/edit/angular-y1avtu?file=src%2Findex.html
Resize the window and you will see the buttons to stack verticaly then scroll down and you will see a large white portion of the web page. This is what I don't want.
Update your css as below :).
.background{
height: 100vh;
width: 100%;
background: url('https://images.pexels.com/photos/1563564/pexels-photo-1563564.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260') no-repeat;
background-size: cover;
background-attachment: fixed;
}
not 100% sure but if the image was fixed and set to be the width and height of the page and a background-size set to cover, when the user scrolled the background would remain stationery and you wouldn't have to worry about the white space at the bottom.
remove width: 100%; from the style
Click the expand snippet link to see the real results
.background{
height: 100vh;
background: url('https://images.pexels.com/photos/1563564/pexels-photo-1563564.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260');
background-repeat: no-repeat;
background-size: cover;
}
<div class='background'>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<br>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>

Linear semi transparent gradient background (pure css) [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
How to create such a fading text effect before text is restricted:
in pure css.
I would prefer to append the style into a box below the fading text.
Shall I operate on border box or other element? Any piece of code compatible with all browsers highly appreciated.
Here you go. You can make it using ::after element with position: absolute;, and it will overlap text in a container.
With this CSS you can add .short-box to any block and it will receive your desired gradient fade.
.short-box {
/* if you want to hide a part of text */
height: 150px;
overflow: hidden;
/* for :after to follow the paretn position */
position: relative;
}
.short-box::after {
content: '';
position: absolute;
width: 100%;
height: 50px; /* here you can use `%` instead of `px`, so this block height will depends on parent height */
bottom: 0;
left: 0;
z-index: 2;
background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
}
<div class="short-box">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>

Prevent overlay of semi-transparent background on text elements

So, there is a paragraph <p> with an inline element <span> that has a semi-transparent background rgba(0,0,0,0.5). It contains more than one line of text. To remove the gap between backgrounds on each line, padding-top, padding-bottom is used.
For example, using Open Sans 16px with 26px line-height and 2px padding -top -bottom, it renders good in Webkit desktop browsers (without gaps or overlays) but has overlays in mobile browsers (Chrome).
It could be done by applying rgba(0,0,0,0.5) to a block element (<p>), but in that case the background will fill all the block, and I need it to be partially applied to some text inside a block. Not using padding is also not an option — gaps between lines with background look bad.
div {
background: linear-gradient(to bottom, #00b3e3 0%, #2c5697 100%);
color: #fff;
font-family: Helvetica;
font-size: 16px;
line-height: 24px;
}
p {
padding: 50px;
}
span {
background-color: rgba(0,0,0,0.3);
padding: 5px 0;
}
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. <span>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit</span> esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. <span>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit</span> esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. <span>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit</span> esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
Playing with padding gives different results in different browsers.
I know you said non-transparent background is not an option, I'd still argue the simplest solution is actually to go with a solid color background that is visually identical to your non-transparent tint.
For instance, rgba(0, 0, 0, .5) renders as rgb(127, 127, 127), which makes sense, because 50% transparent black equals to 50% gray visually.
Even if you're using a colored background, say, rgba(25, 150, 90, .5), it can easily be converted into a solid color—in this case, rgb(139, 203, 173).
See the image for reference.
Fiddling with pixel dimension discrepancies between browser rendering engines can suck up your hours.
The bellow seems to be buggy on Fiferox but works fine on chrome
One idea is to use multiple background where the second one will be the same as the main container but you have to consider background-attachment:fixed to make both of them at the same position to create the illusion of the same one.
I am using different colors than your exmpale to better see the result
div {
background: linear-gradient(to right, red, blue) fixed;
color: #fff;
font-family: Helvetica;
font-size: 16px;
line-height: 24px;
}
p {
padding: 50px;
}
span {
background:
linear-gradient(rgba(0,255,0,0.3),rgba(0,255,0,0.3)),
linear-gradient(to right, red, blue) fixed;
padding: 5px 0;
}
<div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. <span>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit</span> esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>

Fixed image next to scrolling text column

I'm trying to achieve the following with two adjacent HTML boxes:
The text in the right box should be 300 px wide and always stick to the right.
The left box should fill out the rest of the browser width (ie. support window resizing).
The image should be centred horizontally in the left box.
The image should scale automatically to fill the entire browser height.
The image position should be fixed, ie. not scroll when scrolling down the page.
However, with the current version I have to manually specify height/width for the image box (augh!), and the text jumps around when I change the browser width. I'm just not good at this.
What is the simplest, most straight forward way to achieve the desired result?
<style>
body {
margin: 0;
}
.left {
float: left;
width: 700px; /* BAD */
height: 700px; /* BAD */
background-image: url("image.jpg");
background-attachment: fixed;
background-position: center top;
}
.right {
float: right;
width: 300px;
padding: 0 8px 0 8px;
}
</style>
<div class="wrapper">
<div class="left"></div>
<div class="right">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
To have the image on the left fixed you need to have the container fixed to the window so add position:fixed;. Then just use coordinates from all the sides to make it fill the left side but leave 300px on the right - left: 0, top: 0, bottom: 0, right: 300px. For the image to fill the container add background-size. You can use either cover to fill the height and width of the container always or just "auto 100%" to always have it 100% height of the container. I added box-sizing:border-box to your right side element so that it would not multiply the 300px width and the padding so that the total becomes more than 300px and collides with the left side.
.left {
position: fixed;
right: 300px;
top: 0;
bottom: 0;
left: 0;
background-image: url("//placehold.it/1000x1000");
background-position: center;
background-size: cover;
}
.right {
float: right;
width: 300px;
padding: 0 8px 0 8px;
box-sizing:border-box;
}
I created a fiddle for an example: https://jsfiddle.net/7v18eyL2/8/