Search code examples
javascriptjqueryhtmlcsswebkit

CSS added dynamically does not apply to HTML elements


I am working on creating a 3D carousel (using CSS) which is loaded when a user clicks a button. I have the carousel working on its own (i.e carousel loads when the page is opened) but when I try to activate the carousel dynamically via a button click, the styles are not applied.

Below is the code that works. The carousel loads up when the page loads and you can see that it works very nicely.

body > div {
		width: 500px;
		margin: 50px auto;
		text-align: center;
}

figure {
	margin: 0;
}

.container {
	width: 500px;
	height: 300px;
	text-align: left;
	margin: 60px auto;
	-webkit-perspective: 1000px;
	-webkit-perspective-origin: 50% -25%;
}

.carousel {
	-webkit-transform-style: preserve-3d;
	-webkit-transform: translateZ(-540px);
	position: relative;
	margin: 0;
	width: 500px;
	-webkit-transition: 1s;
}

.carousel div {
    display: inline-block !important;
    height: auto !important;
	position: absolute;
    opacity: 0.9;
    text-align: center;
	-webkit-transition: 1s;
    width: 500px;
    height: 300px;
    background-color:rgba(203,203,203,0.5);
    border-style: solid;
}

.carousel div:nth-child(1) { -webkit-transform: translateZ(540px) scale(.8); }
.carousel div:nth-child(2) { -webkit-transform: rotateY(45deg) translateZ(540px) scale(.8); }
.carousel div:nth-child(3) { -webkit-transform: rotateY(90deg) translateZ(540px) scale(.8); }
.carousel div:nth-child(4) { -webkit-transform: rotateY(135deg) translateZ(540px) scale(.8); }
.carousel div:nth-child(5) { -webkit-transform: rotateY(180deg) translateZ(540px) scale(.8); }
.carousel div:nth-child(6) { -webkit-transform: rotateY(225deg) translateZ(540px) scale(.8); }
.carousel div:nth-child(7) { -webkit-transform: rotateY(270deg) translateZ(540px) scale(.8); }
.carousel div:nth-child(8) { -webkit-transform: rotateY(315deg) translateZ(540px) scale(.8); }

label {
	cursor: pointer;
	background: #eee;
	display: inline-block;
	border-radius: 50%;
	width: 30px;
	padding-top: 7px;
	height: 23px;
	font: .9em Arial;
}

label:hover {
	background: #ddd;
}

input {
	position: absolute;
	left: -9999px;
}

input:checked + label {
	font-weight: bold;
	background: #ddd;
}

input[value="1"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px); }
input[value="2"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-45deg); }
input[value="3"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-90deg); }
input[value="4"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-135deg); }
input[value="5"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-180deg); }
input[value="6"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-225deg); }
input[value="7"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-270deg); }
input[value="8"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-315deg); }

