I have a navbar with links using a 1px wide, no-repeat, right-aligned background image as a divider, but for some reason the background image doesn't appear for one of the links in Chrome - in this case between "Athletics" and "Bowling".
It works in Firefox and Explorer, when zooming in and out in Chrome, when changing the font-size, when reducing the character length of the link, etc. so I believe it has something to do with how Chrome renders the background image.
I have tried different suggestions such as setting the background-size to contain/cover/100% and image-rendering to pixelated (supposedly this only targets regular images and not background images), but I can't get it to work.
How can I ensure that all background images are displayed correctly in Chrome?
CSS
ul {
display:flex;
list-style:none;
}
ul a {
background:url(sports-div.png) right bottom no-repeat;
display:inline-block;
font-family:sans-serif;
font-size:13px;
padding:5px;
}
HTML
<ul>
<li>Football</li>
<li>Basketball</li>
<li>Tennis</li>
<li>Ice hockey</li>
<li>Volleyball</li>
<li>Badminton</li>
<li>Snooker</li>
<li>Athletics</li>
<li>Bowling</li>
<li>Cycling</li>
</ul>
http://jsfiddle.net/zc29b8no/1/
The technical explanation is rather long and boring.
But, the gist of it is: it has to do with subpixel rendering.
Your anchors' dimensions are not clear cut pixels and the browser needs to approximate what to render in each pixel. Your 1px image falls on the wrong side of rounding. To make sure it renders inside the element's painted background, you need to replace the right alignment in background-position (which translates to 100%) with calc(100% - 1px):
ul {
display:flex;
list-style:none;
}
ul a {
background:url(https://i.imgur.com/mCra304.png) calc(100% - 1px) bottom no-repeat;
display:inline-block;
font-family:sans-serif;
font-size:13px;
padding:5px;
}
<ul>
<li>Football</li>
<li>Basketball</li>
<li>Tennis</li>
<li>Ice hockey</li>
<li>Volleyball</li>
<li>Badminton</li>
<li>Snooker</li>
<li>Athletics</li>
<li>Bowling</li>
<li>Cycling</li>
</ul>
Another solution would be to make the image 2px wide, but it might still have variable width.
Related
I am designing a webpage that contains a background image
like arrow for label. I have designed the image in Photoshop.
My problem is that the image size is not expanding and reducing as
per text.
So please help me, what should I do? Is there any method to do this?
HTML:
<label><span>First Name</span></label>
CSS:
label
{
background-image:url('./images/lblimg.png');
width:auto;
display:inline-block;
}
span
{
line-height:50px;text-align:center;
}
Use the style:
background-size: cover;
background-repeat: no-repeat;
With background-size:cover the image will grow as large as possible so that the background area is completely covered by it.
you need to set the background-size property to 100% for both with and height.
.bgimg{
background-image: url(https://cdn4.iconfinder.com/data/icons/defaulticon/icons/png/256x256/arrow-right.png);
background-size: 100% 100%;
font-size: 40px;
color: yellowgreen;
}
<span class="bgimg">
div with little text :)
</span>
<br />
<span class="bgimg">
div with more and more and more text :)
</span>
You have two options, both using CSS3 background-size:
Use background-size: cover: the background image will grow as large as possible until it covers the whole background area.
Pros:
The image will cover the whole area
The image will not be stretched
Cons:
As the image doesn't stretch, just grows until it covers the whole area, some parts of the picture may not be displayed.
Use background-size: 100% 100%: the background image will occupy 100% of the width and height of the container.
Pros:
The image will cover the whole area
The whole image will be displayed (no hidden parts)
Cons:
The image may be stretched (although this could be considered a pro, specially for the behavior expected in the question)
In your particular case, the second option will be better as you want to display the whole arrow without risking some parts getting hidden.
In your code, it would look like this:
label
{
background-image:url('./images/lblimg.png');
background-size:100% 100%;
width:auto;
display:inline-block;
}
Edit (as per CSS2 request by OP): This cannot be achieved exclusively with CSS2 unless you change the HTML code. In that case you would actually not be using a background-image, but directly an image that would be behind the text.
This is how the HTML would look:
<label>
<img src="http://lorempixel.com/400/200/animals/" alt="Random pic" />
<span>First Name</span>
</label>
This is how the CSS would look:
label {
width:auto;
display:inline-block;
position:relative;
}
span {
line-height:50px;text-align:center;
position:relative;
z-index:2;
}
img {
position:absolute;
z-index:1;
top:0;
left:0;
width:100%;
height:100%;
}
You can see an example of the CSS3 and CSS2 solutions on this JSFiddle: http://jsfiddle.net/othnjk5x/
I came accross this problem while adding anchor elements to a section for a menu. I want each element to display a transparent block of color behind it when the mouse is hovering over. At the same time, I want the page background to have stripes from CSS (background: linear-gradient; or background:repeating-linear-gradient;) (I run into this problem with either). When I have a link on top of these vertical stripes and I hover over it, the underlying stripes are shifted in one direction by about a pixel. Its a very small effect but none-the-less frustrating. I have removed all other elements from the html and css that are not involved in this issue and placed the resulting files in this jsfiddle: http://jsfiddle.net/bw9fk0y4/5/
body {
margin: 0px;
padding: 0px;
background:
repeating-linear-gradient(90deg,transparent, transparent 2%, rgba(0,0,250,0.2) 2%, rgba(0,0,250,0.2) 4%, transparent 4%);
}
div nav{
position: relative;
left: 250px;
}
div nav a{
margin: 5px;
display: inline-block;
padding: 10px;
}
div nav a:hover{
background-color: rgba(250,250,250,0.4);
}
<body>
<div id = "container">
<nav>
link 1
</nav>
</div>
</body>
What I have found is that for some reason I don't run into this effect when the anchor is further to the right of this page. If it is centered or closer to the left side or even centered I do have this effect, even if I position it by setting a fixed width and the in CSS (margin: 0 auto;). If anyone knows of a way to aleviate this problem I would be very happy. This is only happening in chrome. I've tried using the browser specific gradients, no difference. I am afraid that this is just a result of CSS gradients not behaving well, because they seem to misbehave quite easily when played around with, but they are too convenient for me to give up on them easily.
I have a menu on which I have to make a hover effect, that can't be drawn by css, so I have use it as a picture. My menu objects are <li> objects with different sizes,
and I cant understand how can I make the different sized images fit in <li> because the <li> objects don't have a defined width.
My code is as follows:
ul li:hover{
background:url('../images/hover.jpg');
width:100%;
}
but it sets the picture to <ul> size and repeats it over and over
Alternatively, you could use #font-face to include a font that has support for those characters, and have the menu items using that font. Then you could have something like:
ul li:hover {
background-color: rgba(255, 255, 255, 0.1);
}
You can use
background-size: 100% 100%;
Demo
Learn more about background
I've found the solution. I cropped the mid part of the hover image, and cropped the end and the start. i used the mid as background and set on repeat, then put 2 divs with end at start with position:absolute and left:0px; and right:0px; worked like a charm
I have the following DOM structure:
<li>
<div id="some_id_1">-some html-</div>
</li>
The <li> has an image as a background, and the <div> appears as a control box on the top-right corner of the <li>.
The <div> is floated right, and should show up on the right.
When I refresh the page (in Chrome), the <div> shows up close to the middle of the <li> (as shown in the image on the left).
When I open Chrome's developer tools, and change the opacity (or any other css property) of the <div>, it shifts to the right (as shown in the image on the right).
I tried clearing Chrome's cache, but it didn't work.
Any Chrome-specific issues that might be causing this? (The page works fine in Firefox.)
CSS:
li {
position:relative;
}
div {
position:absolute;
width:40px;
float:right;
margin:0px;
}
(all other properties relate to fonts/colors)
Update: margin-right:0px seems to have fixed problem, but I'm still confused why changing the opacity moved the div around.
have you tried margin-right:0px;
if you are using float:right; try: clear:both;
what is your css? hard to help you this way.
If you are using position:absolute to place the div then make sure li has position:relative
li{
list-style:none;
position:relative;
display:inline-block;
}
div{
position:absolute;
right:0;
width:40px;
background:#333;
color:white;
border-radius:4px
}
DEMO
The PNG image is the sidebar, and the black part is the CSS background, the PNG's alpha seems to override the black box.
When I change the image's opacity, you can see the box continues through the entire image, but is still overridden and I double-checked the sidebar's transparency, but it's set up properly.
It does this on Google Chrome as well as Firefox.
Relevant CSS:
.sidebar{
background: url('side1.png') lightgray 10% 50%;
background-repeat: no-repeat;
background-size: 100%;
height: 600px;
width: 173px;
z-index:1;
float:left;
position:relative;
opacity:0.5;
}
.header{
background: black;
background-position: top right;
float:right;
width:100%;
height: 200px;
z-index:0;
position:absolute;
}
Relevant HTML:
<div class="sidebar">
<img src="images/pic1.png" class="icon">
</div>
<div class="header"></div>
This appears to be just a simple case of the division going back behind the floated content. Most people don't realize that just because there is floated content there, the division still expands back behind it all the way to the edge, like it normally would if the floated content wasn't there.
That division is taking up its maximum amount of available space like it is expected too. The floated content is only pushing the content, which at this point, there isn't any. Making your sidebar partially opaque, this issue becomes visible as you can see that box behind your image now. A quick fix, per say, would be to add a margin to the division to push it out from behind the sidebar, like so:
.header {
margin-left: 173px; /* The width of your sidebar */
}
Note, however, that you would have to apply this margin to the left side of all your block-level elements that need pushed out from under. So it would make sense to put all the right content into a single box that gets pushed out, to prevent confusion.
Edit: The reason your black background doesn't pull through on the sidebar image is that you're setting it's background to light grey here:
background: url('side1.png') lightgray 10% 50%;
This will put a light grey background behind the image rather than letting the transparent part of your image go through to whatever is behind it. Try removing it:
background: url('side1.png') 10% 50%;
See the jsFiddle example.