Can you change css with a click function? - css

I am making a battleship style game and trying to work on the movement of the ships on the table. My idea is that you can drag and drop ships onto the table and when you click on the ship it changes from vertical to a horizontal position or other way around. Every ship has some css with two main parts Width and Height. Is it possible to make so that the Ships css width and height are swapped around when I click on the ship?

With javascript, you can change the CSS width using:
var el = document.querySelector("#yourObjectID");
el.style.width = "100px";
To change the height:
el.style.height = "100px";
To swap the height and width you could use an extra variable as you would swap any other variables.
If you are using a click listener, you can use this instead of creating a variable el and selecting the element with a query selector.
document.querySelector("#ship1").addEventListener('click', function(){
var newHeight = this.style.width;
this.style.width = this.style.height;
this.style.height = newHeight;
}, false);
.ship {
background: gray;
cursor: pointer;
}
<div id="ship1" class="ship" style="width: 100px; height: 50px;"></div>

I am unfortunately not too sure what you are trying to achieve. are you trying to swap the ships from vertical to horizontal or are you trying to swap the width and height with eachother.
If you are trying to rotate the ship you can do it like this:
With css and js you can rotate the ships like this:
html
<div id="MyID" onclick="ChangeClass()"></div>
js
function ChangeClass() {
var MyVar= document.getElementById("MyID")
MyVar.className="MyClass"
}
css
.MyClass{
/* rotates the class. webkit = chrome,safari ms = edge, moz = firefox, o = opera*/
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-o-transform: rotate(90deg);
}
you can change the ID and classes to your desired names.

Related

CSS3 Transform Rotate3D - On Hover, Force FULL Transform?

Here's a fiddle.
.box:hover {
-moz-transform: rotate3d(0,1,0,180deg);
-webkit-transform: rotate3d(0,1,0,180deg);
-ms-transform: rotate3d(0,1,0,180deg);
transform: rotate3d(0,1,0,180deg);
}
I'm using some CSS3 to get the card flip effect on some parts of my site. I have no issues with this in any Windows browsers, but I'm getting reports from some Mac users that the rotation is getting stuck and won't flip over completely. It looks like in those browsers, when doing a 3d transformation it appears that the "hitbox" for hover is transformed along with the element and content (as it gets close to rotating 90 degrees, the hitbox for the element approaches 1px width).
I could be wrong about what's happening or maybe there's a better fix than what I have in mind, but I was looking to hopefully work around this issue by causing the full transition/animation to play out as soon as the mouse triggered the hover. This way, even if the hitbox for the hover does change size, the elements will finish flipping over.
Is this possible with just CSS3? Or should I look into a javascript solution?
Wrap it with a wrapper and put the hover on the wrapper. I tested on FF and chrome on Mac
https://jsfiddle.net/6udv405h/3/
.wrapper:hover .box {
-moz-transform: rotate3d(0,1,0,180deg);
-webkit-transform: rotate3d(0,1,0,180deg);
-ms-transform: rotate3d(0,1,0,180deg);
transform: rotate3d(0,1,0,180deg);
}
HTML
<div class="wrapper">
<div class="box"></div>
</div>
<script type="text/javascript">
$(document).ready(function () {
$('.box').mouseover(function () {
var box = $(this)
$(box).addClass('hovered');
setTimeout(function () {
$(box).removeClass('hovered');
}, 1000);
});
});
</script>
Little bit of Jquery solved my issue. I would still have preferred to use only CSS, so please reach out to me if you have a better solution without using JS.

CSS zoom does not work for a <img> in <a>, in iOS 8 Mobile Safari

