Dynamic height auto-resize with css - html

As I can have a div with two children inside, one of which is not shown (display: none) and the other occupies the entire space of the father, but when I tell javascript to display the hidden the other autoredimensiones to space left without using javascript?
html:
<div class="parent">
<div class="child1" id="id1">
</div>
<div class="child2">
</div>
</div>
css:
.parent {
height: 200px;
background-color: red;
}
.child2 {
height: 100%;
background-color: blue;
}
.child1 {
display:none;
height: 50px;
background-color: green;
}
javascript:
var myDiv = document.getElementById('id1');
myDiv.style.display="block";

This can't be achieved with pure CSS, but if you're okay about adding a little more JavaScript (in order to add a class-name), then it can be achieved:
Amended JavaScript:
var myDiv = document.getElementById('id1');
myDiv.style.display = "block";
myDiv.className += ' nowShown';
Appended CSS:
.child1.nowShown {
float: left;
width: 50%;
}
.child1.nowShown + .child2​ {
display: inline-block;
width: 50%;
}​
JS Fiddle proof-of-concept.
Otherwise it's not possible, simply because CSS lacks the capacity to determine the visual/display state of an element. If it had a :visible pseudo-class then it'd be possible, but without such, as currently, it's sadly not.
Adapted the above proof-of-concept to implement a slightly less-than-concise toggle:
function showDiv1() {
var myDiv = document.getElementById('id1'),
cN = myDiv.className;
myDiv.style.display = "block";
if (cN.match(/nowShown/)){
myDiv.className = cN.replace(/nowShown/,'');
myDiv.style.display = 'none';
}
else {
myDiv.className += ' nowShown';
}
nC = myDiv.className;
myDiv.className = nC.replace(/\s{2,}/,' ');
}
document.getElementsByTagName('button')[0].onclick = function(){
showDiv1();
};​
JS Fiddle demo.

Related

Display a Search bar on header on scroll HTML/CSS

I have a search bar which would like to display onto the header on scroll, a great example is like the one on this site: https://www.indiamart.com/
Approach 1 - A simple way to do this would be to detect a scroll & add and remove a class that contains display: none;
You can have an event listener -
window.addEventListener('scroll', function() {
if( window.scrollY !== 0) {
document.getElementById('searchBar').classList.add('scrolled');
} else {
document.getElementById('searchBar').classList.remove('scrolled');
}
});
With the CSS -
.noScroll
{
background: yellow;
position:fixed;
height: 50px; /*Whatever you want*/
width: 100%; /*Whatever you want*/
top:0;
left:0;
display:none;
}
/*Use this class when you want your content to be shown after some scroll*/
.scrolled
{
display: block !important;
}
.parent {
/* something to ensure that the parent container is scrollable */
height: 200vh;
}
And the html would be -
<div class="parent">
<div class ='noScroll' id='searchBar'>Content you want to show on scroll</div>
</div>
Here's a JSFiddle of the same - https://jsfiddle.net/kecnrh3g/
Approach 2 -
Another simple approach would be
<script>
let prevScrollpos = window.pageYOffset;
window.onscroll = function() {
let currentScrollPos = window.pageYOffset;
if (prevScrollpos > currentScrollPos) {
document.getElementById('searchBar').style.top = '-50px';
} else {
document.getElementById('searchBar').style.top = '0';
}
prevScrollpos = currentScrollPos;
}
</script>
with the html -
<div class="parent">
<div id ='searchBar'>Content you want to show on scroll</div>
</div>
and css
#searchBar {
background: yellow;
position: fixed;
top: 0;
left: 0;
height: 50px;
width: 100%;
display: block;
transition: top 0.3s;
}
.parent {
height: 200vh;
}
Here's a JSFiddle of the same - https://jsfiddle.net/0tkedcns/1/
From the same example, the idea is only to show/hide once user scroll the page using inline css display property, you can do the same or at least provide a code sample so we can help you!
HTML
<div class="search-bar">
<div class="sticky-search">
Sticky Search: <input type="text" value="search" />
</div>
</div>
CSS
.sticky-search {
display:none;
position:fixed;
top:0px;
left:0px;
right:0px;
background:blue;
padding:10px;
}
JS
var searchHeight = $(".search-bar").outerHeight();
var offset = $(".search-bar").offset().top;
var totalHeight = searchHeight + offset;
console.log(totalHeight);
$(window).scroll(function(){
if($(document).scrollTop() >= totalHeight) {
$('.sticky-search').show();
} else {
$('.sticky-search').hide();
}
});

rotated image is going out of parent div

