How to stack elements without using z-index - javascript

I have this code:
<nav>
<div class="slider" id="slider"></div>
<div class="titleGroup">
<h2 onclick="selectArticles()" id="articlesButton" class="active">Articles</h2>
<h2 onclick="selectSocial()" id="socialButton">Social</h2>
</div>
</nav>
I need to make the slider appear on top of titleGroup but under its h2 childs, is there a way to do it using javascript? Making the h2s appear on top of everything would work too.
I tried doing it with z-index but obviously it doesn't work because z-index is relative to the parent.

Since you asked for JavaScript solution... you can prepend it to be the first child of the .titleGroup. But of course a better approach would have been to fix the HTML or try with z-index.
titleGroup.prepend(slider)
.titleGroup {
background: red;
height: 150px;
}
h2 {
position:relative;
background: black;
}
.slider {
opacity: 0.5;
background: yellow;
height: 100px;
width: 100%;
position: absolute;
}
<nav>
<div class="slider" id="slider">I am slider</div>
<div class="titleGroup" id="titleGroup">
<h2 onclick="selectArticles()" id="articlesButton" class="active">Articles</h2>
<h2 onclick="selectSocial()" id="socialButton">Social</h2>
</div>
</nav>

It's actually possible to solve your current problem using z-index and no JavaScript
(assuming you're not doing something funny with your titleGroup).
nav{
position:relative;
}
.titleGroup {
background: red;
height: 150px;
border: 1px solid yellow;
}
#slider{
z-index:1;
position: absolute;
top: 5px;
background: green;
color: white;
height: 80px;
left: 5px;
width: calc(100% - 10px);
padding: 5px;
box-sizing: border-box;
}
#slider::before{
content: "Slider in front of titleGroup background, but behind h2"
}
h2 {
position: relative;
background: cyan;
z-index: 2;
}
<nav>
<div class="slider" id="slider"></div>
<div class="titleGroup" id="titleGroup">
<h2 onclick="selectArticles()" id="articlesButton" class="active">Articles</h2>
<h2 onclick="selectSocial()" id="socialButton">Social</h2>
</div>
</nav>
Note that .titleGroup has no special value for position (or z-index for that matter), so no new stacking context is created.
(And if a css statement somehow affects your titleGroup element’s position property, you can use position:unset or position:static)
More about stacking context: Link1 (The stacking context
)
The following has an example where elements that are not siblings can be controlled just using z-index: Link2 (Stacking context example 1
)
In my example, h2 and #slider are not siblings, but since .titleGroup has no stacking context, in effect the behavior of z-indexes is comparable that of siblings.
Also note that this fails if your .titleGroup has opacity value less than 1, as it creates a new stacking context, and similarly if you have a special filter, etc. (described in the first link).

Related

Target upper div with lower div

I want the background of upperdiv to become red when lowerdiv has the .active class:
<div id="upperdiv">Text case</div>
<div id="lowerdiv" class="active">IMAGE CAROUSEL</div>
.active is being added by JavaScript. Example image.
I tried:
#upperdiv + #lowediv .active {
background: red;
}
but it's not working.
Is this possible with CSS or jQuery?
If I understand the question correctly you are trying to select the previous sibling. There is no way to do this using CSS. However, using JavaScript you can achieve the desired result. When you add the active class to the lower div, use your script to change the background color of the upper div.
See Is there a "previous sibling" CSS selector? for more information.
First I'd like to warn that OP doesn't ask to hack impossible CSS thing like previous sibling styling. So I'd ask people to read carefully question before downvote or abuse this answer.
There are two ways to get it with CSS, but you can use these ways for specific cases only. Common requirement is that both divs should come one by one.
First way is to swap divs using position attributes. I mean that lower div should come first in your HTML:
<div id="lowerdiv" class="active">IMAGE CAROUSEL</div>
<div id="upperdiv">Text case</div>
div {
position: absolute;
width: 100%;
height: 50px;
margin: 0;
left: 0;
background: orange;
}
#upperdiv {
margin-top: 0px;
}
#lowerdiv{
margin-top: 50px;
}
#lowerdiv.active + #upperdiv {
background: red;
}
<div id="lowerdiv" class="active">IMAGE CAROUSEL</div>
<div id="upperdiv">Text case</div>
And second way is to use ::before pseudo-element to put it under upperdiv as a background:
div {
position: relative;
width: 100%;
height: 50px;
margin: 0;
left: 0;
background: transparent;
}
#lowerdiv{
background: orange;
}
#lowerdiv.active:before {
content: " ";
display: block;
position: absolute;
height: 100%;
width: 100%;
bottom: 100%;
background: red;
z-index: -1;
}
<div id="upperdiv">Text case</div>
<div id="lowerdiv" class="active">IMAGE CAROUSEL</div>
Third way really exists but this is beyond conditions of the question.

Creating a roll over pointer animation