input[value="1"]:checked ~ .container .carousel img:nth-child(1) { -webkit-transform: translateZ(540px) scale(1); opacity: 1; }
input[value="2"]:checked ~ .container .carousel img:nth-child(2) { -webkit-transform: rotateY(45deg) translateZ(540px) scale(1); opacity: 1; }
input[value="3"]:checked ~ .container .carousel img:nth-child(3) { -webkit-transform: rotateY(90deg) translateZ(540px) scale(1); opacity: 1; }
input[value="4"]:checked ~ .container .carousel img:nth-child(4) { -webkit-transform: rotateY(135deg) translateZ(540px) scale(1); opacity: 1; }
input[value="5"]:checked ~ .container .carousel img:nth-child(5) { -webkit-transform: rotateY(180deg) translateZ(540px) scale(1); opacity: 1; }
input[value="6"]:checked ~ .container .carousel img:nth-child(6) { -webkit-transform: rotateY(225deg) translateZ(540px) scale(1); opacity: 1; }
input[value="7"]:checked ~ .container .carousel img:nth-child(7) { -webkit-transform: rotateY(270deg) translateZ(540px) scale(1); opacity: 1; }
input[value="8"]:checked ~ .container .carousel img:nth-child(8) { -webkit-transform: rotateY(315deg) translateZ(540px) scale(1); opacity: 1; }
<body>

  <div>

    <input checked id="one" name="multiples" type="radio" value="1">
    <label for="one">1</label>

    <input id="two" name="multiples" type="radio" value="2">
    <label for="two">2</label>

    <input id="three" name="multiples" type="radio" value="3">
    <label for="three">3</label>

    <input id="four" name="multiples" type="radio" value="4">
    <label for="four">4</label>

    <input id="five" name="multiples" type="radio" value="5">
    <label for="five">5</label>

    <input id="six" name="multiples" type="radio" value="6">
    <label for="six">6</label>

    <input id="seven" name="multiples" type="radio" value="7">
    <label for="seven">7</label>

    <input id="eight" name="multiples" type="radio" value="8">
    <label for="eight">8</label>

    <div class="container">
      <div class="carousel">
        <div class="member">
          <img src="" style="margin:auto">
          <h4>john</h4>
          <p style="text-align:center">has the following info</p>
        </div>
        <div class="member">
          <img src="" style="margin:auto">
          <h4>john</h4>
          <p style="text-align:center">has the following info</p>
        </div>
        <div class="member">
          <img src="" style="margin:auto">
          <h4>john</h4>
          <p style="text-align:center">has the following info</p>
        </div>
        <div class="member">
          <img src="" style="margin:auto">
          <h4>john</h4>
          <p style="text-align:center">has the following info</p>
        </div>
        <div class="member">
          <img src="" style="margin:auto">
          <h4>John</h4>
          <p style="text-align:center">has the following info</p>
        </div>
        <div class="member">
          <img src="" style="margin:auto">
          <h4>John</h4>
          <p style="">has the following info</p>
        </div>
        <div class="member">
          <img src="" style="margin:auto">
          <h4>John</h4>
          <p style="">has the following info</p>
        </div>
        <div class="member">
          <img src="" style="margin:auto">
          <h4>John</h4>
          <p style="text-align:center">has the following info</p>
        </div>
      </div>
    </div>

  </div>

</body>

And here is the code that does not work:

function load() {
  $("#activate-carousel-button").hide();
  $('#nav1').css('visibility', 'visible');
  $('head').append('<link rel="stylesheet" type="text/css" href="test.css" />');
  console.log("done");

}
body > div {
		width: 500px;
		margin: 50px auto;
		text-align: center;
}

figure {
	margin: 0;
}

.container {
	width: 500px;
	height: 300px;
	text-align: left;
	margin: 60px auto;
	-webkit-perspective: 1000px;
	-webkit-perspective-origin: 50% -25%;
}

.carousel {
	-webkit-transform-style: preserve-3d;
	-webkit-transform: translateZ(-540px);
	position: relative;
	margin: 0;
	width: 500px;
	-webkit-transition: 1s;
}

.carousel div {
    display: inline-block !important;
    height: auto !important;
	position: absolute;
    opacity: 0.9;
    text-align: center;
	-webkit-transition: 1s;
    width: 500px;
    height: 300px;
    background-color:rgba(203,203,203,0.5);
    border-style: solid;
}

.carousel div:nth-child(1) { -webkit-transform: translateZ(540px) scale(.8); }
.carousel div:nth-child(2) { -webkit-transform: rotateY(45deg) translateZ(540px) scale(.8); }
.carousel div:nth-child(3) { -webkit-transform: rotateY(90deg) translateZ(540px) scale(.8); }
.carousel div:nth-child(4) { -webkit-transform: rotateY(135deg) translateZ(540px) scale(.8); }
.carousel div:nth-child(5) { -webkit-transform: rotateY(180deg) translateZ(540px) scale(.8); }
.carousel div:nth-child(6) { -webkit-transform: rotateY(225deg) translateZ(540px) scale(.8); }
.carousel div:nth-child(7) { -webkit-transform: rotateY(270deg) translateZ(540px) scale(.8); }
.carousel div:nth-child(8) { -webkit-transform: rotateY(315deg) translateZ(540px) scale(.8); }

label {
	cursor: pointer;
	background: #eee;
	display: inline-block;
	border-radius: 50%;
	width: 30px;
	padding-top: 7px;
	height: 23px;
	font: .9em Arial;
}

