I have a content div with a ragged border (using a border-image) and I place another div each below the content div left and right to hold an image. This image is supposed to have a link. While the image shows nicely through the border the link area gets hidden by it. Given that my ragged border is rather wide (almost 100px), this feels quite confusing. Therefore I would like to "float" the image below the border and the actual link area above so that the link is clickable as well were the image is under the border or visible through the border.
Despite not having the background-image uploaded the effect becomes visible since the border is wide black. The structure includes a minimal header, which is not vital to the problem but is part of the root structure.
Another problem is that the link area expands to more than the wrapped image in height, however this is a minor issue.
http://jsfiddle.net/hc3jrkku/
Basestructure:
<header>
<nav>
<a href='?p=faq#faq' id='faq'>
FAQ
</a>
</nav>
</header>
<div class='leftSide'>
<a href="#anchor" class="bgImage"><img src="img/some.png" style="
position: relative;
z-index: -1;
opacity: .99;
border: 1px solid red;
width: 150px;
height: 200px;
background-color: red,
"></a>
</div>
<div class='rightSide'>{$right}</div>
<main>
<div class='container'>
{$content}
</div>
</main>
</body>
CSS:
* {
box-sizing: border-box
}
body {
margin: 0;
}
.leftSide{
position: fixed;
z-index: 0;
top: 20px;
right: 50%;
transform: translateX(-50%);
width: 808px;
height: 100%;
display: flex;
justify-content: flex-end;
margin-right:-93px;
padding: 15px 93px 90px 0;
}
.rightSide{
position: fixed;
z-index: 0;
top: 20px;
left: 50%;
transform: translateX(50%);
width: 808px;
height: 100%;
margin-left:-93px;
padding: 15px 0 90px 93px;
}
a.bgImage {
z-index:900;
opacity:.99;
border:2px dashed blue
}
.rightSide .bgImage {
margin-left: -93px;
}
.leftSide .bgImage {
margin-right: -93px;
}
main {
width: 808px;
min-height: 400px;
margin: 20px auto 0;
position: relative;
z-index: 50;
border-style: solid;
border-width: 0px 93px 127px 93px;
border-image: url(img/paperedge.png) 0 93 127 93 fill round;
padding-top:10px;
}
header {
height: 20px;
background: #ffffff url(img/header_bg.png) repeat-x bottom;
border-bottom: 1px solid #000000;
position: fixed;
width: 100%;
top: 0;
z-index: 100
}
nav {
display: flex;
justify-content: center;
}
Having read http://philipwalton.com/articles/what-no-one-told-you-about-z-index/, I tried creating new context(s) as well, and stripping the divs containing left/right background image of the z-index, However my current code depends on the transform/position thus creating a new context for the parent element either way. Is the sandwich stacking (some children above other parts of the page/others below) possible anyways?
If you want the image to be behind the border (or your content div), you can add this to the CSS of your div in the front:
main {
pointer-events: none;
}
This will kill the events on your div and make the behind events visible in the front: DEMO
You can also search more and find these similar topics:
HTML "overlay" which allows clicks to fall through to elements behind it
HTML/CSS: Make a div "invisible" to clicks?
Related
I'm creating a gallery with images having an overlay dark background and caption text. The placement is alright but the overlay div is falling out of the bounds of the image because a padding is used on the container element.
I read about it at several places and learned that border-box could solve this problem but it isn't. Am I doing something wrong here? Check out the code:
HTML:
<div class="dest-item">
<img src="http://lorempixel.com/500/400">
<div class="dest-caption">
<div class="dest-text">
<h3>This is a caption</h3>
</div>
</div>
</div>
CSS:
.dest-item{
position:relative;
overflow:hidden;
z-index:1;
padding:10px;
width: 500px;
}
.dest-item img{
width: 100%;
}
.dest-caption{
position: absolute;
top: 0px;
background: rgba(0,0,0,0.2);
z-index: 2;
width: 100%;
height: 100%;
box-sizing: border-box;
}
.dest-text{
position: absolute;
bottom: 0;
background: rgba(255,255,255,0.9);
width: 100%;
padding: 0px 10px;
}
Playground link: Code Pen
Try this (fork here:http://codepen.io/anon/pen/RNqbjB)
CSS:
/*remove the padding*/
.dest-item{
position:relative;
overflow:hidden;
z-index:1;
padding:0px;
width: 500px;
}
HTML:
<!--Add a wrapper and add the padding to that-->
<div style="padding:10px;">
<div class="dest-item">
<img src="http://lorempixel.com/500/400">
<div class="dest-caption">
<div class="dest-text">
<h3>This is a caption</h3>
</div>
</div>
</div>
</div>
Remove the padding from whole dest-item div. you don't need that padding over there as I think:
.dest-item {
position: relative;
overflow: hidden;
z-index: 1;
/* padding: 10px; */
width: 500px;
}
Not sure if this is along the right lines?
.dest-item{
position:relative;
overflow:hidden;
z-index:0;
padding:10px;
width: 500px;
}
.dest-item img{
width: 100%;
}
.dest-caption{
position: absolute;
top: 0;
left: 0;
background: rgba(0,0,0,0.2);
width: 100%;
height: 100%;
}
.dest-text{
color: black;
position: absolute;
text-shadow: 2px 2px 40px rgba(255,255,255, 1);
bottom: 0;
left: 0;
background: rgba(255,255,255,0.38);
width: 100%;
padding: 2px 0px 10px 20px;
}
<div class="dest-item">
<img src="http://lorempixel.com/500/400">
<div class="dest-caption">
<div class="dest-text">
<h3>This is a caption</h3>
</div>
</div>
</div>
You don't need border-box to do what you want.
There are 3 types of box-sizing:
content-box is the default behavior and only includes the width and height. It does not account for padding or border width. If you have an element with 500px width + 10px padding + 1px border then the display size of the whole element is 522px wide and the size of the available space for actual content is 500px.
padding-box includes the padding but not the border. Same example as above, if you are using padding-box then the display size is 502px but the available content space is 480px.
border-box covers everything. So in our example, the display size is 500px but available space for content is 478px.
Margins are never counted in the size, in any case.
Depending on how you want the end result to look, then you will achieve this differently but based on your Code Pen sample, it looks like you want to fill the entire item container so the overlay cover the 10px padding as well. You can do this without changing the box-sizing for anything.
First, you need to offset your .dest-caption element to the left by 10px to account for the padding. Then you need to add 10px padding and remove the border-box attribute.
Like this:
.dest-caption {
position: absolute;
top: 0px;
left: -10px; /* offset */
background: rgba(0,0,0,0.5);
z-index: 2;
width: 100%;
height: 100%;
padding: 10px; /* add padding */
}
With that fixed, your text and its box is misaligned and the size of the box is not well-controlled. It is affected by the margin of the H3 tag. Fix this by removing the margins from the H3 tag inside of any .dest-text elements:
.dest-text H3 {
margin: 0px;
}
Without the margins on the H3 tag, the text overlay actually disappears out of the drawable area because it's misaligned. You can fix this by offsetting .dest-text from the bottom by the .dest-caption padding width (x2). You will probably also want top and bottom padding for .dest-text.
.dest-text {
position: absolute;
bottom: 20px; /* account for padding on .dest-caption */
background: rgba(255,255,255,0.9);
width: 100%;
padding: 10px 10px; /* add top/bottom padding */
}
Code Pen Link
I am trying to overlay some text on an image.
This is easy if the image location and size stays the same, but here I am allowing the image to dynamically resize based on screen size.
http://jsfiddle.net/xcs9L7u6/1/
When I set the position of the text to absolute, the text box is the right size, and I can place it at the bottom of the image just fine, but that doesn't work when the image bottom keeps changing due to window size.
So..
how do I keep the text at bottom of the resizing image height?
keep the text box to the width of the resizing width of the image?
HTML :
<div>
<div class="gallery-background">
<div class="gallery-text">Setting up some text to look at boats and fill space so that things move and wrap but need more text as it didn't quite give the right feel</div>
<img src="http://static.giantbomb.com/uploads/original/0/4530/396796-boat.jpg" class="galleryLrg" />
</div>
</div>
CSS :
.gallery-background {
margin: 1.5rem 1rem 1rem 1rem;
/*needed for firefox and ie*/
height: 100%;
}
.gallery-text {
color: white;
padding: .5rem;
max-width: 100%;
display: inline-block;
text-align: left;
background-color: rgba(0, 255, 0, .65);
position: absolute;
}
.galleryLrg {
display: inline-block;
height: 90%;
width: 100%;
}
Any thoughts would be great,
Thank you.
All you've go to do is to set .gallery-background to position: relative, and gallery-textto position: absolute. From there onwards, maintaining .gallery-text at the bottom of the image is just a matter of setting the bottom, left and right CSS attributes to 0.
Fiddle here
Code to be changed:
.gallery-background {
position: relative;
}
.gallery-text {
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
just set .gallery-text to bottom: 0 and it will always sit at the bottom:
.gallery-text {
color: white;
padding: .5rem;
max-width: 100%;
display: inline-block;
text-align: left;
background-color: rgba(0, 255, 0, .65);
position: absolute;
bottom: 0; //add
}
and add position:relative to it's parent to keep it contained:
.gallery-background {
margin: 1.5rem 1rem 1rem 1rem;
/*needed for firefox and ie*/
height: 100%;
overflow: hidden; //add to hide excess
position: relative; //add to contain absolute element
}
FIDDLE
JSFiddle
There two points you should modify,add these attributes.
.gallery-background {
position:relative;
}
. gallery-text {
bottom:0;
}
In my application I have a section header with a caption and a horizontal line. The horizontal line is a background image (which contains the line, the rest of the image is transparent) of the parent container. The caption is defined by a child element.
<div class="header">
<span>Identifier</span>
</div>
What I am trying to achieve - with CSS styling - is that the child element is displayed with the same background color as the parent, but the background image of the parent container should not be displayed underneath the caption.
.header {
background-image: url("bg_image.png");
background-color: #fff;
position: relative;
height: 25px;
}
.header > span {
position: absolute;
background-color: #fff;
padding: 0px 10px;
}
This works perfectly if I set the background color of the child element explicitly. But the background color can be configured by the user, so I don't want to set it explicitly.
So my the question is, is this possible at all using only CSS styling?
This fiddle shows the problem (I used a gradient to simulate the background image).
EDIT: An important requirement is that the solution must work across browsers (including IE8).
If you're okay with a centered headline, try the css that i used in one of my projects:
h1 {
position: relative;
white-space: nowrap;
text-align: center;
padding: .2em 0;
}
h1:before,
h1:after {
content: "";
position: relative;
display: inline-block;
width: 50%;
height: 2px;
vertical-align: middle;
background: #000;
}
h1:before {
left: -.5em;
margin: 0 0 0 -50%;
}
h1:after {
left: .5em;
margin: 0 -50% 0 0;
}
You can see the result here: http://codepen.io/DerZyklop/pen/AouDn
It is pure CSS. It adds two lines by using the css-pseudo-elements :before and :after.
With some modifications it should also work well with a left-aligned headline like in your example.
And another important thing to note here is the white-space: nowrap;. So this will only work with one line, but not with multiple lines.
can you please checkout
http://jsfiddle.net/dYr29/3/
i have update your fiddle
<div class="header">
<span>Identifier</span>
</div>
css
.header {
background: linear-gradient(to bottom, #4c4c4c 0%,#595959 12%,#666666 25%,#474747 39%,#2c2c2c 50%,#000000 51%,#111111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%);
background-color: #fff;
position: relative;
width: 300px;
height: 1px;
top: 10px;
}
.header > span {
position: absolute;
padding: 0px 10px;
top: -10px;
left: 10px;
background:#fff;
}
I finally identified how to solve the problem.
.header > span {
position: absolute;
background-color: inherit;
padding: 0px 10px;
}
Using background-color: inherit will solve the problem.
I also updated the fiddle.
Assume, that I have three boxes (divs) on website (see image below):
header with logo
content with some text
footer with contact info
Each box have unique color (in order: yellow, orange and blue) and black border.
I would like to website always fills the entire screen, the logo was on the top and the footer was at the bottom. So if there is not enough text in content, content should be extended, so that the footer was on the bottom. And if will be a lot of text in content, slider should appear on the right.
How do this in CSS? Important is that boxes have backgrounds. I found many solutions, but none doesn't work properly with backgrounds.
Solution Explained
The black box in your diagram gets min-height 100%, is the scrolling container, and is position relative, to allow child positions to be respective to it.
The red box in your diagram is actually composed of 2 boxes:
one for your dynamically-sized content; this has sufficient top and bottom padding to make room for your header and footer, and force the scrolling container to expand
one for the background; this is position absolute, with top and bottom position specified relative to the black box, its parent.
The yellow and blue boxes in your diagram can be position: absolute, top: 0 and bottom: 0, respectively... or however you choose to position them.
Here's a fiddle of it: http://jsfiddle.net/syndicatedshannon/F5c6T/
And here is another version with explicit viewport elements just to clarify, matching colors, and borders added to replicate the OP graphics (although per the OP the black border is actually the window).
Sample HTML
<html>
<body>
<div class="background"></div>
<div class="content"></div>
<div class="header"></div>
<div class="footer"></div>
</body>
</html>
Sample CSS
html { position: absolute; height: 100%; left: 10px; right: 10px; overflow: auto; margin: 0; padding: 0; }
body { position: relative; width: 100%; min-height: 100%; margin: 0; padding: 0; }
.background { position: absolute; top: 120px; bottom: 120px; background-color: red; width: 100%; }
.content { position: relative; padding: 120px 0; }
.header { position: absolute; top: 10px; height: 100px; width: 100%; background-color: yellow; }
.footer { position: absolute; bottom: 10px; height: 100px; width: 100%; background-color: cyan; }
Also note that this assumes you cannot rely on CSS3 yet.
If you're only targeting modern browsers, you can use calc()
body, html {
height: 100%;
padding: 0;
margin: 0;
}
.header {
height: 50px;
margin-bottom: 10px;
}
.footer {
height: 100px;
margin-top: 20px;
}
.content {
min-height: calc(100% - 50px - 10px - 100px - 20px);
}
The drawback is that you need to know the header and footer sizes and they need to be fixed. I don't know any way around this without using Javascript. For slightly less modern browsers, you can use border-box to get the same effect as above.
body, html {
height: 100%;
padding: 0;
margin: 0;
}
.header {
height: 50px;
margin-bottom: 10px;
z-index: 5;
position: relative;
}
.footer {
height: 100px;
margin-top: -100px;
z-index: 5;
position: relative;
}
.content {
box-sizing: border-box;
padding: 60px 0 120px 0;
margin-top: -60px;
min-height: 100%;
z-index: 1;
position: relative;
}
Lastly, here is the JS solution:
$(function(){
$('.content').css('min-height',
$(window).height()
- $('.header').outerHeight()
- $('.footer').outerHeight() - $('.content').marginTop()
- $('.content').marginBottom());
});
EDIT: My JS solution assumed border-box and no border. This solution should be more robust:
function setContentSize() {
$('.content').css('min-height',
$(window).height()
- $('.header').outerHeight()
- $('.footer').outerHeight()
- ($('.content').outerHeight()
- $('.content').innerHeight()));
}
$(setContentSize);
$(window).on('resize', setContentSize);
I want to position an HTML element in the horizontal middle and vertical golden ratio with CSS only. The height of the element must be absolutly flexible, so I can not just set the top-attribute and the element-height to a percentage value. Is there any way to do that?
Schematic representation:
In the image, arrows of the same color are in golden ratio to each other (38.2% : 61.8%). The dotted line is only imaginary.
I believe the math works out to be this (vertical centering only discussed here):
See Fiddle (thanks to Daniel for making that)
CSS
div {
position: absolute; /* or fixed */
top: 23.6%; /* height is 100% of viewport * 38.2% (blue) * 61.8% (red) */
bottom: 38.2%; /* height is 100% of viewport * 61.8% (blue) * 61.8% (red) */
}
That should get your ratio correct for green. Height is flexible to viewport size.
EDIT: More explanation. Note that the blue arrows start out dividing 100% of the height into 38.2 and 61.8. The red top arrow is going to be 61.8 of the top blue section (38.2), hence 23.6. The red bottom arrow is going to be 61.8 of the bottom blue section (61.8), hence 38.2. Now the double check: 23.6 + 38.2 = 61.8 (that is the TOTAL distance of the two red arrows added together). So their ratio is 23.6/61.8 = 38.2% and 38.2/61.8 = 61.8% (red arrows meet your golden ratio). The green is 100 - 61.8 (the red arrow totals) = 38.2 (the total green area). The top green arrow is 38.2 (top blue) - 23.6 (top red) = 14.6. The bottom green area is 61.8 (bottom blue) - 38.2 (bottom red) = 23.6 (bottom green). Let's check the green ration: 14.6/38.2 = 38.2% and 23.6/38.2 = 61.8% (green arrows meet your golden ratio). Here's a golden ratio addict html/css version of your picture (I know your picture was for illustration purposes, but this was fun):
HTML
<div class="golden"></div>
<div class="dotted"></div>
<div class="blue top arrow"></div>
<div class="blue bottom arrow"></div>
<div class="red top arrow"></div>
<div class="red bottom arrow"></div>
<div class="green top arrow"></div>
<div class="green bottom arrow"></div>
CSS
html {
background-color: #000;
width: 100%;
height: 100%;
}
body {
background-color: #fff;
width: 38.2%;
height: 100%;
margin: 0 30.9%;
position: relative;
}
.golden {
position: absolute;
top: 23.6%;
bottom: 38.2%;
width: 38.2%;
background-color: #ddd;
left: 50%;
margin-left: -19.1%;
}
.dotted {
position: absolute;
top: 38.2%;
height: 0;
width: 100%;
border-top: 1px dotted #444;
}
.blue {
position: absolute;
right: 14.6%;
width: 2px;
background-color: #00f;
}
.blue.top {
height: 38.2%;
top: 0;
}
.blue.bottom {
height: 61.8%;
bottom: 0;
}
.red {
position: absolute;
right: 38.2%;
width: 2px;
background-color: #f00;
}
.red.top {
height: 23.6%;
top: 0;
}
.red.bottom {
height: 38.2%;
bottom: 0;
}
.green {
position: absolute;
right: 50%;
width: 2px;
background-color: #83f92c;
border-color: #83f92c;
}
.green.top {
height: 14.6%;
top: 23.6%;
}
.green.bottom {
height: 23.6%;
bottom: 38.2%;
}
.arrow:before,
.arrow:after {
content: '';
position: absolute;
display: block;
left: 0;
width: 0;
height: 0;
margin-left: -6px;
border-right: 7px solid transparent;
border-left: 7px solid transparent;
}
.arrow:before {top: 0;}
.arrow:after {bottom: 0;}
.blue:before {border-bottom: 10px solid #00f;}
.red:before {border-bottom: 10px solid #f00;}
.green:before {border-bottom: 10px solid #83f92c;}
.blue:after {border-top: 10px solid #00f;}
.red:after {border-top: 10px solid #f00;}
.green:after {border-top: 10px solid #83f92c;}
EDIT 11-10-11: Based on the questioner's comment that my first interpretation above was not correct. I offer the fact that my solution will still work assuming the white area is the content container controlling the height (in case this is useful for anyone). In such a case, do this:
HTML
<div class="content">
...place some arbitrary length content here...
[copy above HTML here]
</div>
CSS--first, remove html and body CSS from above. Then add:
.content {
position: relative;
/* this is the only vital point, you can also style it
similar to the body css in the first version above, minus the height */
}
Finally I found an answer, after eight years :D
Because of new CSS technologies :)
see my CodePen:
https://codepen.io/eHtmlu/pen/ExjZrQb
or the same live example here on stackoverflow:
/***********************************/
/* Here is where the magic happens */
.container {
display: flex; /* we need the flex technique */
flex-direction: column; /* and we need it vertically */
align-items: center; /* horizontally we just center the box */
}
.container::before {
content: " ";
flex-grow: .38196601; /* This is the magic number that places the box vertically in the golden ratio */
}
/* That's it!! */
/* except you want to place it relatively to the viewport - see below, where we position the container element */
/***********************************/
/* To place the container at the golden ratio of the viewport, we need to set the height of "html" and "body" to 100% and margin to 0. Then we use the same technique as we used for the box. */
html,
body {
height: 100%;
margin: 0;
}
body {
display: flex;
flex-direction: column;
align-items: center;
}
body::before {
content: " ";
flex-grow: .38196601;
}
/* The rest are just a few environmental and styling settings */
.container {
border: #000 solid 1px;
height: 20em;
width: 30em;
margin: 0 auto;
}
.box {
width: 10em;
padding: 1em;
border-radius: .5em;
box-shadow: 0 0 1em rgba(0, 0, 0, .5);
text-align: center;
}
<div class="container">
<div class="box">This box is located vertically in the golden ratio of the container element.</div>
</div>
Okay, I've tested this and it appears to work. The trick though requires the two divs, inner and dummy to have exactly the same contents. dummy is used to give the outer div the appropriate height so that the inner div can be positioned by a percentage of that height. A bit hacky but no javascript.
http://jsfiddle.net/fVQeC/4/
<div class="outer">
<div class="inner">
Something<br>too<br>more<br>more<br>more<br>more
</div>
<div class="dummy">
Something<br>too<br>more<br>more<br>more<br>more
</div>
</div>
.outer{
position: absolute;
top: 38.2%;
}
.inner{
width: 200px;
background-color: blue;
position: absolute;
top: -38.2%;
}
.dummy{
width: 200px;
visibility: hidden;
}