I need to have overflow-x: scroll like on first part of my image, and overflow visible to div bigger than its parent like on part 2 of my image.
So my problem is when I add overflow:visible to parent div, all overflows inside it are visible. I want to make overflow:visible, but keep overflow-x:scroll on parent div. Is it even possible?
HTML:
<div id="wrapper">
<div class="content">
<div class="child">
<button onclick="action(this)" class="triggerBtn">Click</button>
</div>
</div>
<div class="content">
<div class="child">
<button onclick="action(this)" class="triggerBtn">Click</button>
</div>
</div>
<div class="content">
<div class="child">
<button onclick="action(this)" class="triggerBtn">Click</button>
</div>
</div>
<div class="content">
<div class="child">
<button onclick="action(this)" class="triggerBtn">Click</button>
</div>
</div>
<div class="content">
<div class="child">
<button onclick="action(this)" class="triggerBtn">Click</button>
</div>
</div>
</div>
CSS:
#wrapper {
height: 200px;
width: 400px;
white-space:nowrap;
overflow-x: auto;
overflow-y: hidden;
margin:auto;
background-color: rgb(240,240,240);
position: relative;
z-index: 1;
}
.content {
width: 200px;
height: 100%;
overflow-x: hidden;
display: inline-block;
position: relative;
z-index: 100;
background-color: rgb(200,200,200);
}
.child {
width: 200px;
height: 50%;
position: absolute;
left: 0;
top: 0;
/* transform: translateX(50%); */
background-color: #bada55;
border-radius: 5px;
z-index: 200;
transition: all .15s ease-in-out;
text-align: center;
}
div.child.active {
width: 400px;
left: -50%;
background-color: #111
}
Bunch of JS:
window.action = function(el) {
var parent = el.parentNode;
if(parent.classList.contains('active')) {
parent.classList.remove("active");
} else {
parent.className += " active";
}
};
a quick fix is to use !important on your child selectors, like so:
.parent {
overflow: visible;
}
.child {
overflow: hidden !important;
}
!important simply tells the system to use the style instead of inheriting the parent's styling. You can also use the immediate child selector >.
Related
I want to make this:
stacked cards
the html would look like so:
<div class="container>
<div class="top-card>
<div class="card-content">
...
</div>
</div>
<div class="bottom-card>
</div>
</div>
I am having trouble styling this so that the height of the entire card adjusts automatically according to the content inside the top card. Thank you in advance.
you can use a combination of box-shadow and display: inline-block to accomplish what you are trying to do. I have updated the answer. Here is the code:
.grandparent {
display: inline-block;
position: relative;
}
.parent {
display: inline-block;
background: blue;
position: absolute;
top: 0;
left: 0;
}
.child {
width: 100px;
height: 100px;
background: red;
margin: 5px;
}
.shadow {
margin-left: -7px;
margin-top: -7px;
background: pink;
z-index: -100;
border: 1px solid green;
}
.empty {
opacity: 0;
}
<div class="grandparent">
<div class="parent">
<div class="child"></div>
</div>
<div class="parent shadow">
<div class="child empty"></div>
</div>
</div>
So from this question Transition effects Top vs. Bottom in CSS is not working I can't do top to bottom transition, so how would I go about trying to get an effect like this (but with transition)
function show_box()
{
let box = document.getElementById("box")
box.className += " show";
}
.box {
background-color: red;
top: 100%;
transition: 1s;
position: fixed;
}
.box.show {
top: initial;
bottom: 0;
}
<div id="box" class="box">
sdome box with some large text
<br/>
<br/>
<br/>
<br/>
sdfasdfsdf
</div>
<button onclick="show_box()">Show</button>
function show_box()
{
let box = document.getElementById("box")
box.className += " show";
}
.box {
height: 0px;
width: 300px;
background-color: red;
top: 100%;
-webkit-transition: 1s;
position: fixed;
}
.box.show {
top: initial;
bottom: 0;
height:200px;
-webkit-transition:height 1s;
}
<div id="box" class="box">
</div>
<button onclick="show_box()">Show</button>
function showBox(boxId)
{
let box = document.getElementById(boxId)
box.className += " show";
}
.box {
background: #cdf;
width: 200px;
height: 200px;
position: fixed;
overflow: hidden;
}
.box#box-2 {
left: 220px;
}
.box#box-3 {
left: 430px;
}
.box > .inner {
width: 100%;
position: absolute;
top: 100%;
bottom: 0;
display: flex;
overflow: hidden;
}
.box.show > .inner {
top: 0;
transition: top 2s ease;
}
.box > .inner > .subInner {
position: relative;
width: 100%;
align-self: flex-end;
background: #f00;
}
<div class="box" id="box-1">
<button onClick="showBox('box-1')">Show</button>
<div class="inner">
<div class="subInner">
<p>Some content in box-1</p>
</div>
</div>
</div>
<div class="box" id="box-2">
<button onClick="showBox('box-2')">Show</button>
<div class="inner">
<div class="subInner">
<p>Content of box-2 with different height</p>
<p>Content of box-2</p>
<p>Content of box-2 again</p>
</div>
</div>
</div>
<div class="box" id="box-3">
<button onClick="showBox('box-3')">Show</button>
<div class="inner">
<div class="subInner">
<p>Third box content</p>
<p>Third box content again</p>
</div>
</div>
</div>
I've added fiddle here as snippet.
UPDATE
I changed boxes behavior from css hover to js-button click event and I'm afraid I've no ideas anymore, because fixed position of boxes made rather strict restrictions to possible solutions, which depends on specific conditions of your task.
I was playing with the opacity attribute and wrote the following code:
#outer {
width: 500px;
height: 500px;
background: pink;
margin: 50px;
position: relative;
}
.item {
width: 50px;
height: 50px;
margin-right: 10px;
background: black;
opacity: 0.5;
float: left;
}
.inner {
width: 500px;
height: 500px;
background: red;
display: none;
position: absolute;
left: 0;
top: 0;
}
.item:hover {
opacity: 1;
}
.item:hover .inner {
display: block;
}
<div id="outer">
<div class="item">
<div class="inner"></div>
</div>
<div class="item">
<div class="inner"></div>
</div>
<div class="item">
<div class="inner"></div>
</div>
<div class="item">
<div class="inner"></div>
</div>
</div>
I wanted the inner div to show up and cover its parent item div when its parent item div is hovered. Because all the other item divs are set to be transparent to show through the inner div and only the hovered item div's opacity is changed to 1, I expected only the hovered item to be covered. However, all the item divs before the hovered one are also hidden. What happened?
Your issue is with absolute positioning: it's relative to "containing block", which is not the parent, but the ascendent element with a non-static position (in your case, the #outer element).
Simply addd position: relative to .item, and it will become the containing box.
Note that this has nothing to do with opacity.
Working snippet:
#outer {
width: 500px;
height: 500px;
background: pink;
margin: 50px;
position: relative;
}
.item {
width: 50px;
height: 50px;
margin-right: 10px;
background: black;
opacity: 0.5;
float: left;
position: relative;
}
.inner {
width: 500px;
height: 500px;
background: red;
display: none;
position: absolute;
left: 0;
top: 0;
}
.item:hover {
opacity: 1;
}
.item:hover .inner {
display: block;
}
<div id="outer">
<div class="item">
<div class="inner"></div>
</div>
<div class="item">
<div class="inner"></div>
</div>
<div class="item">
<div class="inner"></div>
</div>
<div class="item">
<div class="inner"></div>
</div>
</div>
I've used some and inspired jquery tabs to make it easier
$(function(){
$('.item').hover(
function(e){
$('.item').removeClass('hover')
$(this).addClass('hover')
$('.content').removeClass('show')
var content = $(this).attr('data')
$(content).addClass('show')
},
function(e){
$('.item').removeClass('hover')
$('.content').removeClass('show')
}
)
})
#outer {
width: 500px;
height: 500px;
background: pink;
margin: 50px;
position: relative;
}
.btn{
position:absolute;
left:0;
top:0;
z-index:2
}
.btn .item {
width: 50px;
height: 50px;
margin-right: 10px;
background: black;
opacity: 0.5;
float: left;
position: relative;
-webkit-transition: all 0.2s; /* Safari */
transition: all 0.2s;
}
.content {
width: 500px;
height: 500px;
background: red;
position: absolute;
left:0;
top: 0;
z-index:1;
text-align:center;
opacity: 0;
-webkit-transition: all 0.2s; /* Safari */
transition: all 0.2s;
}
.item.hover {
opacity: 1;
}
.content.show{
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="outer">
<div class="btn">
<div class="item" data="#content1"></div>
<div class="item" data="#content2"></div>
<div class="item" data="#content3"></div>
<div class="item" data="#content4"></div>
</div>
<div class="content" id='content1'>content 1
</div>
<div class="content" id='content2'>content 2
</div>
<div class="content" id='content3'>content 3
</div>
<div class="content" id='content4'>content 4
</div>
</div>
I'm having troubles positioning my divs. I want to have my child div stick to the bottom of the parent div, with grandchild_1 and grandchild_2 staying correctly put. By that, I mean having grandchild_1 before grandchild_2, like on the picture.
This is what I've tried, but the "child" div sticks to the top :
#parent {
position: relative;
}
#child {
position: absolute; bottom: 0;
}
<div id="parent">
<div id="child">
<div id="grandchild_1">
</div>
<div id="grandchild_2">
</div>
</div>
</div>
Anyone knows how I should proceed ? Thanks !
If you specify a height on the parent it will stick to the bottom.
Example: http://codepen.io/anon/pen/wGqzVd
HTML
<div id="parent">
Parent
<div id="child">
Child
<div id="grandchild_1">
Grandchild 1
</div>
<div id="grandchild_2">
Grandchild 2
</div>
</div>
</div>
CSS
div {
padding: 5px;
}
#parent {
position: relative;
background: lightgray;
height: 200px;
width: 150px;
}
#child {
position: absolute;
bottom: 5px;
background: yellow;
}
#grandchild_1 {
background: pink;
}
#grandchild_2 {
background: lightblue;
}
The provided code works as is...assuming that the parent has a height greater than that of the child.
#parent {
position: relative;
height: 200px;
background: pink;
}
#child {
position: absolute;
width: 100%;
bottom: 0;
background: green;
}
#grandchild_1,
#grandchild_2 {
height: 25px;
background: red;
margin: 10px;
}
<div id="parent">
<div id="child">
<div id="grandchild_1">GC1
</div>
<div id="grandchild_2">GC2
</div>
</div>
</div>
As an alternative to positioning, flexbox can do the same...and the child will affect the height of the parent which an absolutely positioned child cannot.
#parent {
position: relative;
height: 200px;
background: pink;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
#child {
width: 100%;
background: green;
}
#grandchild_1,
#grandchild_2 {
height: 25px;
background: red;
margin: 10px;
}
<div id="parent">
<div id="child">
<div id="grandchild_1">GC1
</div>
<div id="grandchild_2">GC2
</div>
</div>
</div>
In the following mark up, I simply want to set the negative margin for the .text div so that it appears on the top of the .image div.
<div class="wrap">
<div class="image"><img src="imgage.jpg" /></div>
<div class="text">text with background</div>
</div>
.image {
overflow: hidden;
}
.text{
background: green;
padding: 20px;
margin-top: -60px;
color: #FFFFFF;
overflow: hidden;
}
I have set the background for the .text, but for some reason it does not appear on the image. Only the text appears. You can see the problem here: http://jsfiddle.net/ovkn4egc/
How I can fix it without using the absolute position.
Thanks.
You can simply add position:relative; to .text
DEMO
* {
margin: 0;
padding: 0;
}
.image {
overflow: hidden;
}
.image img {
display: block;
}
.text {
position:relative;
background: green;
padding: 20px;
margin-top: -60px;
color: #FFFFFF;
overflow: hidden;
}
<div class="wrap">
<div class="image">
<img src="https://farm8.staticflickr.com/7550/15615231269_e5a66cbe16_z.jpg" />
</div>
<div class="text">text with background</div>
</div>
Updated to :
<div class="wrap">
<div class="text">text with background</div>
<div class="image">
<img src="https://farm8.staticflickr.com/7550/15615231269_e5a66cbe16_z.jpg" />
</div>
</div>
*{
margin: 0;
padding: 0;
}
.image {
overflow: hidden;
}
.image img{
display: block;
}
.text{
background: green;
padding: 20px;
color: #FFFFFF;
overflow: hidden;
position:relative;
top: 0;
}
http://jsfiddle.net/ovkn4egc/4/
If you want the text to only span the width of the image only, there are a couple of changes more you need to make as below.
I believe this is the behaviour you are after:
DEMO
The HTML has to slightly change like below.
<div class="wrap">
<div class="image">
<img src="https://farm8.staticflickr.com/7550/15615231269_e5a66cbe16_z.jpg" />
<div class="text">text with background</div>
</div>
</div>
The CSS for the image div also has to change to such, where we set the position property to absolute:
.image {
overflow: hidden;
position: absolute;
}
Finally, the position property for the text, has to alter as such:
.text{
background: green;
padding: 20px;
margin-top: -60px;
color: #FFFFFF;
overflow: hidden;
position: relative;
}
Change you css to the below code
*{
margin: 0;
padding: 0;
}
.wrap{position:relative;}
.image {
overflow: hidden;
}
.image img{
display: block;
}
.text{
background: green;
padding: 20px;
top: 0px;
color: #FFFFFF;
overflow: hidden;
position: absolute;
width: 100%;
}
As well as your html to below one
<div class="wrap">
<div class="text">text with background</div>
<div class="image">
<img src="https://farm8.staticflickr.com/7550/15615231269_e5a66cbe16_z.jpg" />
</div>
</div>
I have written .wrap as relative because text div should be compare its position according to wrap div otherwise if you use only absolute for text div then it will be positioned according to body.