(Originally : To transform or not to transform)
I wanted to start spinning the DIV box so it would spin behind the text boxes. BECAUSE the text boxes did not seem to care what I did with the DIV I just made the javascript spin the DIV. To my surprise - by spinning the DIV the text boxes spun with the DIV and when they went outside of the DIV boxes area - they are now clipped. If I comment out the transforms the text boxes go back to ignoring anything I do with the DIV. So ideas why it is doing this? Do I maybe have to always do a transform and just set the degrees to zero(0)? Ideas and comments are welcome. :-) Here is the code:
PS: I put in the BODY's "overflow:hidden;" because I was testing that out too. Just a FYI. :-)
<html>
<head>
<title>Test</title>
<style>
.p1 { position:absolute;
top:50px;
left:50px;
border: 1px solid grey;
padding: 5px;
font-family: sans-serif,Arial,Helvetica,Verdana,"Trebuchet MS",Tahoma,"MS Sans Serif",Geneva;
font-size: 12pt;
width: 150px;
height: 10pt;
overflow: hidden;
z-index:0;
}
</style>
</head>
<body style='overflow:hidden;'>
<div id='d1' name='d1' style="width:500px;height:400px;overflow:hidden;z-index:1;
border:1px solid black;clip: rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);">
<p id='p1' name='p1' class='p1'>This is a test of how HTML works</p>
<p id='p2' name='p2' class='p1'>This is a test of how HTML works</p>
<p id='p3' name='p3' class='p1'>This is a test of how HTML works</p>
</div>
<script>
function moveIt(n)
{
document.getElementById("p1").style.left = n;
document.getElementById("p2").style.top = n;
document.getElementById("p3").style.left = n;
document.getElementById("p3").style.top = n;
// document.getElementById("d1").style.transform = "rotate(" + n + "deg)";
if( n < 2000 ){ setTimeout("moveIt(" + (n + 1) + ")", 1 ); }
else { moveIt2(n); }
}
function moveIt2(n)
{
document.getElementById("p1").style.left = n;
document.getElementById("p2").style.top = n;
document.getElementById("p3").style.left = n;
document.getElementById("p3").style.top = n;
// document.getElementById("d1").style.transform = "rotate(" + n + "deg)";
if( n > -1000 ){ setTimeout("moveIt2(" + (n - 1) + ")", 1 ); }
else { moveIt(n); }
}
moveIt(50);
</script>
</body>
</html>
A CSS transform on a parent element affects all the parent's children. That's why the text rotates.
You can prevent their rotation by applying a negative rotation equal in amount to the parent's positive rotation.
Also: You need to supply units such as px when setting the position of elements, like this:
document.getElementById('p1').style.left = n + 'px';
Working Fiddle
Related
We have this picture
What I want to try to do is on refresh or on load, the picture highlights a 200x200 square, and removes the rest of the picture like this:
What is the simplest way to do this without javascript if possible?
Here is an example of how you can do this using CSS and javascript. This will work for any height or width window as it gathers the values from the element.
I've commented the javascript but let me know if you wanted something else.
Demo
// Load image element
image = document.getElementById("random-window-image");
// Get the height and width of the window
window_width = document.getElementById("random-window-wrapper").offsetWidth;
window_height = document.getElementById("random-window-wrapper").offsetHeight;
// Calculate a random left value
temp_left = (image.width - window_width) * Math.random();
// Calculate a random top value
temp_top = (image.height - window_height) * Math.random();
// Apply values to the img
image.style.left = "-" + temp_left + "px";
image.style.top = "-" + temp_top + "px";
#random-window-wrapper {
width: 200px;
height: 200px;
overflow: hidden;
position: absolute;
}
#random-window-image {
position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="random-window-wrapper">
<img id="random-window-image" src="https://placeimg.com/640/480/any">
</div>
<!DOCTYPE html>
<html>
<head>
<style>
img {
position: absolute;
clip: rect(10px,90px,100px,0px);
}
</style>
</head>
<body>
<img src="https://i.stack.imgur.com/kt5HP.jpg" width="200" height="200">
</body>
</html>
I'm trying to make a circle out of images with different sizes and different shapes (some rectangle, some sqaure, some portrait, some landscape).
When I'm using: clip-path: circle(50% at 50% 50%); or border-radius: 50%;, it turns the image into a perfect circle, only if the image is square:
Is there a way to crop an image into a square and then use one of these methods to make it a perfect circle:
Using pure CSS withou using background-image (most images are given the background image from server side),
Keeping a 50% ratio - without losing aspect ratio - (both if border-radius or clip-path)(Images size may vary).
Here's a code snippet to show a square image and a rectangle image:
.clipped {
clip-path: circle(50% at 50% 50%);
}
Square<br>
<img src='http://i.imgur.com/d5byNNR.jpg' width="100" class='clipped' /><br><br>
Rectangle<br>
<img src='http://i.imgur.com/22W12EQ.jpg' width="100" class='clipped' />
You can use circle() but without the parameters:
.clipped {
clip-path: circle();
}
It appears to use the smaller side of your image as the circle's circumference.
Working sample here.
It works on Chrome and FireFox. IE and Edge still does not support clip-path
That's an another way to do it using pure CSS:
HTML
<div class="circular--portrait">
<img src='http://i.imgur.com/22W12EQ.jpg'/>
</div>
CSS
.circular--portrait {
position: relative;
overflow: hidden;
width: 100px;
height: 100px;
border-radius: 50%;
}
.circular--portrait img {
width: 100%;
height: auto;
margin-top: -30px;
}
Code Snippet (with portrait and landscape examples)
Alright, took me a moment but this is what I came up with:
function ScaleImage(srcwidth, srcheight, targetwidth, targetheight, fLetterBox, xOffSet, yOffSet) {
var result = { width: 0, height: 0, fScaleToTargetWidth: true };
if ((srcwidth <= 0) || (srcheight <= 0) || (targetwidth <= 0) || (targetheight <= 0)) {
return result;
}
// scale to the target width
var scaleX1 = targetwidth;
var scaleY1 = (srcheight * targetwidth) / srcwidth;
// scale to the target height
var scaleX2 = (srcwidth * targetheight) / srcheight;
var scaleY2 = targetheight;
// now figure out which one we should use
var fScaleOnWidth = (scaleX2 > targetwidth);
if (fScaleOnWidth) {
fScaleOnWidth = fLetterBox;
}
else {
fScaleOnWidth = !fLetterBox;
}
if (fScaleOnWidth) {
result.width = Math.floor(scaleX1);
result.height = Math.floor(scaleY1);
result.fScaleToTargetWidth = true;
}
else {
result.width = Math.floor(scaleX2);
result.height = Math.floor(scaleY2);
result.fScaleToTargetWidth = false;
}
//result.targetleft = Math.floor((targetwidth - result.width) / 2);
//result.targettop = Math.floor((targetheight - result.height) / 2);
result.targetleft = Math.floor((targetwidth - result.width) / 2 - xOffSet);
result.targettop = Math.floor((targetheight - result.height) / 2 - yOffSet);
return result;
}
function OnImageLoad(evt, xOffSet = 0, yOffSet = 0) {
var img = evt.currentTarget;
// what's the size of this image and it's parent
var w = $(img).width();
var h = $(img).height();
var tw = $(img).parent().width();
var th = $(img).parent().height();
// compute the new size and offsets
var result = ScaleImage(w, h, tw, th, false, xOffSet, yOffSet);
// adjust the image coordinates and size
img.width = result.width;
img.height = result.height;
$(img).css("left", result.targetleft);
$(img).css("top", result.targettop);
}
.result {
width: 250px;
height: 250px;
border: thick solid #666666;
overflow: hidden;
position: relative;
border-radius: 50%;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
No offset:
<div class='result'>
<img src="http://i.imgur.com/22W12EQ.jpg" style="position: absolute;" onload="OnImageLoad(event, 0, 0);"/>
</div>
Y offset:
<div class='result'>
<img src="http://i.imgur.com/22W12EQ.jpg" style="position: absolute;" onload="OnImageLoad(event, 0, 30);"/>
</div>
I took most of the work from this resource: https://selbie.wordpress.com/2011/01/23/scale-crop-and-center-an-image-with-correct-aspect-ratio-in-html-and-javascript/ and I've adepted it to allow the use of Offsets so you can crop any image at the position you want.
How it works
You create a div of any size you want. It can be square, but if you want an egg-like result, that works as well (lol). Then insert the image of any unknown size inside it.
Change onload="OnImageLoad(event, 0, 30); with the offsets you want. Positive offsets for moving the image left or down, negative for up or right.
Note: I did use jQuery for this.
Small update
Note: Target is mainly Chrome (perhaps Firefox) – as it is for an extension. But, of course, if there is an all-round solution that would be nice to know as well.
Another update
Note: Noticed that if there are no spaces in the text for A and it is too big, it pushes out B. Problem became worse and looks like I'm further from a solution then first thought. Updated sample code to allow input from user. Try sample without spaces.
I am having a fixed positioned box of full width and fixed height. It is placed inside an environment of variable / dynamic width.
+-----------------------------+
| |
| |
[=============================] << The box.
| |
| |
...
<- dynamic width ->
The box has two main children A and B. B takes precedence on width and are to hold all of it contents on given height, but not in a greedy way. A is eats remainder of space in a greedy fashion. On text-overflow in A, ellipsis should be added – and that is where I'm stuck.
Some examples.
1. B fills it's space, A expand to fill width.
+-------------------+--------+
| A________ | __B___ |
+-------------------+--------+
2. A has overflow, ellipsis added.
+-------------------+--------+
| A_____________... | __B___ |
+-------------------+--------+
3. B, has grown, A shrinks.
+----------------+-----------+
| A__________... | __B______ |
+----------------+-----------+
After fiddling around with various approaches from floats to absolute, relative and other types I finally landed on a table layout (as in CSS-table, not HTML). Can't get desired effect with other approach. If anyone know how it is OK to tell :)
Problem is the ellipsis part on overflow in A.
Can I somehow tweak e.g. how A is set up to get this?
Sample code:
Ignore the JavaScript, it is only a convenience routine to display the over and under-flow. (Found it nice to have whilst editing in Firefox's Style Editor)
/* Yes. It is all a mess and weird usage of variables vs this etc. */
function Hack() {
var x = 0,
n = 150,
wrap = document.querySelector('#wrap'),
left = document.querySelector('#left'),
right = document.querySelector('#right'),
txt = document.querySelector('#txt'),
ent = document.querySelectorAll('.entry'),
log = document.querySelector('#log'),
run = document.querySelector('#run'),
rt = document.querySelector('#rt'),
samp = document.querySelector('#sample'),
t = samp.value
;
this.rt = parseInt(rt.value) || 1000;
function getComp(e) {
var x = window.getComputedStyle(e, null);
return ''+
~~(parseInt(x.getPropertyValue('height'))) + 'x' +
~~(parseInt(x.getPropertyValue('width')))
;
}
this.status = function () {
log.textContent = 'Height / Width for:\n' +
' wrap : ' + getComp(wrap) + '\n' +
' left : ' + getComp(left) + '\n' +
' right : ' + getComp(right) + '\n' +
' sample: ' + getComp(txt) + '\n'
;
}
/* Change between long and short text in sample cells. */
this.flip = function () {
txt.textContent = x ? t : (new Array(n)).join(t);
Array.prototype.forEach.call(ent, function (e) {
e.textContent = x ? 'abc' : 'abcabc';
});
x ^= 1;
this.status();
}
/* Toggle auto run. */
this.update = function () {
t = samp.value;
this.rt = parseInt(rt.value);
if (!this.rt || this.rt < 10)
rt.value = this.rt = 100;
clearInterval(this.ttt);
if (run.checked)
this.ttt = setInterval(this.flip.bind(this), this.rt);
}
document.addEventListener('click', this.flip.bind(this));
run.addEventListener('click', this.update.bind(this));
rt.addEventListener('change', this.update.bind(this));
samp.addEventListener('keyup', this.update.bind(this));
this.update();
}
window.addEventListener('load', function () {
var hack = new Hack();
hack.flip();
});
* { margin : 0; padding : 0; }
#log { margin : 5pt; border : 1px solid #ccc; }
#filler { margin-top : 90px; height : 2000px; background : #efefef; }
label,
input { cursor : pointer; }
/* inner elements of cells in right -- (B) */
.hdr,
.entry { padding : 2px 5px; }
.hdr { font-weight: bold; }
#wrap { /* the red thing -- aka (the box) */
position : fixed;
top : 135px;
height : 23px;
background : #600;
color : #999;
height : 20px;
width : 100%;
display : table-row;
}
#left { /* the green thing -- aka (A) */
background : #044;
display : table-cell;
width : 100%;
}
#txt { /* sample text in left */ /* Where I want ellipsis */
display : block;
height : 20px;
width : 100%;
overflow : hidden;
text-overflow: ellipsis;
}
#right { /* the purple / blue thing -- aka (B) */
background : rgba(0,0,200,.5);
height : 20px;
display : table-cell;
width : 100%;
white-space: nowrap;
}
<p>Click document to expand text, or auto-run:</p>
<div>
<input type="checkbox" id="run" checked /><label for="run">Change every </label>
<input type="number" id="rt" value="1000" step="100" /> millisecond.
Sample text: <input type="text" value=" sample" id="sample" />
</div>
<pre id="log"></pre>
<!-- The box -->
<div id="wrap">
<div id="left">
<span id="txt">sample <!-- ellipsis here --> </span>
</div>
<div id="right">
<span class="hdr">Foo</span><span class="entry">abcd</span>
<span class="hdr">Bar</span><span class="entry">abcd</span>
</div>
</div>
<!-- EOF: The box -->
<div id="filler">dummy filler page height</div>
Is using Javascript ok?
text-overflow only works in table cells if there is a fixed width. The following snippet sets the max-width of the span to the correct width.
Place this in your flip function and in a resize event listener (if the containing div does not have a fixed width).
txt.style["max-width"] = "calc(" + wrap.clientWidth + "px - " + right.clientWidth +"px)";
Youu will also have to add white-space: nowrap to your #txt style.
function Hack() {
var x = 0,
n = 150,
t = 'sample ',
wrap = document.querySelector('#wrap'),
left = document.querySelector('#left'),
right = document.querySelector('#right'),
txt = document.querySelector('#txt'),
ent = document.querySelectorAll('.entry'),
log = document.querySelector('#log'),
run = document.querySelector('#run'),
rt = document.querySelector('#rt')
;
this.rt = parseInt(rt.value) || 1000;
function getComp(e) {
var x = window.getComputedStyle(e, null);
return ''+
~~(parseInt(x.getPropertyValue('height'))) + 'x' +
~~(parseInt(x.getPropertyValue('width')))
;
}
this.status = function () {
log.textContent = 'Height / Width for:\n' +
' wrap : ' + getComp(wrap) + '\n' +
' left : ' + getComp(left) + '\n' +
' right : ' + getComp(right) + '\n' +
' sample: ' + getComp(txt) + '\n'
;
}
/* Change between long and short text in sample cells. */
this.flip = function () {
txt.textContent = x ? t : (new Array(n)).join(t);
Array.prototype.forEach.call(ent, function (e) {
e.textContent = x ? 'abc' : 'abcabc';
});
txt.style["max-width"] = "calc(" + wrap.clientWidth + "px - " + right.clientWidth +"px)";
x ^= 1;
this.status();
}
/* Toggle auto run. */
this.toggle = function (r) {
this.rt = parseInt(rt.value);
if (!this.rt || this.rt < 10)
rt.value = this.rt = 100;
clearInterval(this.ttt);
if (run.checked)
this.ttt = setInterval(this.flip.bind(this), this.rt);
}
document.addEventListener('click', this.flip.bind(this));
run.addEventListener('click', this.toggle.bind(this));
rt.addEventListener('change', this.toggle.bind(this, 1));
this.toggle();
}
window.addEventListener('load', function () {
var hack = new Hack();
hack.flip();
});
* { margin : 0; padding : 0; }
#log { margin : 5pt; border : 1px solid #ccc; }
#filler { margin-top : 90px; height : 2000px; background : #efefef; }
label,
input { cursor : pointer; }
/* inner elements of cells in right -- (B) */
.hdr,
.entry { padding : 2px 5px; }
.hdr { font-weight: bold; }
#wrap { /* the red thing -- aka (the box) */
position : fixed;
top : 135px;
height : 23px;
background : #600;
color : #999;
height : 20px;
width : 100%;
display : table-row;
}
#left { /* the green thing -- aka (A) */
background : #044;
display : table-cell;
width : 100%;
}
#txt { /* sample text in left */ /* Where I want ellipsis */
display : block;
height : 20px;
width : 100%;
overflow : hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
#right { /* the purple / blue thing -- aka (B) */
background : rgba(0,0,200,.5);
height : 20px;
display : table-cell;
width : 100%;
white-space: nowrap;
}
<p>Click document to expand text, or auto-run:</p>
<div>
<input type="checkbox" id="run" checked /><label for="run">Change every </label>
<input type="number" id="rt" value="1000" step="100" /> millisecond.
</div>
<pre id="log"></pre>
<!-- The box -->
<div id="wrap">
<div id="left">
<span id="txt">sample <!-- ellipsis here --> </span>
</div>
<div id="right">
<span class="hdr">Foo</span><span class="entry">abcd</span>
<span class="hdr">Bar</span><span class="entry">abcd</span>
</div>
</div>
<!-- EOF: The box -->
<div id="filler">dummy filler page height</div>
Needing a solution to autoresize text in a fixed sized container. A single word should appear really large filling the container. The longer the string the smaller the font becomes as it resizes to fit on one line.
The code I've found (see below) is almost there but for some reason wraps the text onto a second line. Any suggestions on how I could fix it so no matter how long the string of text it will resize and always be just a single line of text?
Thanks
<html>
<head>
<style type="text/css">
#dynamicDiv
{
background: #CCCCCC;
width: 240px;
height: 64px;
font-size: 64px;
overflow: hidden;
}
</style>
<script type="text/javascript">
function shrink()
{
var textSpan = document.getElementById("dynamicSpan");
var textDiv = document.getElementById("dynamicDiv");
textSpan.style.fontSize = 64;
while(textSpan.offsetHeight > textDiv.offsetHeight)
{
textSpan.style.fontSize = parseInt(textSpan.style.fontSize) - 1;
}
}
</script>
</head>
<body onload="shrink()">
<div align='center' id="dynamicDiv"><span id="dynamicSpan">Here is a string of text I want on just one line</span></div>
</body>
</html>
This code works, but I am using a little jQuery, I hope this helps in some way...
<style type="text/css">
#container {
height:100px;
background-color:#eeeeee;
text-align:center;
font-family:Myriad Pro;
}
<style>
<div id="container">01234567890123456789</div>
<script type="text/javascript">
$(document).ready(function()
{
var w = parseInt($("#container").width());
var l = parseInt($("#container").html().length);
var fontSize = ( (w / l) * 2 ) - 2;
fontSize = fontSize+'px';
$("#container").css('font-size', fontSize);
});
</script>
I have a div that has the following CSS:
.div_stuff {
width: 830px;
margin: 20px auto;
font-size:22px;
}
How do I prevent the text that goes to the next line to not align left right under the text above but simply become centered on the next line?
Although I'm not sure if I understood what you want to achieve and I can't find a use case for this... Changing the alignment from the second line on would be possible by adding some span tags with javascript/jQuery (DEMO):
$(function() {
var box = $('.div_stuff');
var text = box.text();
var words = text.split(' ');
box.text(words[0]);
var height = box.height();
var chars = 0;
for(var i = 1; i < words.length; i++){
box.text(box.text() + ' ' + words[i]);
chars += words[i-1].length + 1;
if(box.height() > height){
height = box.height();
box.html('<span class="first-line">' + text.substring(0,chars) + '</span><span class="following-lines">' + text.substring(chars+1, text.length)+'</span>');
break;
}
}
});
And set a different alignment to them:
span {
display: block;
}
.first-line {
text-align: left;
}
.following-lines {
text-align: center;
}
I've used that answer for determining auto line breaks.
Add text-align: center to center the text inside. You are centering the div position only.
you can try css3 text justified
http://www.w3schools.com/cssref/css3_pr_text-justify.asp