Using zoom: 0.5;, image gets rendered in 0.5x size when not inside <a> tag, but in 1x size when inside <a> tag.
This occurred with iOS 8 GM (iPhone 5 simulator of Xcode 6 GM, and iPad mini).
This did not occur with iOS 7.1.2 (iPhone 5) and iOS 7.0 (iPhone 5 simulator of Xcode 6 GM).
Here is an example : https://dl.dropboxusercontent.com/u/379843/ios8csszoom/test.html
<!DOCTYPE html>
<html>
<body>
<img src="star-on#2x.png" style="border: 1px solid blue; zoom: 0.5;"/>
<a href="#">
<img src="star-on#2x.png" style="border: 1px solid blue; zoom: 0.5;"/>
</a>
<hr>
<img src="star-on#2x.png" style="border: 1px solid blue; -webkit-transform: scale(0.5);"/>
<a href="#">
<img src="star-on#2x.png" style="border: 1px solid blue; -webkit-transform: scale(0.5);"/>
</a>
</body>
</html>
-webkit-transform is functioning on iOS 8, but I don' want to use this, because even though the image is rendered in 0.5x size, the space consumed by the <img> tag is 1x size.
Any workarounds?
Although not ideal, this is how I've coped with the problem:
Replace anchors with another element (div or span depending on block/inline)
Give each element a shared class name
Either leave the href, or, add a data-href property with the href
On a high level, have an event listener bind to all elements with your class name
Event listener reads href and then triggers routing/controller logic appropriate for your framework
Example: http://jsfiddle.net/z5crh05a/
$(".fauxLink").on("click", function(e) {
var href = $(e.currentTarget).attr("href");
e.preventDefault();
e.stopPropagation();
// navigation logic here
alert("Navigate to: "+href);
});
});
Hopefully the issue in Safari is fixed in a future iOS update.
By default -webkit-transform on Safari and MobileSafari has an origin “center center”, which means the parent container will be the same size as if not scaled.
Adjust this by setting this to “top left” using:
-webkit-transform-origin 0 0;
Whole solution would then be (with IE9+, FF, Chrome and Safari/MobileSafari support):
transform: scale(0.5);
-ms-transform: scale(0.5);
-mos-transform: scale(0.5);
-webkit-transform: scale(0.5);
transform-origin: 0 0;
-ms-transform-origin: 0 0;
-mos-transform-origin: 0 0;
-webkit-transform-origin: 0 0;
I transform these pictures with scale.
-webkit-transform: scale(0.5);
-moz-transform: scale(0.5);
-o-transform: scale(0.5);
transform: scale(0.5);
this also works for ios but you have to reposition your pics after that!
I figured out a workaround, but can only be used with a webapp framework.
I was using CakePHP, and was using a helper method to output all img tags, so I overrided that method so that it would output width and height attributes, and quit using the css zoom.
I used getimagesize of GD to get the width and height.
http://php.net/manual/ja/function.getimagesize.php
Rather than changing your markup, you can just resize the images using a little bit of javascript.
Here's a working snippet (using jQuery) of what I'm currently using on my WordPress blog:
var dmblog = {
// [TRUNCATED]
// ! dmblog.imgZoomResize
imgZoomResize : function(element) {
var zoom = element.css('zoom');
element.width(element[0].naturalWidth*zoom);
element.height(element[0].naturalHeight*zoom);
},
// ! dmblog.retinaImagesResize
retinaImagesResize : function() {
$('.post .entry-content img, .comment .comment-content img').each(function(){
dmblog.imgZoomResize($(this));
// set a handler on the resize event to resize the retina images
var $w = $(window),
namespace = $(this)[0].id.replace('#','.'),
element = $(this),
handler = function() {
dmblog.imgZoomResize(element);
};
$w.bind('resize'+namespace, handler);
});
}
};
// [TRUNCATED]
// ! for single posts, load some scripts
if ($('body').hasClass('single'))
{
// [TRUNCATED]
// resize retina images
dmblog.retinaImagesResize();
}
Using this workaround, there's no need to change your css, the anchor tags, nor any of your markup, just add a little bit of javascript to resize the images.
I'm using CSS media queries to set the CSS zoom to 1 on large screens, and to 0.5 on smaller screens. Even though the zoom value doesn't work anymore, it still reports as 0.5 in jQuery. Since it's a responsive design, I added a handler on the window resize event to automatically resize the image up/down whenever the zoom value is changed (responding to CSS media queries).
If you're not using media queries to responsively change the CSS zoom value though, then the amount of javascript you'll need (without the handler) is much less.

CSS3 animation: inherit property for keyframe at 0%

