I am fairly new to coding and don't have the in-depth knowledge to solve this problem on my own. I would be really grateful if somebody could help me out!
I am trying to wrap a dynamically loaded text without a fixed number of characters around a spinning cylinder using CSS and splitting.js. I tried following this tutorial and everything worked great until I started changing the text. The problem is that this method only works with text that doesn't change in length because it either gets cut off if the text is too long or a gap in the cylinder results if it is too short.
Here is the source code I have right now. Sadly it doesn't work properly when I paste it in jsfiddle. It does however work just fine in my code editor and is the same as in the tutorial I linked above.
<div class="circle" data-splitting>
Circle-Text-Animation-Effect-Cool-great
</div>
<script>
Splitting();
</script>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: monospace;
}
body{
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color:aqua;
}
.circle {
transform-style: preserve-3d;
animation: animate 8s linear infinite;
}
#keyframes animate {
0% {
transform: perspective(1000px) rotateY(360deg) rotateX(15deg);
}
100% {
transform: perspective(1000px) rotateY(0deg) rotateX(15deg);
}
}
.circle .char {
position: absolute;
top: 0;
left: 0;
background: red;
color: blue;
font-size: 4em;
padding: 5px 12px;
border: 4px solid black;
transform-style: preserve-3d;
transform-origin: center;
transform: rotateY(calc(var(--char-index) * 10deg)) translateZ(250px);
}
Is there any workaround for this problem? Maybe even without using splitting.js?
I hope I could describe my problem properly. English isn't my first language and I can't upload images to Stackoverflow yet so I wasn't able to describe the problem visually!
Thank you in advance for your help!
enter image description here
The trick here is to note that the number of degrees you need to rotate a character depends on the total number of characters in the string.
I don't have the splitter.js library so have put in a bit of JS which does the same thing - separates each character into its own div with a style that defines a CSS variable - the index of the character.
The JS also sets a new CSS variable, --numchs, which is used in the CSS to calculate the number of degrees to rotate each character, --deg. This is then used instead of the 10deg to decide where to place a character.
const circle = document.querySelector('.circle');
const text = circle.innerHTML;// Note I am being lazy here and assuming the string has no unwanted whitespace
circle.innerHTML = '';
circle.style.setProperty('--numchs', text.length);
for ( let i = 0; i < text.length; i++ ) {
circle.innerHTML = circle.innerHTML + '<div class="char" style="--char-index: ' + i + ';">' + text.charAt(i) + '</div>';
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: monospace;
}
body{
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color:aqua;
}
.circle {
transform-style: preserve-3d;
animation: animate 8s linear infinite;
--deg: calc(360deg / var(--numchs));
}
#keyframes animate {
0% {
transform: perspective(1000px) rotateY(360deg) rotateX(15deg);
}
100% {
transform: perspective(1000px) rotateY(0deg) rotateX(15deg);
}
}
.circle .char {
position: absolute;
top: 0;
left: 0;
background: red;
color: blue;
font-size: 4em;
padding: 5px 12px;
border: 4px solid black;
transform-style: preserve-3d;
transform-origin: center;
transform: rotateY(calc(var(--char-index) * var(--deg))) translateZ(250px);
}
<div class="circle" data-splitting>Circle-Text-Animation-Effect-Cool-great</div>
I've find a beautiful button in html/css that I have add on my leaflet map. (Adding the lines to my previous code)
I am blocked because this is not a real <button> and i don't find anything on Stackoverflow which answer to my question :(
I would like to add any functions which use Javascript, even a simple like add a Pop up when click on the button or anything which related to adding a little bit of interactivity like when click on the button, the zoom go on a specific place of the map.
I just want to know how to link this button to JavaScript.
Find below the section of my code that i want be linked to a function.
#import url('https://fonts.googleapis.com/css?family=Poppins:900i');
* {
box-sizing: border-box;
}
body {
height: 100vh;
display: flex;
justify-content: right;
align-items: right;
}
.wrapper {
display: flex;
justify-content: center;
z-index: 10000;
}
.cta {
right: auto;
margin-left: 500px;
top: 520px;
position: relative;
left: 500px;
display: flex;
padding: 3px 31px;
text-decoration: none;
font-family: 'Poppins', sans-serif;
font-size: 30px;
color: white;
background: #ffa500;
transition: 1s;
box-shadow: 6px 6px 0 black;
transform: skewX(-15deg);
}
.cta:focus {
outline: none;
}
.cta:hover {
transition: 0.5s;
box-shadow: 10px 10px 0 #FBC638;
}
.cta span:nth-child(2) {
transition: 0.5s;
margin-right: 0px;
}
.cta:hover span:nth-child(2) {
transition: 0.5s;
margin-right: 45px;
}
span {
transform: skewX(15deg)
}
span:nth-child(2) {
width: 20px;
margin-left: 30px;
position: relative;
top: 12%;
}
/**************SVG****************/
path.one {
transition: 0.4s;
transform: translateX(-60%);
}
path.two {
transition: 0.5s;
transform: translateX(-30%);
}
.cta:hover path.three {
animation: color_anim 1s infinite 0.2s;
}
.cta:hover path.one {
transform: translateX(0%);
animation: color_anim 1s infinite 0.6s;
}
.cta:hover path.two {
transform: translateX(0%);
animation: color_anim 1s infinite 0.4s;
}
/* SVG animations */
#keyframes color_anim {
0% {
fill: white;
}
50% {
fill: #FBC638;
}
100% {
fill: white;
}
}
<div class="wrapper">
<a class="cta" href="#">
<span>Datacenter SG</span>
<span>
<svg width="66px" height="43px" viewBox="0 0 66 43" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="arrow" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path class="one" d="M40.1543933,3.89485454 L43.9763149,0.139296592 C44.1708311,-0.0518420739 44.4826329,-0.0518571125 44.6771675,0.139262789 L65.6916134,20.7848311 C66.0855801,21.1718824 66.0911863,21.8050225 65.704135,22.1989893 C65.7000188,22.2031791 65.6958657,22.2073326 65.6916762,22.2114492 L44.677098,42.8607841 C44.4825957,43.0519059 44.1708242,43.0519358 43.9762853,42.8608513 L40.1545186,39.1069479 C39.9575152,38.9134427 39.9546793,38.5968729 40.1481845,38.3998695 C40.1502893,38.3977268 40.1524132,38.395603 40.1545562,38.3934985 L56.9937789,21.8567812 C57.1908028,21.6632968 57.193672,21.3467273 57.0001876,21.1497035 C56.9980647,21.1475418 56.9959223,21.1453995 56.9937605,21.1432767 L40.1545208,4.60825197 C39.9574869,4.41477773 39.9546013,4.09820839 40.1480756,3.90117456 C40.1501626,3.89904911 40.1522686,3.89694235 40.1543933,3.89485454 Z" fill="#FFFFFF"></path>
<path class="two" d="M20.1543933,3.89485454 L23.9763149,0.139296592 C24.1708311,-0.0518420739 24.4826329,-0.0518571125 24.6771675,0.139262789 L45.6916134,20.7848311 C46.0855801,21.1718824 46.0911863,21.8050225 45.704135,22.1989893 C45.7000188,22.2031791 45.6958657,22.2073326 45.6916762,22.2114492 L24.677098,42.8607841 C24.4825957,43.0519059 24.1708242,43.0519358 23.9762853,42.8608513 L20.1545186,39.1069479 C19.9575152,38.9134427 19.9546793,38.5968729 20.1481845,38.3998695 C20.1502893,38.3977268 20.1524132,38.395603 20.1545562,38.3934985 L36.9937789,21.8567812 C37.1908028,21.6632968 37.193672,21.3467273 37.0001876,21.1497035 C36.9980647,21.1475418 36.9959223,21.1453995 36.9937605,21.1432767 L20.1545208,4.60825197 C19.9574869,4.41477773 19.9546013,4.09820839 20.1480756,3.90117456 C20.1501626,3.89904911 20.1522686,3.89694235 20.1543933,3.89485454 Z" fill="#FFFFFF"></path>
<path class="three" d="M0.154393339,3.89485454 L3.97631488,0.139296592 C4.17083111,-0.0518420739 4.48263286,-0.0518571125 4.67716753,0.139262789 L25.6916134,20.7848311 C26.0855801,21.1718824 26.0911863,21.8050225 25.704135,22.1989893 C25.7000188,22.2031791 25.6958657,22.2073326 25.6916762,22.2114492 L4.67709797,42.8607841 C4.48259567,43.0519059 4.17082418,43.0519358 3.97628526,42.8608513 L0.154518591,39.1069479 C-0.0424848215,38.9134427 -0.0453206733,38.5968729 0.148184538,38.3998695 C0.150289256,38.3977268 0.152413239,38.395603 0.154556228,38.3934985 L16.9937789,21.8567812 C17.1908028,21.6632968 17.193672,21.3467273 17.0001876,21.1497035 C16.9980647,21.1475418 16.9959223,21.1453995 16.9937605,21.1432767 L0.15452076,4.60825197 C-0.0425130651,4.41477773 -0.0453986756,4.09820839 0.148075568,3.90117456 C0.150162624,3.89904911 0.152268631,3.89694235 0.154393339,3.89485454 Z" fill="#FFFFFF"></path>
</g>
</svg>
</span>
</a>
</div>
When you want to display a popup or something on a leaflet map, your posted code should contain your leaflet code. Also it is very helpful when you create a live demo, for example on jsfiddle.
But now to your question:
You can add a event over the default way addEventListener or with the leaflet library to a element. Here I use it over the leaflet library:
But first add a id to your button <div class="wrapper" id='testId'>
var button = document.getElementById('testId')
L.DomEvent.on(button,'click',function(e){
console.log('Button clicked')
});
When you want to open a popup on a specific location call:
L.DomEvent.on(button,'click',function(){
var latlng = map.getCenter(); // or [47.478058, 9.720154]
L.popup().setContent('Test').setLatLng(latlng).openOn(map)
});
I think your next question would be "How can I zoom to a marker":
This is a little bit difficult, because we need to know to which marker you want to zoom. This means that you have to save your marker to a global variable, so it can used in the button click event.
var latlng = map.getCenter(); // or [47.478058, 9.720154]
var marker = L.marker(latlng).addTo(map);
L.DomEvent.on(button,'click',function(){
var zoomlvl = 16;
map.flyTo(marker.getLatLng(),zoomlvl)
});
I'm building React components. I have added CSS inline in the components as suggested in this brilliant presentation by one of the people behind React. I've been trying all night to find a way to add CSS pseudo classes inline, like on the slide titled "::after" in the presentation. Unfortunately, I do not just need to add the content:""; property, but also position:absolute; -webkit-filter: blur(10px) saturate(2);. The slides show how to add content through {/* … */}, but how would you add other properties?
Got a reply from #Vjeux over at the React team:
Normal HTML/CSS:
<div class="something"><span>Something</span></div>
<style>
.something::after {
content: '';
position: absolute;
-webkit-filter: blur(10px) saturate(2);
}
</style>
React with inline style:
render: function() {
return (
<div>
<span>Something</span>
<div style={{position: 'absolute', WebkitFilter: 'blur(10px) saturate(2)'}} />
</div>
);
},
The trick is that instead of using ::after in CSS in order to create a new element, you should instead create a new element via React. If you don't want to have to add this element everywhere, then make a component that does it for you.
For special attributes like -webkit-filter, the way to encode them is by removing dashes - and capitalizing the next letter. So it turns into WebkitFilter. Note that doing {'-webkit-filter': ...} should also work.
Inline styles cannot be used to target pseudo-classes or pseudo-elements. You need to use a stylesheet.
If you want to generate CSS dynamically, then the easiest way is to create a DOM element <style>.
<style dangerouslySetInnerHTML={{
__html: [
'.my-special-div:after {',
' content: "Hello";',
' position: absolute',
'}'
].join('\n')
}}>
</style>
<div className='my-special-div'></div>
Depending if you only need a couple attributes to be styled inline you can do something like this solution (and saves you from having to install a special package or create an extra element):
https://stackoverflow.com/a/42000085
<span class="something" datacustomattribute="👋">
Hello
</span>
.something::before {
content: attr(datascustomattribute);
position: absolute;
}
Note that the datacustomattribute must start with data and be all lowercase to satisfy React.
Inline styling does not support pseudos or at-rules (e.g., #media). Recommendations range from reimplement CSS features in JavaScript for CSS states like :hover via onMouseEnter and onMouseLeave to using more elements to reproduce pseudo-elements like :after and :before to just use an external stylesheet.
Personally dislike all of those solutions. Reimplementing CSS features via JavaScript does not scale well -- neither does adding superfluous markup.
Imagine a large team wherein each developer is recreating CSS features like :hover. Each developer will do it differently, as teams grow in size, if it can be done, it will be done. Fact is with JavaScript there are about n ways to reimplement CSS features, and over time you can bet on every one of those ways being implemented with the end result being spaghetti code.
So what to do? Use CSS. Granted you asked about inline styling going to assume you're likely in the CSS-in-JS camp (me too!). Have found colocating HTML and CSS to be as valuable as colocating JS and HTML, lots of folks just don't realise it yet (JS-HTML colocation had lots of resistance too at first).
Made a solution in this space called Style It that simply lets your write plaintext CSS in your React components. No need to waste cycles reinventing CSS in JS. Right tool for the right job, here is an example using :after:
npm install style-it --save
Functional Syntax (JSFIDDLE)
import React from 'react';
import Style from 'style-it';
class Intro extends React.Component {
render() {
return Style.it(`
#heart {
position: relative;
width: 100px;
height: 90px;
}
#heart:before,
#heart:after {
position: absolute;
content: "";
left: 50px;
top: 0;
width: 50px;
height: 80px;
background: red;
-moz-border-radius: 50px 50px 0 0;
border-radius: 50px 50px 0 0;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-transform-origin: 0 100%;
-moz-transform-origin: 0 100%;
-ms-transform-origin: 0 100%;
-o-transform-origin: 0 100%;
transform-origin: 0 100%;
}
#heart:after {
left: 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transform-origin: 100% 100%;
-moz-transform-origin: 100% 100%;
-ms-transform-origin: 100% 100%;
-o-transform-origin: 100% 100%;
transform-origin :100% 100%;
}
`,
<div id="heart" />
);
}
}
export default Intro;
JSX Syntax (JSFIDDLE)
import React from 'react';
import Style from 'style-it';
class Intro extends React.Component {
render() {
return (
<Style>
{`
#heart {
position: relative;
width: 100px;
height: 90px;
}
#heart:before,
#heart:after {
position: absolute;
content: "";
left: 50px;
top: 0;
width: 50px;
height: 80px;
background: red;
-moz-border-radius: 50px 50px 0 0;
border-radius: 50px 50px 0 0;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-transform-origin: 0 100%;
-moz-transform-origin: 0 100%;
-ms-transform-origin: 0 100%;
-o-transform-origin: 0 100%;
transform-origin: 0 100%;
}
#heart:after {
left: 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transform-origin: 100% 100%;
-moz-transform-origin: 100% 100%;
-ms-transform-origin: 100% 100%;
-o-transform-origin: 100% 100%;
transform-origin :100% 100%;
}
`}
<div id="heart" />
</Style>
}
}
export default Intro;
Heart example pulled from CSS-Tricks
You can use styled components.
Install it with npm i styled-components
import React from 'react';
import styled from 'styled-components';
const ComponentWithPseudoClass = styled.div`
height: 50px;
position: relative;
&:after {
// whatever you want with normal CSS syntax. Here, a custom orange line as example
content: '';
width: 60px;
height: 4px;
background: orange
position: absolute;
bottom: 0;
left: 0;
}
`;
const YourComponent = props => {
return (
<ComponentWithPseudoClass>...</ComponentWithPseudoClass>
)
}
export default YourComponent
I don't know if this would be considered hacky but it certainly works (using CSS variable):
const passedInlineStyle = { '--color':'blue'}
Then in an imported CSS file:
background:var(--color);
The easiest trick is to add '""' instead of '' in the content property for the pseudo-element.
const styles = {
container: {
// ... Container styling
'&::after': {
display: 'block',
content: '""'
}
}
};
Not a direct answer to the question, but this may help those who are having trouble creating style information using Typescript.
I was getting an error telling me that the following was incorrect:
let iconStyle = {
position: 'relative',
maxHeight: '90px',
top: '25%',
}
The error told me that "types of property 'position' are incompatible". I have no idea why.
I fixed this by adding a strict Typescript declaration, like so:
let iconStyle: CSSProperties = {
position: 'relative',
maxHeight: '90px',
top: '25%',
}
This works.
I'm working on a website for a client who wants a 3D carousel.
I found this which works perfectly in Chrome and FF: http://codepen.io/dudleystorey/pen/kiajB
HTML:
<div id=carousel>
<figure id=spinner>
<img src=//demosthenes.info/assets/images/wanaka-tree.jpg alt="">
<img src=//demosthenes.info/assets/images/still-lake.jpg alt="">
<img src=//demosthenes.info/assets/images/pink-milford-sound.jpg alt="">
<img src=//demosthenes.info/assets/images/paradise.jpg alt="">
<img src=//demosthenes.info/assets/images/morekai.jpg alt="">
<img src=//demosthenes.info/assets/images/milky-blue-lagoon.jpg alt="">
<img src=//demosthenes.info/assets/images/lake-tekapo.jpg alt="">
<img src=//demosthenes.info/assets/images/milford-sound.jpg alt="">
</figure>
</div>
<span style=float:left class=ss-icon onclick="galleryspin('-')"><</span>
<span style=float:right class=ss-icon onclick="galleryspin('')">></span>
CSS:
div#carousel {
perspective: 1200px;
background: #100000;
padding-top: 10%;
font-size:0;
margin-bottom: 3rem;
overflow: hidden;
}
figure#spinner {
transform-style: preserve-3d;
height: 300px;
transform-origin: 50% 50% -500px;
transition: 1s;
}
figure#spinner img {
width: 40%; max-width: 425px;
position: absolute; left: 30%;
transform-origin: 50% 50% -500px;
outline:1px solid transparent;
}
figure#spinner img:nth-child(1) { transform:rotateY(0deg);
}
figure#spinner img:nth-child(2) { transform: rotateY(-45deg); }
figure#spinner img:nth-child(3) { transform: rotateY(-90deg); }
figure#spinner img:nth-child(4) { transform: rotateY(-135deg); }
figure#spinner img:nth-child(5){ transform: rotateY(-180deg); }
figure#spinner img:nth-child(6){ transform: rotateY(-225deg); }
figure#spinner img:nth-child(7){ transform: rotateY(-270deg); }
figure#spinner img:nth-child(8){ transform: rotateY(-315deg); }
div#carousel ~ span {
color: #fff;
margin: 5%;
display: inline-block;
text-decoration: none;
font-size: 2rem;
transition: 0.6s color;
position: relative;
margin-top: -6rem;
border-bottom: none;
line-height: 0; }
div#carousel ~ span:hover { color: #888; cursor: pointer; }
JS:
var angle = 0;
function galleryspin(sign) {
spinner = document.querySelector("#spinner");
if (!sign) { angle = angle + 45; } else { angle = angle - 45; }
spinner.setAttribute("style","-webkit-transform: rotateY("+ angle +"deg); -moz-transform: rotateY("+ angle +"deg); transform: rotateY("+ angle +"deg);");
}
Unfortunately it is a disaster in IE11.
I've searched the web for help but it seems that everything is managed by the latest versions of IE so I'm a bit confused.
I do not have much experience with javascript and css, for me everything seems ok.
Does someone can help?
The most likely reason your feature is failing in IE has to do with the transform-style: preserve-3d; rule applied to figure#spinner1.
IE support for CSS3 3D features has improved, but according to caniuse IE10 and 11 still do not support that particular feature of the 3D transform API. When I remove the rule from your CSS, I can see that the whole 3d layout fails when that feature is missing.
There may be another way of nesting and formatting your 3d objects that will achieve the same visual effect without 'preserve-3d', but it will likely be much more complicated than the implementation you have now.
Another option you might consider is using threejs and WebGL to handle your 3d carousel when necessary CSS 3D attributes are not available in the target browser.
First post here. Hope you can help me out with a problem I'm having:
I am writing a game, where a user needs to guess a word from shuffled letters by clicking on each letter to insert it in the first empty space of a "correct" field.
Now, when a letter is clicked, it needs to move to its new spot in an animated way. As I'm using span to create a separate field for each letter I couldn't figure out how to make this span move to its new location in an animated way using CCS3/JavaScript/JQuery.
The code is in JSFiddle here: http://jsfiddle.net/Pfsqu/
JS:
var randomNumber = Math.floor(Math.random() * words.length);
var word = words[randomNumber];
var chars = word.split('');
chars=_.shuffle(chars);
for (var i in chars) {
$('#shuffled').append('<span>'+chars[i]+'</span>');
$('#correct').append('<span>');
}
$('#shuffled > span').click(function() {
var letter = $(this);
letter.replaceWith('<span>');
$('#correct > span:empty').first().append( letter ); /* this part needs to be animated*/
CSS:
p > span{
background-color: white;
margin: 10px;
-webkit-border-radius: 15px;
border-radius: 15px;
width: 2.5em;
height: 2.5em;
display: inline-block;
text-align: center;
line-height: 2.5em;
vertical-align: middle;
animation: 1000ms move ease-in-out;
-webkit-animation: 1000ms move ease-in-out;
}
I think that it is quite difficult to animate the items the way that you are intending.
The way I would solve it would be keeping the same DOM element, and changing its properties.
For instance, see this
demo
The HTML is
<div class="solution">
<span class="q q4">W</span>
<span class="q q2">O</span>
<span class="q q3">R</span>
<span class="q q1">D</span>
</div>
I have set the letters of WORD in order, and then I have set to them one of the classes q1 to q4. This class will set the span to a specific position on screen.
This is achieved in this CSS (and also the position for the "solved" status
.solution {
margin-top: 100px;
-webkit-transition: all 5s;
position: relative;
}
.solution span {
border: solid 1px green;
padding: 10px;
margin-top: 80px;
-webkit-transition: all 2s;
position: absolute;
background-color: lightgreen;
font-size: 30px;
}
.solution span:nth-child(1) {
-webkit-transform: translate(0px, 0px) rotate(0deg);
}
.solution span:nth-child(2) {
-webkit-transform: translate(80px, 0px) rotate(0deg);
}
.solution span:nth-child(3) {
-webkit-transform: translate(160px, 0px) rotate(0deg);
}
.solution span:nth-child(4) {
-webkit-transform: translate(240px, 0px) rotate(0deg);
}
div.solution span.q {
background-color: yellow !important;
border: solid 1px red;
border-radius: 50%;
}
.solution .q.q1 {
-webkit-transform: translate(0px, -100px) rotate(360deg);
}
.solution .q.q2 {
-webkit-transform: translate(80px, -100px) rotate(360deg);
}
.solution .q.q3 {
-webkit-transform: translate(160px, -100px) rotate(360deg);
}
.solution .q.q4 {
-webkit-transform: translate(240px, -100px) rotate(360deg);
}
Now the jQuery is very easy
$('.q').click(function(){
$(this).removeClass('q');
});
I have used the webkit prefixes, but you can easily set it to work for others browsers
Edited answer:
Changing the nth-child styles to:
.answer1 {
-webkit-transform: translate(0px, 0px) rotate(0deg);
}
.answer2 {
-webkit-transform: translate(80px, 0px) rotate(0deg);
}
.answer3 {
-webkit-transform: translate(160px, 0px) rotate(0deg);
}
.answer4 {
-webkit-transform: translate(240px, 0px) rotate(0deg);
}
and the script to:
var element = 1;
$('.q').click(function(){
$(this).removeClass('q').addClass("answer" + element);
element = element + 1;
});
You got, as per your request, that the letters go to the first available place.
The only remining task is to construct the spans from the array of letters.
I think that you have already some code that does quite a similar job; it's only a matter of adapting it.
updated demo