background-image doesn't appear if <div> is empty? - css

I created a <div> first thing in the <body> to draw a top line at the top of the page:
<body>
<div class="bordertop"></div>
.....
</body>
and the style:
body {
font-family: Helvetica, Arial, sans-serif;
-webkit-text-size-adjust: 100%;
margin:0;
}
.bordertop {
background-image: url(../images/top_border.png);
background-repeat: repeat-x;
}
However, the top_border image doesn't appear unless I write some text inside the <div> but I don't want to. How could I fix this?

Since the div is empty, there's no content to push it "open" leaving the div to be 0px tall. Set explicit dimensions on the div and you should see the background image.
.bordertop
{
background-image: url(../images/top_border.png);
background-repeat: repeat-x;
height: 100px;
width: 100%; /* may not be necessary */
}

You might need to set the css width and height of your <div> element to whatever size you want
.bordertop {
background-image: url(../images/top_border.png);
background-repeat: repeat-x;
width: 200px;
height: 100px;
}

Give the div a height:1px. That should work. Otherwise your div is 0px high, meaning you won't see anything.
You could also give it padding-top:1px
Another thing you could do is to set the background-image of the line on the body in your CSS. This is assuming the line is the entire width of the body.
See demo

As the answers above me suggest ^^' it's because it has virtually no size, you need either to put content inside to resize it or to set width/height or padding in css bordertop class, or you can put another empty inside it with set size. I was going to skip this answer since there are already answers but I just wanted to add that width/height is not your only option.
On a side note, oh man, people here posting so fast I sometimes wonder if its a race and what is the prize, there must be some, I guess helping other is itself great prize. :) When I was starting to type this there was no answer yet.

The best way I have found is:
for landscape:
width:100%;
height:0;
padding-top:[ratio]%;
for portrait:
width:[ratio]%;
height:0;
padding-top:100%;
You need to determine which side is longer and accept this dimension as 100%
then calculate [ratio] - percentage of shorter dimension in relation to 100% longer dimension. Then use the one of solutions above.

I had the same problem for quite some time, my solution was giving the style lines of: min-height. This opens the div to the height given if there is no elements inside. The height can get bigger with the more elements inside, but not smaller.
Example code:
.fixed-bg {
/* The background image */
background-image: url("img_tree.gif");
/* Set a specified height, or the minimum height for the background image */
min-height: 500px;
/* Set background image to fixed (don't scroll along with the page) */
background-attachment: fixed;
/* Center the background image */
background-position: center;
/* Set the background image to no repeat */
background-repeat: no-repeat;
/* Scale the background image to be as large as possible */
background-size: cover;
}
code gotten from https://www.w3schools.com/cssref/pr_background-attachment.asp

If it is the only div element in the body use the following style to to make it occupy the full-width.
.bordertop {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-image:
url('../images/top_border.png');
}

I couldn't get my background showing in the div even with the width set up. Turns out i had to put "../" in the url section then it showed the picture i was struggling for quite a while.
left {
width: 800px;
height: auto;
min-height: 100%;
position: relative;
background-image: url("../img/loginpic.jpg");
background-size: cover;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
background-color: crimson;
}

Otherwise, you can just open a <p></p> and in styles, remove the default margin length, that's margin: 0; and add height: 0.1px which doesn't consume much space, so it'll work.
Note: it'll work properly until it's not zoomed out more than 50%, so make sure of the use case before you apply it to the body.

Related

Push background position off screen to the left