I am trying to create an effect that when you roll over an image a pointer will point towards it. The same as used in this website about half way down: https://thecleansekitchen.com.au/
I'm not sure where to begin or if there are any JQuery or plugins out there for this but I cant find any?
Any help appreciated.
I'm sure there are some jQuery plugins out there that do this but that's probably unnecessary. You can accomplish this pretty easily with some basic HTML, CSS and JavaScript.
I created a JSFiddle to try to help you get started. https://jsfiddle.net/x823m6ff/
Note that the above is very crude and you'll definitely need to massage it for your needs but hopefully it will help you start down the right path.
I'll lay out the code here as well to explain.
HTML:
<div class="container">
<div class="block">
<div class="arrow arrow-down"></div>
</div>
<div class="block">
<div class="arrow arrow-down"></div>
</div>
<div class="block">
<div class="arrow arrow-down"></div>
</div>
</div>
For the HTML, I created a container with three blocks (like your screenshot). Each block has a child arrow element that is hidden through CSS.
CSS:
.container {
width: 960px;
margin: 0 auto;
}
.block {
width: 100px;
height: 150px;
background-color: #000;
float: left;
margin-right: 20px;
position: relative;
}
.arrow {
display: none;
position: absolute;
top: 0;
left: 25%;
}
.arrow-down {
width: 0;
height: 0;
border-left: 25px solid transparent;
border-right: 25px solid transparent;
border-top: 25px solid #FFF;
}
The CSS sets up some widths and heights for our blocks and creates the arrow elements. We're positioning these arrow elements relative to each block and putting them at the top middle of each block.
JavaScript:
$(document).ready(function() {
$('.block').hover(function() {
$(this).find('.arrow').show();
}, function() {
$(this).find('.arrow').hide();
});
});
The above JavaScript is very simple and basically just listens for a mouse hover over our block and shows / hides our arrow depending on the state of the user's mouse over the block.

Make <div> scale to content when absolutely positioned?

Usually a <div> will expand to fill content insize.
<div>
<p>Hello</p>
</div>
The <div> scales to contain the <p>
Is it possible to make the <div> do this when it's absolutely positioned?
In my case I have a modal which has a set height and width, but I want to make it scale to the content.
Something like this? http://jsfiddle.net/3L99pycm/
CSS:
div {
position: absolute;
left: 50%;
top: 100px;
background-color: red;
width: 30%;
height: 100px;
}
p {
background-color: blue;
color: white;
}
div behave the same independently from its position, most likely the problem is that you are setting a fixed size parameter somewhere.
Well You dont need to do anything special to make the absolute div scale to the child. I added an example here http://jsfiddle.net/rtkvswmn/
CSS
div {
position: absolute;
background: red;
}
p{
width: 100px;
background: blue;
text-align: center;
}

How to overlay "transformed" element?

HTML structure:
<div class="menu">
menu
<div class="submenu">submenu</div>
</div>
<div class="video">video</div>
The question is how to show the .submenu element on top of the .video element which has transform css rule without changing the structure?
Fiddle - http://jsfiddle.net/vpetrychuk/YtAP6/1/
Update: .menu is also transformed.
You can set the z-index to a positive number large enough:
.submenu {
background: #c00;
position: absolute;
top: 0; left: 40px;
height: 100px;
z-index:1;
}

Page with fixed elements and filled with others?

I'd like to build a page with some fixed centered elements surrounded by elements thats fill all the space available (depending on browser's width).
Here's a wireframe to illustrate it : http://s23.postimg.org/pm61hyam3/Sans_titre_6.jpg
CSS3, JS ... Is there a way to do that ?
Thanks for the help !
Solution #1
I think the future way how to tackle this problem will be with CSS Exclusions.
Check out this fiddle in IE10+
CSS Exclusions extend the notion of content wrapping previously
limited to floats. ... Elements layout their inline content in their content area and wrap around the exclusion areas in their associated wrapping context (--excerpts from the spec)
This msdn article also explains exclusions
...web authors can now wrap text so that it completely surrounds
elements, thereby avoiding the traditional limitations of floats.
Instead of limiting elements to floating either to the left or right
relative to their position in the document flow, CSS Exclusions can be
positioned at a specified distance from the top, bottom, left, or
right sides of a containing block, while remaining part of the
document flow.
Ironically, to date this only works in IE10 (look for wrap-flow:both here)
This is what the code looks like:
<div class="container">
<div class="exclusion1"></div>
<div class="exclusion2"></div>
<div class="dummy_text">
text here
</div>
</div>
CSS
.exclusion1, .exclusion2
{
-ms-wrap-flow: both;
-ms-wrap-margin: 10px;
z-index: 1;
position:absolute;
left:0;
right:0;
top:0;
bottom: 0;
margin: auto;
}
.exclusion1
{
width: 150px;
height: 150px;
background: yellow;
}
.exclusion2
{
width: 250px;
height: 50px;
background: blue;
margin-top: 320px;
}
Solution #2
The CSS-tricks article Faking ‘float: center’ with Pseudo Elements should help.
FIDDLE
Markup
<div id="page-wrap">
<img src="http://placekitten.com/250/250" id="logo">
<div id="l">
<p>left column text</p>
</div>
<div id="r">
<p>right column text</p>
</div>
</div>
CSS
#logo {
position: absolute;
top: 0;
left: 50%;
margin-left: -125px;
}
#l, #r {
width: 49%;
}
#l:before, #r:before {
content: "";
width: 125px;
height: 250px;
}
#l {
float: left;
}
#l:before {
float: right;
}
#r {
float: right;
}
#r:before {
float: left;
}

Categories