label:hover {
	background: #ddd;
}

input {
	position: absolute;
	left: -9999px;
}

input:checked + label {
	font-weight: bold;
	background: #ddd;
}

input[value="1"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px); }
input[value="2"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-45deg); }
input[value="3"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-90deg); }
input[value="4"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-135deg); }
input[value="5"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-180deg); }
input[value="6"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-225deg); }
input[value="7"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-270deg); }
input[value="8"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-315deg); }

input[value="1"]:checked ~ .container .carousel img:nth-child(1) { -webkit-transform: translateZ(540px) scale(1); opacity: 1; }
input[value="2"]:checked ~ .container .carousel img:nth-child(2) { -webkit-transform: rotateY(45deg) translateZ(540px) scale(1); opacity: 1; }
input[value="3"]:checked ~ .container .carousel img:nth-child(3) { -webkit-transform: rotateY(90deg) translateZ(540px) scale(1); opacity: 1; }
input[value="4"]:checked ~ .container .carousel img:nth-child(4) { -webkit-transform: rotateY(135deg) translateZ(540px) scale(1); opacity: 1; }
input[value="5"]:checked ~ .container .carousel img:nth-child(5) { -webkit-transform: rotateY(180deg) translateZ(540px) scale(1); opacity: 1; }
input[value="6"]:checked ~ .container .carousel img:nth-child(6) { -webkit-transform: rotateY(225deg) translateZ(540px) scale(1); opacity: 1; }
input[value="7"]:checked ~ .container .carousel img:nth-child(7) { -webkit-transform: rotateY(270deg) translateZ(540px) scale(1); opacity: 1; }
input[value="8"]:checked ~ .container .carousel img:nth-child(8) { -webkit-transform: rotateY(315deg) translateZ(540px) scale(1); opacity: 1; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <div class="inner">
    <div>
      <img src="Images/logo.png" height="130" width="120"></img>
    </div>
    <div id='nav1' style="visibility:hidden">
      <input checked id="one" name="multiples" type="radio" value="1">
      <label for="one">1</label>
      <input id="two" name="multiples" type="radio" value="2">
      <label for="two">2</label>
      <input id="three" name="multiples" type="radio" value="3">
      <label for="three">3</label>
      <input id="four" name="multiples" type="radio" value="4">
      <label for="four">4</label>
      <input id="five" name="multiples" type="radio" value="5">
      <label for="five">5</label>
      <input id="six" name="multiples" type="radio" value="6">
      <label for="six">6</label>
      <input id="seven" name="multiples" type="radio" value="7">
      <label for="seven">7</label>
      <input id="eight" name="multiples" type="radio" value="8">
      <label for="eight">8</label>
    </div>
    <div class="container" style="padding:8px">
      <div class="carousel">
        <div class="member">
          <img src="" style="margin:auto">
          <h4>john</h4>
          <p style="text-align:center">has the following info</p>
        </div>
        <div class="member">
          <img src="" style="margin:auto">
          <h4>john</h4>
          <p style="text-align:center">has the following info</p>
        </div>
        <div class="member">
          <img src="" style="margin:auto">
          <h4>john</h4>
          <p style="text-align:center">has the following info</p>
        </div>
        <div class="member">
          <img src="" style="margin:auto">
          <h4>john</h4>
          <p style="text-align:center">has the following info</p>
        </div>
        <div class="member">
          <img src="" style="margin:auto">
          <h4>John</h4>
          <p style="text-align:center">has the following info</p>
        </div>
        <div class="member">
          <img src="" style="margin:auto">
          <h4>John</h4>
          <p style="">has the following info</p>
        </div>
        <div class="member">
          <img src="" style="margin:auto">
          <h4>John</h4>
          <p style="">has the following info</p>
        </div>
        <div class="member">
          <img src="" style="margin:auto">
          <h4>John</h4>
          <p style="text-align:center">has the following info</p>
        </div>
      </div>
    </div>
    <div id="activate-carousel-button">
      <button type="button" onclick="load();" class="btn btn-default">Click to activate carousel controls</button>
    </div>
  </div>
</body>

The aim for the above code is as follows: When the users clicks the button, the html is generated and placed into the DOM, and then the CCS stylesheet to define the carousel is appended to the head of the html element. In my above example, only the carousel controls are shown when the user clicks the button and the CSS styles are reapplied, but the point stands that the carousel doesn't work.

I believe that the source of the problem is the fact that the buttons to control the carousel don't work. It seems their webkit properties are being overwritten somehow (see the browser developer tools - I saw it in chrome).

I believe this is a specificity problem within the CSS.

What I've tried:

Changing all the class selectors to ID selectors and changing the relevant HTML to use id rather than class. i.e <div class="carousel"> becomes <div id="carousel">. I did this because I thought id selectors are the most specific thing so they shouldn't be overwritten. This however didn't work.

I also tried adding !important to all the webkit properties since this should force the browser to use them over everything. However, this didn't work either.

What could be causing this and how can I fix it?

EDIT: I also tried adding the following line to my js code:

$('.inner').trigger('create');

Which didn't work either.

EDIT2:

I also tried this in an attempt to force a refresh of the CSS:

$('.inner').css('display','block');

But this didn't work either


Solution

  • Your CSS selectors are no longer matching because you put the inputs and labels inside #nav1. If you really want to continue using CSS for this you can remove the #nav1 and hide all the inputs and labels separately:

    $('[name=multiples], [name=multiples] + label').css('visibility', 'hidden');
    
    function load() {
      $("#activate-carousel-button").hide();
      $('[name=multiples], [name=multiples] + label').css('visibility', 'visible');
      $('head').append('<link rel="stylesheet" type="text/css" href="test.css" />');
      console.log("done");
    }
    

    $('[name=multiples], [name=multiples] + label').css('visibility', 'hidden');
    
    function load() {
      $("#activate-carousel-button").hide();
      $('[name=multiples], [name=multiples] + label').css('visibility', 'visible');
      $('head').append('<link rel="stylesheet" type="text/css" href="test.css" />');
      console.log("done");
    }
    body > div {
    		width: 500px;
    		margin: 50px auto;
    		text-align: center;
    }
    
    figure {
    	margin: 0;
    }
    
    .container {
    	width: 500px;
    	height: 300px;
    	text-align: left;
    	margin: 60px auto;
    	-webkit-perspective: 1000px;
    	-webkit-perspective-origin: 50% -25%;
    }
    
    .carousel {
    	-webkit-transform-style: preserve-3d;
    	-webkit-transform: translateZ(-540px);
    	position: relative;
    	margin: 0;
    	width: 500px;
    	-webkit-transition: 1s;
    }
    
    .carousel div {
        display: inline-block !important;
        height: auto !important;
    	position: absolute;
        opacity: 0.9;
        text-align: center;
    	-webkit-transition: 1s;
        width: 500px;
        height: 300px;
        background-color:rgba(203,203,203,0.5);
        border-style: solid;
    }
    
    .carousel div:nth-child(1) { -webkit-transform: translateZ(540px) scale(.8); }
    .carousel div:nth-child(2) { -webkit-transform: rotateY(45deg) translateZ(540px) scale(.8); }
    .carousel div:nth-child(3) { -webkit-transform: rotateY(90deg) translateZ(540px) scale(.8); }
    .carousel div:nth-child(4) { -webkit-transform: rotateY(135deg) translateZ(540px) scale(.8); }
    .carousel div:nth-child(5) { -webkit-transform: rotateY(180deg) translateZ(540px) scale(.8); }
    .carousel div:nth-child(6) { -webkit-transform: rotateY(225deg) translateZ(540px) scale(.8); }
    .carousel div:nth-child(7) { -webkit-transform: rotateY(270deg) translateZ(540px) scale(.8); }
    .carousel div:nth-child(8) { -webkit-transform: rotateY(315deg) translateZ(540px) scale(.8); }
    
    label {
    	cursor: pointer;
    	background: #eee;
    	display: inline-block;
    	border-radius: 50%;
    	width: 30px;
    	padding-top: 7px;
    	height: 23px;
    	font: .9em Arial;
    }
    
    label:hover {
    	background: #ddd;
    }
    
    input {
    	position: absolute;
    	left: -9999px;
    }
    
    input:checked + label {
    	font-weight: bold;
    	background: #ddd;
    }
    
    input[value="1"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px); }
    input[value="2"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-45deg); }
    input[value="3"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-90deg); }
    input[value="4"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-135deg); }
    input[value="5"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-180deg); }
    input[value="6"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-225deg); }
    input[value="7"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-270deg); }
    input[value="8"]:checked ~ .container .carousel { -webkit-transform: translateZ(-540px) rotateY(-315deg); }
    
    input[value="1"]:checked ~ .container .carousel img:nth-child(1) { -webkit-transform: translateZ(540px) scale(1); opacity: 1; }
    input[value="2"]:checked ~ .container .carousel img:nth-child(2) { -webkit-transform: rotateY(45deg) translateZ(540px) scale(1); opacity: 1; }
    input[value="3"]:checked ~ .container .carousel img:nth-child(3) { -webkit-transform: rotateY(90deg) translateZ(540px) scale(1); opacity: 1; }
    input[value="4"]:checked ~ .container .carousel img:nth-child(4) { -webkit-transform: rotateY(135deg) translateZ(540px) scale(1); opacity: 1; }
    input[value="5"]:checked ~ .container .carousel img:nth-child(5) { -webkit-transform: rotateY(180deg) translateZ(540px) scale(1); opacity: 1; }
    input[value="6"]:checked ~ .container .carousel img:nth-child(6) { -webkit-transform: rotateY(225deg) translateZ(540px) scale(1); opacity: 1; }
    input[value="7"]:checked ~ .container .carousel img:nth-child(7) { -webkit-transform: rotateY(270deg) translateZ(540px) scale(1); opacity: 1; }
    input[value="8"]:checked ~ .container .carousel img:nth-child(8) { -webkit-transform: rotateY(315deg) translateZ(540px) scale(1); opacity: 1; }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <body>
      <div class="inner">
        <div>
          <img src="Images/logo.png" height="130" width="120"></img>
        </div>
          <input checked id="one" name="multiples" type="radio" value="1">
          <label for="one">1</label>
          <input id="two" name="multiples" type="radio" value="2">
          <label for="two">2</label>
          <input id="three" name="multiples" type="radio" value="3">
          <label for="three">3</label>
          <input id="four" name="multiples" type="radio" value="4">
          <label for="four">4</label>
          <input id="five" name="multiples" type="radio" value="5">
          <label for="five">5</label>
          <input id="six" name="multiples" type="radio" value="6">
          <label for="six">6</label>
          <input id="seven" name="multiples" type="radio" value="7">
          <label for="seven">7</label>
          <input id="eight" name="multiples" type="radio" value="8">
          <label for="eight">8</label>
        <div class="container" style="padding:8px">
          <div class="carousel">
            <div class="member">
              <img src="" style="margin:auto">
              <h4>john</h4>
              <p style="text-align:center">has the following info</p>
            </div>
            <div class="member">
              <img src="" style="margin:auto">
              <h4>john</h4>
              <p style="text-align:center">has the following info</p>
            </div>
            <div class="member">
              <img src="" style="margin:auto">
              <h4>john</h4>
              <p style="text-align:center">has the following info</p>
            </div>
            <div class="member">
              <img src="" style="margin:auto">
              <h4>john</h4>
              <p style="text-align:center">has the following info</p>
            </div>
            <div class="member">
              <img src="" style="margin:auto">
              <h4>John</h4>
              <p style="text-align:center">has the following info</p>
            </div>
            <div class="member">
              <img src="" style="margin:auto">
              <h4>John</h4>
              <p style="">has the following info</p>
            </div>
            <div class="member">
              <img src="" style="margin:auto">
              <h4>John</h4>
              <p style="">has the following info</p>
            </div>
            <div class="member">
              <img src="" style="margin:auto">
              <h4>John</h4>
              <p style="text-align:center">has the following info</p>
            </div>
          </div>
        </div>
        <div id="activate-carousel-button">
          <button type="button" onclick="load();" class="btn btn-default">Click to activate carousel controls</button>
        </div>
      </div>
    </body>