I have following problem:
I want to use CSS3 animation with keyframe rules (#keyframes myname {})
Problem is, I want to use SINGLE at-rule keyframe animation for multiple elements, but these elements have different position each. So, #keyframes animation should inherit original properties of selector at 0% (or from {}) rule, so animation would originate at original position and size of selector.
like this one:
#keyframes myanim {
0% {
left: inherit;
top: inherit;
width:inherit;
height:inherit;
}
100% {
top: 50%;
left:50%;
width: 100%;
height: 60%;
}
}
And selector:
.myselector-one {
top:10em;
left:0em;
width:10em;
height:5em;
animation: myanim 1s;
}
.myselector-two {
top:20em;
left:30em;
width: 15em;
height: 8em;
animation: myanim 1s;
}
Goal is to get original properties of each selector, put them to 0% keyframe as originating position and size and animate to 100% with same properties for every selector.
Is this possible or I have to create animation for each selector? Problem is, that I wouldn't know their position as it's going to be dynamically calculated.
Please, no jQuery solution, just pure CSS3 one! I DON't want to use jQuery animate method.
Hmmm, I have been looking into this problem for a little while and I don't think it is possible using CSS Animations. I've been trying with this JSFiddle a number of different things and running through tutorials about CSS Animations (seeing if anyone mentions the same issue) and also other information about it.
I did then come to the realization of what you are trying to accomplish and I think perhaps there is an easier solution. IF the locations are being dynamically calculated, I would assume you are indeed using some level of Javascript (or some crazy advanced CSS calc method) so I would at least think you would be setting the style of the DOM element with new left or top positions. While I'm not talking about jQuery animation, what you can do instead is use CSS3 Transitions in conjunction with Javascript. This means you get some of the benefits of CSS Animations like the computation being more native (hardware accelerated) as opposed to being done in Javascript but you do lose out on a few things.
Most importantly, there are no transition events for the browser like there is for CSS Animations nor can you have as fine-grain control over keyframes but you do get to work with it dynamically. I only suggest it as your question only refers to a keyframe of 0% and one of 100%.
The issue with what you were trying to do is that using CSS Animations needs to be static and won't pull the values that were currently set to do the animation (unlike transitions). When you are using inherit, you are actually trying to make it use the top and left etc. from it's parent.
Again, this doesn't meet your requirement of pure CSS but using CSS Transitions does mean only limited DOM manipulation via Javascript rather than what jQuery animate does.
Here is another JSFiddle using no jQuery (only very basic javascript to set a class or inline-styles) and CSS Transitions.
HTML
<div class="myselector-one" id="a">Click Me</div>
<div class="myselector-two" id="b">Click Me</div>
Javascript
document.getElementById("a").onclick = function()
{
if (this.className.indexOf("animate-complete")!=-1)
{
this.className = this.className.replace(/animate\-complete/g,"");
}
else
{
this.className += " animate-complete";
}
}
var bIsTransitioned = false;
document.getElementById("b").onclick = function()
{
if (!bIsTransitioned)
{
this.style.top = "50%";
this.style.left = "50%";
this.style.width = "100%";
this.style.height = "60%";
}
else
{
this.style.top = "";
this.style.left = "";
this.style.width = "";
this.style.height = "";
}
bIsTransitioned = !bIsTransitioned;
}
CSS
.myselector-one {
top:10em;
left:0em;
width:10em;
height:5em;
transition:all 2s;
background-color:#ffaa99;
position:absolute;
}
.myselector-two {
top:4em;
left:30em;
width: 15em;
height: 8em;
transition:all 2s;
background-color:#aaff99;
position:absolute;
}
.animate-complete
{
top: 50%;
left:50%;
width: 100%;
height: 60%;
}
An update for anyone who lands on this thread. According to MDN omitting the 0% / from selector would have the desired behaviour. https://developer.mozilla.org/en-US/docs/Web/CSS/#keyframes
Valid keyframe lists
If a keyframe rule doesn't specify the start or
end states of the animation (that is, 0%/from and 100%/to), browsers
will use the element's existing styles for the start/end states. This
can be used to animate an element from its initial state and back.

how to dynamically size multi-css sprite image

