I'd like to be able to layer two (or more) .png images on top of one another while calling each image from its own separate/distinct style.
Using multiple backgrounds in one style does not help me in this case, as I'd like to have the image of a "door" with a transparent background show on top of a variety of "floor tiles" at will. The door is a separate style, each floor tile is a separate style. I wouldn't want to create an additional combo style for every possible combination of door and floor, which is what the multiple background function within one style would force me to do.
I also would like to not employ an img if possible as I will later have additional graphics (characters and monsters) be appearing on top of the floor and door tiles which I will introduce as img.
Thanks in advance.
When applying multiple background images (about 20% of the way down https://css-tricks.com/almanac/properties/b/background-image/), you need to comma-separate images, meaning packing them into the same style. CSS3 doesn't allow you to alter a single image in the stack.
So, there are a couple options open to you:
Use multiple elements that overlay each other. Using absolute positioning allows for overlaying items.
Use pseudo elements (::before, ::after) in order to apply images over the parent image.
Both are essentially the same. Here's some boilerplate code:
<div class="game-window">
<div class="game-background walls"></div>
<div class="game-backgroud tiles"></div>
</div>
Then, you can style the backgrounds accordingly to stretch the window:
.game-window {
position: relative;
width: 640px;
height: 480px; /* Old school */
}
.game-background {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.walls {
background: url(/images/walls.png);
}
...
Without z-indexing, the last HTML element will render on the top of your image stack.
Related
I am trying to add a pulsing ring that rapidly and repeatedly shrinks around a target element to draw a user's attention to that location. Not subtle, but it'll do the job. I have several places on my site I want to place it, so I want to be able to attach it to any element without significantly altering the element that I attach it to.
My current attempt uses a div with absolute positioning with a wide border and border radius of 50%:
HTML Declaration:
<a href="mysite/readme">
<div class="attention-ring"></div>
Click Me
<a>
CSS
.attention-ring {
border-radius: 50%;
border: 10px solid red;
position: absolute;
z-index: 100;
}
The animation is achieved with jQuery. It gives it a width of 100% and quickly shrinks it using setInterval(), resetting when width reaches 0:
function animateRing() {
if ($('.attention-ring') != null) {
var ringDiameter = 100;
setInterval(function () {
if (ringDiameter > 0) {
$('.attention-ring').css({ "padding":`${ringDiameter}%`, "margin":`${-1 * ringDiameter}%`})
ringDiameter -= 1
} else {
ringDiameter = 100;
}
}, 10)
}
}
What I have does work. But there are a few problems:
The ring element at maximum diameter extends past the edge of the page. This is particularly bad for elements already close to the edge of the page. It causes intermittent blank space to appear past the edge of the page and makes the scroll-bars go haywire. Ideally I want the page to ignore that this element is going out of bound.
I currently need to place the div with the ring class directly inside elements. This means for elements, the user will have difficulty clicking on other elements on pages where this feature is active. Not ideal because I eventually want to add a way to turn this off using a different button.
How would I solve the above problems?
This is a perfect use-case for pseudo-elements and CSS animations. In fact, you don't need any Javascript at all.
Problem #1 happens because the script resizes the actual .attention-ring div itself. With position: absolute this doesn't affect the size of its container, but it will still trigger overflow if it gets beyond the container's bounds. Hence the dancing scrollbars. (You'd have to set any container to position:relative; overflow:hidden to prevent that... which could get hairy if you want to apply this in a lot of locations. Fortunately that's not necessary!)
Instead of resizing the div as an element, you can use transform: scale(<some number>) to scale the rendered element visually. (See CSS transform property.) This takes place after the "boxes" for each element are laid out in the browser, so it doesn't cause anything to overflow.
You can then animate the transform property in CSS with a named #keyframes rule, which gets attached to the animated element with the animation property.
Problem #2 can be solved with two steps. First, set pointer-events: none on the ring element. This makes clicks go "through" it, as if it's not part of the a tag it belongs to. Then you can avoid adding a separate div by turning the ring into a ::before pseudoelement. This way you can turn it on or off simply by adding or removing a class from the element you want to highlight.
Here's a demo of the whole thing in action:
.attention-ring::before {
display: block;
content: "";
pointer-events: none;
border-radius: 50%;
border: 10px solid red;
position: absolute;
animation: attention 1s cubic-bezier(0,0,.2,1) infinite;
}
#keyframes attention {
50%,to {
transform: scale(5); /* multiple of the initial size */
opacity: 0;
}
}
<p><a href="mysite/readme" class="attention-ring">
Click Me
</a></p>
<p><a href="#">
Also Click Me
</a></p>
<p
Note: the display:block; content:"" on the before:: makes the ring display, otherwise the browser treats it as an empty node and won't render it.
Credit: this is partly inspired by the ping animation in Tailwind CSS, but my solution above is a bit more flexible.
I'm currently trying to get a single image (website under construction) to cover the entire Tumblr website I'm working on, temporarily, without losing any of the underlying HTML and CSS code. Additionally, I'm not sure where to put the image itself (head, body, etc) to get it to cover up the menus and other links that are above the content without changing the structure.
There are many ways to do this.
Option 1
The most efficient way would be to have a new page with just the image and put a temporary redirect on your DNS entry if that is accessible to you. If you do not have access you can add a redirect into the head tag. (If you are looking to eventually have good SEO(Search Engine Optimization) you should be wary how you perform this redirect. Hosting the site before its ready may negatively impact rankings.
Option 2
Add the image to a div or the body tag as the background with 100% height and give it a large z-score to raise it above the rest of the content.
I suggest you put a div in the body, then style it with the following rules:
.mask {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: lightgrey;
z-index: 100;
}
Then put the image in this mask div. The mask element will fill the page.
I only have access to the css code so i can't edit the html. here's the page: http://myanimelist.net/animelist/linodiogo and the css code can be found here: http://pastebin.com/Kyz3dkmB. What i wanted to do was attach a transparent picture to the table right top corner so it would look better.
If you have any other recommendation I'm here to listen.
You can use the following via CSS, however you would probably need access to the HTML to be able to incorporate this without affecting the layout of the rest of the table.
class/id {
content:url(http://example.com)
}
I'm not entirely sure from the question/site what your aim is, but if you don't have access to the HTML it sounds as though an absolutely positioned pseudo-element might be the way to go here (even if you do have access to the HTML, it's still a good way to avoid clogged markup). The absolute positioning may avoid disruption to the table element.
Add position: relative to the table (or whatever you want the parent to be), and use the following to position a transparent element in the top-right:
parent:before {
content: '';
width: ...
height: ...
background: transparent;
position: absolute;
top: 0;
right: 0;
}
I have a select tag that I would like to remove the arrow from and insert a different one for styling purposes; however, the arrow I am inserting is in a sprite. I would like to keep it in the sprite if possible to minimize server requests. I only need to see the example in chrome, and then I can transpose it into the firefox and IE forms of the solution. My attempt is in the JS Fiddle and the code is below.
HTML:
<select id="playerType">
<option>Human</option>
<option>Computer</option>
</select>
CSS:
#playerType {
width: 81px;
-webkit-appearance: none;
background: url('http://goo.gl/8jNwT') no-repeat -250px -117px;
}
My problem is that I don't know how to clip off the othre parts of the sprite other than the downwards chevron that I inserted. Any help would be much appreciated.
I would recommend to use a vertical sprite instead of a horizontal one.
Also, each image in the vertical sprite should have at least the height of the select element.
(In Your example they have).
Then you can use the vertical sprite right aligned.
Also, if you have other images in your sprite, not related to the dropdown, the image parts intended for the dropdowns should be as wide as your widest select element, the remainder of the space being filled with transparent, or whatever colour you wish to use. (it needs a little guessing/anticipating)
I am trying to set a background image to be outside the actual containing div.
<div class="expandable">Show Details</div>
.expandable
{
background: transparent url('./images/expand.gif') no-repeat -20px 0px;
}
so the "expand" image should basically appear just to the left of the div.
I can't get this working, the image doesn't show when it's positioned outside the borders of the container. I'm not sure if there's a CSS trick I am missing, or if it's something to do with my page layout (the "expandable" div is nested inside several other divs).
Is it possible to do this? Any hints?
Edit: here is a jsFiddle showing the problem: link
I know this is an old thread but I just wanted update it and add that this is possible using CSS pseudo elements.
.class:before {
content: "";
display: inline-block;
width: {width of background img};
height: {height of background img};
background-image: url("/path/to/img.png");
background-repeat: no-repeat;
position: relative;
left: -5px; //adjust your positioning as necessary
}
You're going to have to put the background image inside a separate element. Background image positions cannot place the image outside the element they're applied to.
edit your question jogged my memory and I went and checked the CSS specs. There is in fact a "background-attachment" CSS attribute you can set, which anchors the background to the viewport instead of the element. However, it's buggy or broken in IE, which is why I've got it sitting on the "do not use" shelf in my head :-)
edit — Note that this answer is from 2010, and newer (and, more importantly, widely-supported) CSS capabilities exist in 2016.
You can't do this how you want to exactly, but there is a pretty straightforward solution. You can put another div inside of .expandable like:
<div class="expandable">Show Details<div class="expandable-image"></div></div>
Then your CSS would look something like:
.expandable{ position:relative; }
.expandable-image{
position:absolute; top:0px; left:-20px;
width:<width>px; height:<height>px;
background: url('./images/expand.gif') no-repeat;
}
Depending on the details of your situation, you might be able to get away with CSS3's border-image-* rules. For instance, I used them effectively to place "dummy search buttons" in the filter row of a CGridView widget in yii (clicking anywhere outside the filter's input boxes will trigger the ajax call, but these "buttons" give the user something intuitive to do). It wasn't worth it to me to subclass the CGridColumn widget just to hack the html in its renderFilterCell() method * -- I wanted a pure CSS solution.
.myclass .grid-view .items {
border-collapse: separate ;
}
.myclass .grid-view .filters td + td {
border-image-source: url("/path/to/my/img_32x32.png");
border-image-slice: 0 0 0 100%;
border-image-width: 0 0 0 32;
border-image-outset: 0 0 0 40px;
border-width: 1px;
}
.myclass .grid-view .filters input {
width: 80%;
}
There is a little bit of a trick involved in the border-image-width values -- that 32 is a multiplier not a length (do not put px) of the unit used in border-width (ie 1px). The result is fake buttons in the first n-1 columns of the gridview. In my case, I didn't need anything in the last column because it is a CButtonsColumn which does not have a filter box. Anyway, I hope this helps people looking for a pure CSS solution 😀 :-D
* Not long after writing this, I discovered I can just concatenate code for an image in the 'filter' property of the array used to construct the CGridColumn, so my rationale turns out to be moot. Plus there seems to be an issue (in Firefox, anyway) with the border-image-repeat being forced to stretch even when space is specified. Still, maybe this might come in handy for someone 😕 :-\