Using n inside calc - css

can I use the n variable inside a calc expression?
For example:
.child:nth-child(n) {
margin-left: calc(n * 46px);
}
My Code:
<div class="share-buttons">
<div class="share-button-main"></div>
<div class="share-button share-facebook">
<img src="facebook.png" alt="" />
</div>
<div class="share-button share-whatsapp">
<img src="whatsapp.png" alt="" />
</div>
<div class="share-button share-email">
<img src="email.png" alt="" />
</div>
<div class="share-button share-sms">
<img src="sms.png" alt="" />
</div>
</div>
CSS (Sass):
.share-buttons {
position: relative;
display: flex;
.share-button-main {
width: 46px;
height: 46px;
z-index: 2;
cursor: pointer;
content: url('share-menu-share-closed.png')
}
.share-button {
position: absolute;
top: 0;
left: 0;
width: 46px;
height: 46px;
z-index: 1;
transition: all .3s ease;
opacity: 0;
}
&.open {
.share-button-main {
content: url('share-menu-share-opened.png')
}
.share-button {
opacity: 1;
}
.share-facebook {
left: 56px;
}
.share-whatsapp {
left: 112px;
}
.share-email {
left: 168px;
}
.share-sms {
left: 224px;
}
}
img {
width: 46px;
height: 46px;
}
}
Javascript (JQuery):
$('.share-button-main').click(function() {
$('.share-buttons').toggleClass('open');
});
I'm basically trying to acheive a dynamic opening effect to the menu so if I add or remove elements it'll still work (and not like now when I set each div's left separately).

Not exactly what you may be after, but you can achieve a similar effect with scss if you know the number of elements. Just bear in mind that this will generate a lot of css:
#for $i from 1 through 7 {
&:nth-child(#{$i}) {
margin-left: calc(#{$i} * 46px);
}
}

No; you can't do that.
The counter feature can almost do that, except that it can't be used with calc() either.

You can't, as mentioned by #SLaks. But this can be solved by placing each next element inside the previous one.
See with divs:
div {
margin-left: 46px
}
<div>test
<div>test
<div>test
<div>test</div>
</div>
</div>
</div>
Or, use jQuery.
var margin=0;
$("div").each(function(){
$(this).css("margin-left",margin+=46)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>text</div>
<div>text</div>
<div>text</div>
<div>text</div>
<div>text</div>

Related

clip-path not working as expected in Chrome (works in Firefox and Safari)

I have been trying to find a workaround to overflow:hidden not applying to fixed elements, and I came across clip and clip-path. As clip is deprecated, I am trying to use clip-path to create the desired effect. I have successfully created the effect I am looking for in both Firefox and Safari, but the clip-path function does not appear to be working in Chrome.
I've included the current HTML and CSS below; the desired effect is for each title and subtitle to only be visible when their respective parent element is in view. If you are viewing on Firefox or Safari this should be working appropriately. However, if viewing on Chrome you should see that the clip-path function is not applying and therefore you can see both titles and subtitles at the same time when viewing the first parent element (the turquoise rectangle).
As you can see in the code, I am using clip-path: fill-box which works in both Firefox and Safari, but not Chrome. I've also tried inset(0), which still works in FF/Safari but it too fails in Chrome.
* {
padding: 0;
margin: 0;
border: none;
}
html {
background-color: black;
}
.info {
list-style-type: none;
margin-left: 13vw;
padding: 0;
overflow: hidden;
position: fixed;
color: white;
z-index: -1;
top: 80vh;
}
.container {
width: 100%;
height: 110vh;
}
.parent {
position: absolute;
width: 100%;
height: 110vh;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
pointer-events: none;
clip-path: fill-box;
}
.parent_1 {
background-color: turquoise;
}
.parent_2 {
background-color: tomato;
}
.parent_3 {
background-color: purple;
}
.subchild {
position: fixed;
color: white;
width: 60vw;
left: 14vw;
}
.p1, .p3 {
top: 40vh;
}
.p2 {
top: 45vh;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test</title>
<link href="css/clip.css" rel="stylesheet" type="text/css">
</head>
<body>
<section class="container container_1">
<Div class="parent parent_1">
<Div class="child child_1">
<p class="subchild p1">
First Title
</p>
<p class="subchild p2">
First Subtitle
</p>
</Div>
</Div>
</section>
<section class="container container_2">
<Div class="parent parent_2">
<Div class="child child_2">
<p class="subchild p3">
Second Title
</p>
<p class="subchild p2">
Second Subtitle
</p>
</Div>
</Div>
</section>
</body>
</html>
I decided to play a little with Javascript. I've changed a little the HTML and the CSS. The subchilds are positioned top: 150px;.
function getY(element) {
var rect = element.getBoundingClientRect();
return rect.bottom;
}
let container1 = document.querySelector(".container_1");
let container2 = document.querySelector(".container_2");
let container3 = document.querySelector(".container_3");
let subchild1 = document.querySelector(".container_1 .subchild");
let subchild2 = document.querySelector(".container_2 .subchild");
let subchild3 = document.querySelector(".container_3 .subchild");
document.addEventListener('scroll', function() {
let bottom1 = getY(container1);
let bottom2 = getY(container2);
let bottom3 = getY(container3);
if ((bottom1 > 166) && (bottom2 > 166) && (bottom3 > 166)) {
subchild1.style.display = "block";
}
else {
subchild1.style.display = "none";
}
//
if ((bottom1 < 166) && (bottom2 > 166) && (bottom3 > 166)) {
subchild2.style.display = "block";
}
else {
subchild2.style.display = "none";
}
//
if ((bottom1 < 166) && (bottom2 < 166) && (bottom3 > 166)) {
subchild3.style.display = "block";
}
else {
subchild3.style.display = "none";
}
});
* {
padding: 0;
margin: 0;
border: none;
}
html {
background-color: black;
}
.info {
list-style-type: none;
margin-left: 13vw;
padding: 0;
overflow: hidden;
position: fixed;
color: white;
z-index: -1;
top: 80vh;
}
.container {
width: 100%;
height: 110vh;
}
.parent {
position: absolute;
width: 100%;
height: 110vh;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
pointer-events: none;
}
.parent_1 {
background-color: turquoise;
}
.parent_2 {
background-color: tomato;
}
.parent_3 {
background-color: purple;
}
.subchild {
position: fixed;
color: white;
width: 60vw;
left: 14vw;
top: 150px;
}
.container_1 .subchild {
display: block;
}
.container_2 .subchild {
display: none;
}
.container_3 .subchild {
display: none;
}
<section class="container container_1">
<Div class="parent parent_1">
<Div class="child child_1">
<p class="subchild">
First Title
</p>
</Div>
</Div>
</section>
<section class="container container_2">
<Div class="parent parent_2">
<Div class="child child_2">
<p class="subchild">
Second Title
</p>
</Div>
</Div>
</section>
<section class="container container_3">
<Div class="parent parent_3">
<Div class="child child_3">
<p class="subchild">
Third Title
</p>
</Div>
</Div>
</section>

Unable to prevent :hover from repeatedly firing

I've got the following code. When the user hovers over the div, it should drop and stay that way until the user has hovered off of the div. When on the div, even if you move your mouse a bit, the hover action keeps firing.
html
<div class="whitelabelfeatures">
<div class="box1 requirements responsibilities">
<div class="responsibilitiesbox">
<div class="responsibility">
<div class="section1">
Pricing
</div>
<div class="section1a">
Pricing test
</div>
</div>
</div>
</div>
</div>
css
.box1.requirements.responsibilities {
height: 300px;
overflow: hidden;
}
.responsibility .section1 {
background-color: #c2bbb1;
height: 300px;
color: white;
font-weight: 700;
position: relative;
z-index: 2;
transition: all .3s ease;
}
.responsibility .section1:hover {
transform: translateY(300px);
}
.responsibility .section1a {
position: absolute;
z-index: 1;
top: 0;
}
codepen
https://codepen.io/jasonhoward64/pen/YzKNxVN
Thanks!
You can use javascript here. Please see below code.
var targetDiv = document.getElementsByClassName("section1")[0];
targetDiv.addEventListener('mouseenter', function(){
targetDiv.classList.add('section1mouseover');
});
var testDiv = document.getElementsByClassName("section1a")[0];
testDiv.addEventListener('mouseenter', function(){
targetDiv.classList.remove('section1mouseover');
});
.box1.requirements.responsibilities {
height: 300px;
overflow: hidden;
}
.responsibility .section1 {
background-color: #c2bbb1;
height: 300px;
color: white;
font-weight: 700;
position: relative;
z-index: 2;
transition: all .3s ease;
}
.section1mouseover {
transform: translateY(300px);
}
.responsibility .section1a {
position: absolute;
z-index: 1;
top: 0;
}
<div class="whitelabelfeatures">
<div class="box1 requirements responsibilities">
<div class="responsibilitiesbox">
<div class="responsibility">
<div class="section1">
Pricing
</div>
<div class="section1a">
Pricing test
</div>
</div>
</div>
</div>
</div>
The problem is that your :hover needs to be actuated higher in the DOM. With your current code, when you hover over the .section1 element, once the CSS transform takes place and translates the .section1 element vertically, the cursor is both "off" and "over" the transforming element, which causes the :hover to trigger on and off in response.
So in your codepen, on line 17, change your hover to the parent element and it should work.
Instead of:
.responsibility .section1:hover, try .responsibility:hover .section1

Displaying images under slideshow

I find it quite hard to explain, but I have made a demo here:
http://plnkr.co/edit/X0X4RAFjnUX7LzBL1R6p?p=preview
Basically I have 2 columns that are side-by-side. When the page gets smaller, the columns go under each other. One of the columns has a slider plugin where the image change. The wrapper has a relative position so it changes size. The images inside use an absolute position for the slider to work.
Under those images I want 3 separate images that always stay under. Unfortunately, I can only get them to appear either on the main image, or under the layer (not positioned below).
Here's the entire code:
var timer = setInterval(nextImage, 4000);
var curImage = 0;
var numImages = 3;
function nextImage() {
var e;
// remove showMe class from current image
e = document.getElementById("slideimg" + curImage);
removeClass(e, "showMe");
// compute next image
curImage++;
if (curImage > numImages - 1) {
curImage = 0;
}
// add showMe class to next image
e = document.getElementById("slideimg" + curImage);
addClass(e, "showMe");
}
function addClass(elem, name) {
var c = elem.className;
if (c) c += " "; // if not blank, add a space separator
c += name;
elem.className = c;
}
function removeClass(elem, name) {
var c = elem.className;
elem.className = c.replace(name, "").replace(/ /g, " ").replace(/^ | $/g, ""); // remove name and extra blanks
}
body,
html {
height: 100%
}
body {
min-height: 100%;
background-position: center;
background-size: cover;
font-family: 'Lato', sans-serif;
font-weight: 400;
margin: 0;
}
#content {
max-width: 1750px;
margin-left: auto;
margin-right: auto;
}
* {
box-sizing: border-box;
}
/* Create two equal columns that floats next to each other */
.column {
float: left;
width: 50%;
padding-top: 20px;
padding-bottom: 20px;
padding-left: 30px;
padding-right: 30px;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
/* Responsive layout - makes the two columns stack on top of each other instead of next to each other */
#media screen and (max-width: 900px) {
.column {
width: 100%;
}
}
.homepage-main-img-wrapper {
position: relative;
right: 0;
left: 0;
margin: auto;
height: 100%;
}
.homepage-main-img {
width: 100%;
border: 2px solid #194d98;
outline: 2px solid #0c7d5f;
}
.slide {
border: none;
opacity: 0;
position: absolute;
top: 0;
left: 0;
-webkit-transition: opacity 2s linear;
-moz-transition: opacity 2s linear;
-o-transition: opacity 2s linear;
transition: opacity 2s linear;
}
.showMe {
opacity: 1;
}
<html lang="et" xml:lang="et">
<body>
<div id="container">
<div id="content">
<div class="row">
<div class="column" style="background-color:#aaa;">
<div>stuff</div>
</div>
<div class="column container2">
<div class="homepage-main-img-wrapper">
<img id="slideimg0" class="slide homepage-main-img showMe" src="https://i.imgur.com/n3oGBvR.jpg">
<img id="slideimg1" class="slide homepage-main-img" src="https://i.imgur.com/Ak7Ykl8.jpg">
<img id="slideimg2" class="slide homepage-main-img" src="https://i.imgur.com/tSmA8zP.jpg">
</div>
<div id="test" style="
position: relative;
">
<div id="instagram-feed" class="instagram_feed">
<div class="instagram_gallery">
<img src="https://i.imgur.com/aoaWgFY.jpg" style="margin:0.5% 0.5%;width:32.333333333333336%;float:left;">
<img src="https://i.imgur.com/41i7fue.jpg" style="margin:0.5% 0.5%;width:32.333333333333336%;float:left;">
<img src="https://i.imgur.com/ITSAyjN.jpg" style="margin:0.5% 0.5%;width:32.333333333333336%;float:left;">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Since the height of the images change when the browser is resized, you can take an existing image or transparent image with the same "homepage-main-img" class so that the scale is the same on browser resize.
I also removed the position:relative from your id test div.
Change your HTML to be the following in the HTML block. JS and CSS remains untouched. Just added for the snippit to work.
var timer = setInterval(nextImage, 4000);
var curImage = 0;
var numImages = 3;
function nextImage() {
var e;
// remove showMe class from current image
e = document.getElementById("slideimg" + curImage);
removeClass(e, "showMe");
// compute next image
curImage++;
if (curImage > numImages - 1) {
curImage = 0;
}
// add showMe class to next image
e = document.getElementById("slideimg" + curImage);
addClass(e, "showMe");
}
function addClass(elem, name) {
var c = elem.className;
if (c) c += " "; // if not blank, add a space separator
c += name;
elem.className = c;
}
function removeClass(elem, name) {
var c = elem.className;
elem.className = c.replace(name, "").replace(/ /g, " ").replace(/^ | $/g, ""); // remove name and extra blanks
}
body,
html {
height: 100%
}
body {
min-height: 100%;
background-position: center;
background-size: cover;
font-family: 'Lato', sans-serif;
font-weight: 400;
margin: 0;
}
#content {
max-width: 1750px;
margin-left: auto;
margin-right: auto;
}
* {
box-sizing: border-box;
}
/* Create two equal columns that floats next to each other */
.column {
float: left;
width: 50%;
padding-top: 20px;
padding-bottom: 20px;
padding-left: 30px;
padding-right: 30px;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
/* Responsive layout - makes the two columns stack on top of each other instead of next to each other */
#media screen and (max-width: 900px) {
.column {
width: 100%;
}
}
.homepage-main-img-wrapper {
position: relative;
right: 0;
left: 0;
margin: auto;
height: 100%;
}
.homepage-main-img {
width: 100%;
border: 2px solid #194d98;
outline: 2px solid #0c7d5f;
}
.slide {
border: none;
opacity: 0;
position: absolute;
top: 0;
left: 0;
-webkit-transition: opacity 2s linear;
-moz-transition: opacity 2s linear;
-o-transition: opacity 2s linear;
transition: opacity 2s linear;
}
.showMe {
opacity: 1;
}
<div id="container">
<div id="content">
<div class="row">
<div class="column" style="background-color:#aaa;">
<div>stuff</div>
</div>
<div class="column container2">
<div class="homepage-main-img-wrapper">
<img id="slideimg0" class="slide homepage-main-img showMe" src="https://i.imgur.com/n3oGBvR.jpg">
<img id="slideimg1" class="slide homepage-main-img" src="https://i.imgur.com/Ak7Ykl8.jpg">
<img id="slideimg2" class="slide homepage-main-img" src="https://i.imgur.com/tSmA8zP.jpg">
</div>
<div id="test"><img id="fakeslide" class="homepage-main-img" src="https://i.imgur.com/n3oGBvR.jpg">
<div id="instagram-feed" class="instagram_feed">
<div class="instagram_gallery">
<img src="https://i.imgur.com/aoaWgFY.jpg" style="margin:0.5% 0.5%;width:32.333333333333336%;float:left;">
<img src="https://i.imgur.com/41i7fue.jpg" style="margin:0.5% 0.5%;width:32.333333333333336%;float:left;">
<img src="https://i.imgur.com/ITSAyjN.jpg" style="margin:0.5% 0.5%;width:32.333333333333336%;float:left;">
</div>
</div>
</div>
</div>
</div>
</div>
</div>

CSS doesn't shows when load a component

I'm working with mapbox and my problem is that it doesn't shows me the map as should be.
If I load the component in render directly (example 1) it works and shows the map perfectly but if I load the component when change the state (example 2) doesn't shows me well.
render() {
return (
<div className="App">
<div className="NavBar">
<NavbarComponent parentNavbar={this.doParentNavbar} />
</div>
<div className="Map">
<MapComponent />
</div>
</div>
);
}
Example 2
render() {
return (
<div className="App">
<div className="NavBar">
<NavbarComponent parentNavbar={this.doParentNavbar} />
</div>
<div className="Map">
{
(this.state.nameMap) ? <MapComponent /> : null
}
</div>
</div>
);
}
CSS File:
.NavBar {
position: relative !important;
z-index: 9999 !important;
}
.Map {
position: absolute !important;
width: 100% !important;
height: 100% !important;
overflow: visible !important;
z-index: -9999 !important;
}
.mapboxgl-canvas {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
height: 100%;
}
sorry, I'm so stupid....
In App.css I forgot this:
body {
height: 100vh;
margin: 0;
padding: 0;
font-family: sans-serif;
}

overlay a div over another one with css

I have a wrapper div that has some css property set. on click of a button i have to show an overly with some message.
<div class="dvLanding">
<div class="popupArea">
<span class="VoteOnce">You can only vote once.</span> <a style="vertical-align: top">
<img alt="close" src="../../Images/error1-exit-button.png" /></a></div></div>
</div>
my css classes.
.dvVoteWrapper
{
background-color: #949494;
opacity: 0.5;
filter: Alpha(opacity=50);
display:none;
width: 1024px;
height: 768px;
position: absolute;
}
.popupArea
{
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.dvLanding
{
background-image: url(/Images/screen1-bg-logos.jpg);
background-repeat: no-repeat;
position: absolute;
width: 100%;
height: 100%;
}
.VoteOnce
{
font-family: Calibri regular;
font-size: 24pt;
background-image: url(/Images/error1-vote-once-bg.png);
background-repeat: no-repeat;
width:288px;
height:74px;
color: #000000;
}
i am removing the display:none attribute with jquery. When applying this classes it is not covering the full page and looking distorted. kindly suggest how to do this. for better understanding i have attached the screen shots
Here's another one
HTML:
<div class="dvLanding">
<div class="dvVolunter"></div>
<div class="dvVote">
<br />
<br />
</div>
<div class="dvVoteWrapper"></div>
</div>
<div class="popupArea">
<span class="VoteOnce">You can only vote once.
<a class="closeButton">
<img alt="close" src="../../Images/error1-exit-button.png" />
</a>
</span>
</div>
CSS:
.dvLanding {
background-image: url(http://lorempixel.com/800/600);
position: absolute;
width: 100%;
height: 100%;
opacity: 0.5;
}
.popupArea {
background-color: yellow;
position: absolute;
top: 50%;
left: 50%;
margin-top: -30px;
margin-left: -180px;
}
.closeButton {
vertical-align: top;
font-size: 10pt;
}
.VoteOnce {
font-family: Calibri regular;
font-size: 24pt;
}
JSFiddle for testing.
If you want the wrapper to cover the whole screen you can use:
position:fixed; left:0; top:0; z-index:100; width:100%; height:100%;
Your z-index property will need to be higher than any of the elements below it that you are trying to cover

Resources