I have an image built from multiple css sprites, as described in this question: css image building with sprites
How would I use that so that I could apply a size on the top container that would dynamically re-size all the children?
here is the working fidlle so far: http://jsfiddle.net/hWhUb/3/
here is the current html structure:
<div class="icon">
<div class="brigade brigade-purple-left"> </div>
<div class="brigade brigade-purple-middle"> </div>
<div class="brigade brigade-purple-right"> </div>
<div class="icon-type icon-hero"> </div>
</div>​
I have a few questions, that might lead to a solution:
Why are you using multiple images for something that can be easily achieved using a bit of css3 and a single image (the cross thingie)? A single image can more easily be resized, as a percentage of the container width, or even using css3 background-size property.
If you must use images for each thing, could you possibly consider never using sprites, ever? Its maintainability is pure annoyance, especially if someone has to take the project away from you later on.
Perhaps a combination of both?
If you choose the second option, I suggest using data uris.
Here's a short explaination:
http://css-tricks.com/data-uris/
It saves one more http request than sprites, easier to maintain, and the difference in overall size is rather insignificant in my honest opinion, and support is great - IE8+ and all sane browsers our there.
Setting up is easy enough, especially if you use the all-mighty sass interpreter, but there are some nifty utils out there (command-line, gui or even web-based) to transform your images into base64.
It can even support IE7 with a little effort!
Edit 3.11.12
You can also add http://css3pie.com/ to the options to check out - it lets you do the css3 tricks we so love and adore with internet explorer. It's a bit unpredictable to my taste, but for a small feat like this it can definitely do the trick.
Further, I commented on your browser-support needs below. IE7 is not what's going to stop you;)
You can use a combo of zoom for webkit/ie and -moz-transform:scale for Firefox
[class^="icon-"]{
display: inline-block;
background: url('../img/icons/icons.png') no-repeat;
width: 64px;
height: 51px;
overflow: hidden;
zoom:0.5;
-moz-transform:scale(0.5);
-moz-transform-origin: 0 0;
}
.icon-huge{
zoom:1;
-moz-transform:scale(1);
-moz-transform-origin: 0 0;
}
.icon-big{
zoom:0.60;
-moz-transform:scale(0.60);
-moz-transform-origin: 0 0;
}
.icon-small{
zoom:0.29;
-moz-transform:scale(0.29);
-moz-transform-origin: 0 0;
}
One of the ways to achieve it will be to use inline CSS and to dynamically generate attribute values in JavaScript or PHP/What you use.
Assuming you know the width of the top container and the position of the css sprites
Calculate the left middle and right
You can also opt to generate the CSS code in a separate file
http://aquagraphite.com/2011/11/dynamically-generate-static-css-files-using-php/
Using a bit of jQuery I can make the elements resize to whatever you want (resizeTo):
$(document).ready(function () {
$('#resize').click(function (e) {
e.preventDefault();
var resizeTo = 100,
resizeRatio = Number(resizeTo) / Number($(".icon").width());
$(".icon").css('width', resizeTo);
$(".child").each(function () {
var childWidth = Number($(this).width()),
childHeight = Number($(this).height()),
newChildWidth = childWidth * resizeRatio,
newChildHeight = childHeight * resizeRatio;
$(this).css({ 'width': newChildWidth, 'height': newChildHeight });
});
});
});​
However, size doesn't resize the sprites to fit the new box sizes so seems like a pointless task.
Fiddler: http://jsfiddle.net/hWhUb/4/
Though what you want to do can be accomplished, I think your approach is wrong. It's way more complicated than it needs to be, but the idea is sound.
Looking at your sprite, the only thing that can't be changed with CSS is the actual icons (the artwork). The rounded corners and background colors -- that's a different story.
CSS
.icon-cross {
background:purple url('cross.jpg') no-repeat 40px 12px;
border-radius:5px;
border:1px solid gray
}
#media only screen and (max-width:768px) {
.icon-cross {
background-size: 800px 1200px;
background-position; ??px ??px
}
}
#media only screen and (max-width:400px) {
.icon-cross {
background-size: 500px 900px;
background-position; ??px ??px
}
}
HTML
<div class="icon-cross"></div>
You can use css3 2d transforms:
.icon {
transform: scale(2);
-ms-transform: scale(2); /* IE 9 */
-webkit-transform: scale(2); /* Safari and Chrome */
-o-transform: scale(2); /* Opera */
-moz-transform: scale(2); /* Firefox */
}
and change the transform origin with: transform-origin

How can I zoom an HTML element in Firefox and Opera?