The background is the red rectangle
The screen is the black rectangle
(Fig1) is the original position of my background
If I want to push it all the way to the right, off-screen (Fig2), I just set
background-position: 100vw;
This works perfectly fine. However I want to do the same in reverse, push the background off screen to the left (Fig4). If I set the background-position like so
background-position: -100vw;
It does not work as expected (Fig3- bug) since the original point of background (0,0) is always top-left.
Could you guys show me how to achieve Fig4 position? Thanks
You can change the reference and use right 100vw
body {
margin:0;
height:100vh;
background:
url(https://picsum.photos/id/1/200/200) right 99vw bottom 0 no-repeat;
}
Related question for more details: Using percentage values with background-position on a linear gradient. You will also find a generic way to make the background outside of its container in the section Special cases
Use a wrapper and then transform the background here I set to -90% but you can set to -100%:
<div class="body-bg"></div>
<div class="content"><h1>Some content</h1></div>
.body-bg {
width: 50vw;
height: 50vh;
background: black;
position: absolute;
z-index: 0;
transform: translateX(-90%);
}
.content {
position: relative;
}
h1 {
color: red;
}
https://codepen.io/alexplummer/pen/JjPavBe

Button out of 3 graphic parts with fluid mid-part

I have an image:
with 3 parts:
, and
I want a button with a repeating part2, so the button text (centered) is variable.
But the button text should range 50% into the other pieces.
Part1 and part3 need a min width I think, unfortunately I have no useful example.
:before and :after didn't work very well (with position:absolute or similar), because the repeat part have to be fluid between the outer parts.
Any ideas? Greetz.
A modern posibility would be using border-image.
But if you want a wider support, do it with backgrounds.
The problem is that a repeating bkg is difficult to size . So, it's best to handle it in a pseudo element
.test {
min-width: 200px;
text-align: center;
line-height: 90px;
display: inline-block;
margin: 20px;
height: 100px;
padding: 0px 20px;
font-size: 30px;
color: white;
background-image: url('//i.stack.imgur.com/mYxcX.png'), url('//i.stack.imgur.com/TlpN0.png');
background-size: auto 100%;
background-repeat: no-repeat;
background-position: left top, right top;
position: relative;
}
.test:after {
content: "";
position: absolute;
background-image: url('//i.stack.imgur.com/GMhMi.png');
background-size: auto 100%;
left: 90px;
right: 100px;
top: 0px;
bottom: 0px;
z-index: -1;
}
<div class="test">TEST</div>
<div class="test">long test</div>
<div class="test">much longer test</div>
And the same, using border image. Using this image
we will get this: (note the trick about height:0px to allow for a single image in all the left and right sides.)
.test {
display: inline-block;
margin: 20px;
height: 0px;
font-size: 30px;
border-width: 50px;
border-image-source: url(http://i.stack.imgur.com/oXiA6.png);
border-image-slice: 50% 49% 50% 50% fill;
border-image-repeat: repeat repeat;
}
<div class="test">TEST</div>
<div class="test">long test</div>
<div class="test">much longer test</div>
UPDATED and totally Changed:
Thanks to #vals comment below which let me had the "idea bulb" above my head, hence the "unless.." part in the comment.
This new solution is much cleaner in CSS and HTML, less code, no need to worry about position:absolute, no need for extra mess, just simply uses "multiple backgrounds" (1) as well as calc()(2) function with min-width too techniques. but first here's the code and comments will explain:
JS Fiddle
.test-class {
/* so that div can expand to contain the text as well as the padding */
width:auto;
/* min width = 173px left image width + 199px right image width */
/* without this it'll collapse */
min-width:372px;
padding:0 20px 0 10px; /* just to give it breathign space on sides */
line-height: 148px;
color: white;
font-size:24px;
/* no color background because the images are PNGs with alpha */
background-color: transparent;
/* setting multiple images having the middle "extendable" one as third background */
background-image: url('//i.stack.imgur.com/mYxcX.png'),
url('//i.stack.imgur.com/TlpN0.png'),
url('//i.stack.imgur.com/GMhMi.png');
/* set no repeat to all, even the extendable otherwise it'll appear behind the
other two images, instead we don't repeat it but control its size later */
background-repeat: no-repeat, no-repeat, no-repeat;
/* position each image to its corresponding position, the 46.5% for the middle
image is because the left-side image has less width than the one on the right */
background-position:left center, right center, 46.5% 50%;
/* finally giving the images on the sides their exact-pixel size, while for the
one on the middle we make use of calc() function, so the width size of the middle
image = full div size (100%) - the width values of the left and right image (173+199) */
background-size: 173px 148px, 199px 148px, calc(100% - 372px) 148px;
display: inline-block;
text-align:center;
}
<div class="test-class">Home</div>
<div class="test-class" style="margin-left:200px;">about company</div>
<div class="test-class">example dummy text for demo only</div>
Alternatively, as I commented, you can use the CSS Sliding Door technique which was so practical and used a lot before CSS border-radius and CSS shadow presented and simplified interfaces. another example perfect CSS sprite sliding doors button
This JS Fiddle 2 shows how to implement the sliding door method for achieving such task, while it looks kind too much wide for this images set, since the right side image has 199px width, it could be used for images with less width values.
And this JS Fiddle 3 is similar to sliding door but with :before and :after but with one issue that it has to have display:block which make it not workign for horizontal alignment but could be fixed with javascript after settign it's display to inline-block.
Also there's another way, using SVG as background image which is better first because it is scale-able especially for non linear images like the blue ink circle used in the great example by #vals .
Second benefit of using SVG is using inline SVG and because SVG is made of groups and element could be targeted with CSS just like targeting other DOM elements.
https://css-tricks.com/using-svg/
----------------------------------------------------------------------------
(1). Resources:
caniuse - Multiple backgrounds
MDN - Using CSS multiple backgrounds
(2). Resources:
caniuse CSS calc()
MDN - calc()
CSS-Tricks - A couple of use cases for calc

Prevent chrome cutting off background images on body when using background-position

I have a background image of a paper airplane on the body tag of this page: http://cogo.goodfolk.co.nz. The very tip of it is being cut off - if you resize the browser window the full image pops back in.
It's only happening in Chrome, and isn't consistent, if you refresh sometimes, or even hover over sometimes it's fine. If I remove all the background styles (background position and no-repeat) then the whole image is there - but of course isn't positioned correctly. It's also happening on other pages of my website (eg http://cogo.goodfolk.co.nz/online-surveying).
After days of debugging/searching I can't find anything that refers to this issue and/or fixes it - is it possibly a Chrome bug with background-position?
Any ideas or workarounds? Thank you!
//EDITED//
The relevant code is pasted below, although obviously this is pretty standard so it must be something else in the site that's causing the problem:
.home {
background: url("../img/airplane.jpg") no-repeat center;
background-size: 70%;
background-position: 10% 98%;
}
The background image is set to center, so this is expected behaviour, depending on window size. You could change this CSS declaration from:
.home {
background: url("../img/airplane.jpg") no-repeat center;
background-size: 70%;
}
To:
.home {
background: url("../img/airplane.jpg") no-repeat center top;
background-size: 70%;
}
This would anchor the image to the top of the screen, meaning it would not clip, but this may not be the behaviour you are looking for.
To complicate matters, you also have this, which is probably contributing to the problem. I would suggest removing it entirely:
#media (min-width: 1200px)
.home {
background-position: 20% -10%;
}
Yay thanks to everyone who left suggestions, fortunately I've figured out a workaround! I managed to pretty much keep the background styles the same, and just placed everything in a :before pseudo element on the body tag. You can check out the updated code at cogo.goodfolk.co.nz if you're interested, or it's pasted here:
.home {
position: relative;
min-height: 860px;
}
.home:before {
content: "";
position: absolute;
width: 100%;
height: 100%;
background: url("../img/airplane.jpg") no-repeat center;
background-size: 70%;
background-position: 50% 15%;
}
Set the display to "inline-table".

How do you make a background repeat y start lower?

I'm curently workign on this page and I'm trying to make the background repeat-y from a certain height but to no avail. If you look at the link's background (bottom area); you'll see that it leaves a an ugly space there, which is ugly. The CSS is as show below
body {
font-family:Calibri;
font-size: 16px;
margin: 0px;
padding: 0px;
background-color: #000;
background-image: url(images/bg.png);
background-repeat: repeat -200px 0px;
}
There's no way I'm aware of that makes the repeat skip some pixels. If I were you I would split them so the background-image of the body would be what the majority of it is now without the top. And then I would add a div to the top with these settings:
<div id="upperpart"></div>
in css:
#upperpart{
background-image: url(whatever it is);
width:100%;
height:how high it is
background-repeat: repeat-x;
margin-bottom: minus its height; <-- this will make everything below this div get ontop the div
}
After some mathematical thinking and experiments, the line of code below did the magic. I had to also watch where to cut it off with -1530px. Make sure you use the same background you used with the body tag.
html {
background: url(images/bg.png) repeat 0px -1530px;
}

Can a background image be larger than the div itself?

I have a footer div with 100% width. It's about 50px high, depending on its content.
Is it possible to give that #footer a background image that kind of overflows this div?
The image is about 800x600px, and I want it to be positioned in the left bottom corner of the footer. It should work sort of like a background image for my website, but I've already set a background image on my body. I need another image positioned at the bottom left corner of my website and the #footer div would be perfect for that.
#footer {
clear: both;
width: 100%;
margin: 0;
padding: 30px 0 0;
background:#eee url(images/bodybgbottomleft.png) no-repeat left bottom fixed;
}
The image is set to the footer, however it doesn't overflow the div. Is it possible to make that happen?
overflow:visible doesn't do the job!
There is a very easy trick. Set padding of that div to a positive number and margin to negative
#wrapper {
background: url(xxx.jpeg);
padding-left: 10px;
margin-left: -10px;
}
I do not believe that you can make a background image overflow its div. Images placed in Image tags can overflow their parent div, but background images are limited by the div for which they are the background.
You can use a css3 psuedo element (:before and/or :after) as shown in this article
https://www.exratione.com/2011/09/how-to-overflow-a-background-image-using-css3/
Good Luck...
No, you can't.
But as a solid workaround, I would suggest to classify that first div as position:relative and use div::before to create an underlying element containing your image. Classified as position:absolute you can move it anywhere relative to your initial div.
Don't forget to add content to that new element. Here's some example:
div {
position: relative;
}
div::before {
content: ""; /* empty but necessary */
position: absolute;
background: ...
}
Note: if you want it to be 'on top' of the parent div, use div::after instead.
Using background-size cover worked for me.
#footer {
background-color: #eee;
background-image: url(images/bodybgbottomleft.png);
background-repeat: no-repeat;
background-size: cover;
clear: both;
width: 100%;
margin: 0;
padding: 30px 0 0;
}
Obviously be aware of support issues, check Can I Use: http://caniuse.com/#search=background-size
Use trasform: scale(1.1) property to make bg image bigger, move it up with position: relative; top: -10px;
<div class="home-hero">
<div class="home-hero__img"></div>
</div>
.home-hero__img{
position:relative;
top:-10px;
transform: scale(1.1);
background: {
size: contain;
image: url('image.svg');
}
}
You mention already having a background image on body.
You could set that background image on html, and the new one on body. This will of course depend upon your layout, but you wouldn't need to use your footer for it.
Not really - the background image is bounded by the element it's applied to, and the overflow properties only apply to the content (i.e. markup) within an element.
You can add another div into your footer div and apply the background image to that, though, and have that overflow instead.
This could help.
It requires the footer height to be a fixed number. Basically, you have a div inside the footer div with it's normal content, with position: absolute, and then the image with position: relative, a negative z-index so it stays "below" everything, and a negative top value of the footer's height minus the image height (in my example, 50px - 600px = -550px). Tested in Chrome 8, FireFox 3.6 and IE 9.

Resources