I want to rotate the image, but it is going out of parent div.
<div>
<img src="https://cdn.eso.org/images/thumb300y/eso1907a.jpg">
<button class="rotate-button">rotate image</button>
</div>
jquery code
$('.rotate-button').on('click', function() {
var image = $(this).prev('img');
image.className = "rotated_90deg";
});
unrotated state:
rotated state:
how can I keep the image smaller in rotated state, so that it does not go out of parent div?
Try using the solution with scale property
$('.rotate-button').on('click', function() {
var image = $(this).prev('img');
image.className = "rotated_90deg";
});
.rotated_90deg {
transform: rotate(90deg) scale(0.5, 1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<img src="https://cdn.eso.org/images/thumb300y/eso1907a.jpg">
<button class="rotate-button">rotate image</button>
</div>
"tranform rotate" does just that. It retains its original height, and the forging is done in a separate visual layer.
the best thing you can do is set the height of the area where the image rotates equal to the largest side of the image
const img = document.querySelector('img');
const {offsetHeight, offsetWidth} = img;
if(offsetWidth >= offsetHeight) {
img.parentElement.style.height = offsetWidth + 'px';
}
const rotations = [];
const rotateImage = () => {
rotations.push('rotate(45deg)');
img.style.transform = rotations.join(' ');
}
div { display: flex; }
img { transition: .3s; margin: auto; }
button { display: block; margin: auto; position: relative }
<div>
<img src="http://placekitten.com/300/200">
</div>
<button onclick=rotateImage()>Rotate</button>
hmm ... maybe I hastened to answer.
As a solution, "position: relative;" on the button
Put the image inside a container div, give it an id or class and set the overflow to hidden:
.imgContainer{
overflow: hidden;
}
Or if you want the picture to scale so it fits within the div, set max width and height:
.imgContainer img{
max-width: 100%;
max-height: 100%;
}

Why is my paragraph popup coming outside my div with the "mousedown" event?

I need to show my paragraph inside my <div> when click on the <div>. This is my code:
const area = document.getElementById("area");
const popup = document.getElementById("popup");
function showPopup(event) {
let x = event.clientX;
let y = event.clientY;
popup.style.left = `${x}px`;
popup.style.top = `${y}px`;
popup.style.visibility = "visible";
}
area.addEventListener("mousedown", showPopup);
.area {
border: 1px solid;
position: absolute;
height: 200px;
width: 200px;
}
.popup {
visibility: hidden;
position: absolute;
display: inline-block;
}
<div id="area" class="area">
<p class="popup" id="popup">popup</p>
</div>
Note that this is inside another main body <div> (also with position: absolute).
Try this
<div id="area">
<div class="area""
<p class="popup" id="popup">popup</p>
</div>
</div>
I tested your code and observed you are changing style.top property based on your ClientX value which is causing popup element to appear over random position. Use following updated code and it's should be good.
function showPopup(event) {
console.log(event.clientX, event.clientY)
let x = event.clientX;
let y = event.clientY;
popup.style.left = `${x - 8}px`;
popup.style.top = `${y - 8}px`;
popup.style.visibility = "visible";
}
and few CSS changes as -
.area {
border: 1px solid;
position: relative;
height: 200px;
width: 200px;
}
.popup {
visibility: hidden;
position: absolute;
display: inline-block;
margin: 0;
}
For more close positioning of popup element.

Show hidden text on hover (CSS)

I have tried for a while now to show some text on :hover, is anyone able to explain it for me?
I tried:
#DivForHoverItem:hover #HiddenText {
display: block;}
without luck, sadly. This little piece is in every example I found.
I also failed to understand: https://css-tricks.com/forums/topic/show-text-on-hover-with-css/
I try to get <div id="DivForHoverItem"><p>Shown text</p></div>
<div id="HiddenText"><p>Hidden text</p></div>
CSS:
#HiddenText {
display: none;
}
and the code line up there ^
#DivForHoverItem:hover #HiddenText {
display: block;}
The #HiddenText element has to be inside the #DivForHoverItem element if you want to achieve this with CSS. Try something like this:
#DivForHoverItem {
/*just so we can see it*/
height: 50px;
width: 300px;
background-color: red;
}
#HiddenText {
display: none;
}
#DivForHoverItem:hover #HiddenText {
display:block;
}
<div id="DivForHoverItem">
<div id="HiddenText"><p>Hidden text</p></div>
</div>
jsfiddle link for convenience
If you're okay with using JavaScript you could use:
var outDiv = document.getElementById('DivForHoverItem');
var inDiv = document.getElementById('HiddenText');
outDiv.onmouseover = function() {
inDiv.style.display = 'inline';
};
outDiv.onmouseout = function() {
inDiv.style.display = 'none';
};

Is there a way to change the style of a div's :after psuedoelement when hovering over it's :before psuedoelement?

Given the following css:
.myDiv:before{
content:'';
width:15px;
height:15px;
display:block;
}
.myDiv:after{
...
...
display:none;
}
and html:
<div class='myDiv'></div>
Is there a way to show the .myDiv:after psuedoelement while hovering over the :before? I know I can use the hover selector as .myDiv:hover:before but I don't know how to access the :after psuedoelement from within that selector.
You can add a new style to display the content in the :after css class although it may not be the best practice.
.myDiv:hover:after {
display:block;
}
http://jsfiddle.net/gk7R2/1/
The only close way that you can do it is if you hover the entire element like this:
.myDiv {
height: 200px;
background: red;
}
.myDiv:before {
content: '';
display: block;
height: 20px;
width: 100%;
background: blue;
}
.myDiv:hover:after {
content: '';
display: block;
height: 20px;
width: 100%;
background: blue;
}
http://jsfiddle.net/Hive7/W4ca3/
You are not able to trigger the :hover::after from executing a :hover::before. You can solve this problem with javascript though. If you're wanting to maintain a clean markup, you could create a loop within this fiddle and dynamically add placeholders behind the pseudo elements so that you can interact with them instead of trying to access pseudo elements that do not exist in the DOM.
$("head").append("<style id='pseudoElementStyle'></style>");
var setPseudoElementDisplay = function (hover) {
var content = hover ? ' after' : '';
var cssRule = '.text::after { content: "' + content + '"; }';
$('#pseudoElementStyle').text(cssRule);
};
$('.text').prepend('<span class="place-holder before">before </span>');
$('.text').append('<span class="place-holder after"> after</span>');
$('.place-holder').each(function () {
var direction;
var width = $(this).css('width');
direction = $(this).hasClass('before') ? 'left' : 'right';
$(this).css('margin-' + direction, '-' + width);
});
$('.before').mouseover(function () {
setPseudoElementDisplay(true);
}).mouseout(function () {
setPseudoElementDisplay(false);
});
http://jsfiddle.net/jasonjohnson115/2d96N/