How can I zoom an HTML element in Firefox and Opera?
The zoom property is working in IE, Google Chrome and Safari, but it’s not working in Firefox and Opera.
Is there any method for adding this property to Firefox and Opera?
Try this code, this’ll work:
-moz-transform: scale(2);
You can refer to this.
Zoom and transform scale are not the same thing. They are applied at different times. Zoom is applied before the rendering happens, transform - after. The result of this is if you take a div with width/height = 100% nested inside of another div, with fixed size, if you apply zoom, everything inside your inner zoom will shrink, or grow, but if you apply transform your entire inner div will shrink (even though width/height is set to 100%, they are not going to be 100% after transformation).
For me this works to counter the difference between zoom and scale transform, adjust for the intended origin desired:
zoom: 0.5;
-ms-zoom: 0.5;
-webkit-zoom: 0.5;
-moz-transform: scale(0.5,0.5);
-moz-transform-origin: left center;
Use scale instead! After many researches and tests I have made this plugin to achieve it cross browser:
$.fn.scale = function(x) {
if(!$(this).filter(':visible').length && x!=1)return $(this);
if(!$(this).parent().hasClass('scaleContainer')){
$(this).wrap($('<div class="scaleContainer">').css('position','relative'));
$(this).data({
'originalWidth':$(this).width(),
'originalHeight':$(this).height()});
}
$(this).css({
'transform': 'scale('+x+')',
'-ms-transform': 'scale('+x+')',
'-moz-transform': 'scale('+x+')',
'-webkit-transform': 'scale('+x+')',
'transform-origin': 'right bottom',
'-ms-transform-origin': 'right bottom',
'-moz-transform-origin': 'right bottom',
'-webkit-transform-origin': 'right bottom',
'position': 'absolute',
'bottom': '0',
'right': '0',
});
if(x==1)
$(this).unwrap().css('position','static');else
$(this).parent()
.width($(this).data('originalWidth')*x)
.height($(this).data('originalHeight')*x);
return $(this);
};
usege:
$(selector).scale(0.5);
note:
It will create a wrapper with a class scaleContainer. Take care of that while styling content.
I would change zoom for transform in all cases because, as explained by other answers, they are not equivalent. In my case it was also necessary to apply transform-origin property to place the items where I wanted.
This worked for me in Chome, Safari and Firefox:
transform: scale(0.4);
transform-origin: top left;
-moz-transform: scale(0.4);
-moz-transform-origin: top left;
zoom: 145%;
-moz-transform: scale(1.45);
use this to be on the safer side
Only correct and W3C compatible answer is: <html> object and rem. transformation doesn't work correctly if you scale down (for example scale(0.5).
Use:
html
{
font-size: 1mm; /* or your favorite unit */
}
and use in your code "rem" unit (including styles for <body>) instead metric units. "%"s without changes. For all backgrounds set background-size. Define font-size for body, that is inherited by other elements.
if any condition occurs that shall fire zoom other than 1.0 change the font-size for tag (via CSS or JS).
for example:
#media screen and (max-width:320pt)
{
html
{
font-size: 0.5mm;
}
}
This makes equivalent of zoom:0.5 without problems in JS with clientX and positioning during drag-drop events.
Don't use "rem" in media queries.
You really doesn't need zoom, but in some cases it can faster method for existing sites.
I've been swearing at this for a while. Zoom is definitely not the solution, it works in chrome, it works partially in IE but moves the entire html div, firefox doesnt do a thing.
My solution that worked for me was using both a scaling and a translation, and also adding the original height and weight and then setting the height and weight of the div itself:
#miniPreview {
transform: translate(-710px, -1000px) rotate(0rad) skewX(0rad) scale(0.3, 0.3);
transform-origin: 1010px 1429px 0px;
width: 337px;
height: 476px;
Obviously change these to your own needs. It gave me the same result in all browsers.
It does not work in uniform way in all browsers.
I went to to: http://www.w3schools.com/html/tryit.asp?filename=tryhtml_pulpitimage and added style for zoom and -moz-transform. I ran the same code on firefox, IE and chrome and got 3 different results.
<html>
<style>
body{zoom:3;-moz-transform: scale(3);}
</style>
<body>
<h2>Norwegian Mountain Trip</h2>
<img border="0" src="/images/pulpit.jpg" alt="Pulpit rock" />
</body>
</html>
try this code to zoom the whole page in fireFox
-moz-transform: scale(2);
if I am using this code, the whole page scaled with y and x scroll not properly zoom
so Sorry to say fireFox not working well using "-moz-transform: scale(2);"
**
Simply you can't zoom your page using css in fireFox
**
does this work correctly for you? :
zoom: 145%;
-moz-transform: scale(1.45);
-webkit-transform: scale(1.45);
scale(1.45);
transform: scale(1.45);
For me this works well with IE10, Chrome, Firefox and Safari:
#MyDiv>*
{
zoom: 50%;
-moz-transform: scale(0.5);
-webkit-transform: scale(1.0);
}
This zooms all content in to 50%.

Resources