I basically have two divs, one being absolutely placed over the other. I also have a variable from an application that represents the percent of a VoIP test completeness. Now I need to have the progress bar call the percent variable using JavaScript.
I have been told I need an asynchronously update the progress bar but im unsure how to do that. im aware there are many ways to do this. I am still learning JavaScript and need an example to work with. I have tried a number of what I would assume would work but what I post here is just the most recent attempt.
I am referencing this YouTube example/tutorial, but obviously I am not using setInterval() because I want the width based on the variable. I have the test run on a button's click and felt that it was unnecessary to include.
//Variable for the test's percent. it provides just a number in increments of 5
<param name="js-prog" value="progress($PROGRESS$)">\
function progress(pRess) {
const pRessBar = document.getElementsByClassName('ressBar');
const computedStyle = getComputedStyle(pRessBar);
const styleWidth = parseFloat(computedStyle.getPropertyValue('pwidth')) || 0
pRessBar.style.setproperty('pwidth', styleWidth + pRess)
}
.ressBar {
position: relative;
width: 500px;
height: 3em;
background-color: #111;
margin-left: auto;
margin-right: auto;
border-radius: 15px;
color: white;
}
.ressBar::before {
content: attr(data-label);
display: flex;
align-items: center;
position: absolute;
left: .5em;
top: .5em;
bottom: .5em;
width: calc(var(pwidth, 0) * 1%);
min-width: .1rem;
max-width: calc(100% - 1em);
background-color: #069;
border-radius: 15px;
padding: 1em;
}
`<div class="ressBar" Id="ressBar" style="pwidth: .1" data-label="Loading..."></div>
css variables should always have double dash at beginning of their names.
Personally, I find the example twisted on youtube,
for the same result, I see things like that:
const pRessBar = document.getElementById('ressBar')
function setRessBar_percent(val) { // 0 <= val <= 100
pRessBar.style.setProperty('--pwidth', `${val}%`)
pRessBar.dataset.label = (val<100)? 'Loading...' : 'Loading completed ;-)'
}
/* test part */
inSiz.oninput=_=>
{
inSiz.nextSibling.textContent = `${inSiz.value}%`
setRessBar_percent(inSiz.value)
}
#ressBar {
box-sizing: border-box;
position: relative;
width: 500px;
--pwidth: 50%;
height: 3em;
background-color: #111;
margin: 1em auto;
border-radius: 1.5em;
color: white;
border: .5em solid #111; ; /* try red color */
overflow: hidden;
}
#ressBar::before {
position: absolute;
top: 0;
left: calc( -100% + var(--pwidth) );
content: '';
width: 100%;
height: 100%;
background-color: #069;
border-radius: 1em;
}
#ressBar::after {
content: attr(data-label);
position: absolute;
left: 1em;
top: 0;
height: 2em;
line-height: 2em;
}
/* test part */
#inSiz {
margin : 1em;
width: 200px;
}
<div Id="ressBar" data-label="Loading..."></div>
<!-- test part -->
<hr>
<p>play with this range : <p>
<input id="inSiz" type="range" value="50" min="0" max="100" step="1"><span>50%</span> (supposed value for the progress bar)
<p> to test the appearance of the progress bar<p>
let me pick your brain and try to pick this apart.
no problemo amigo ;)
double dash makes sense but I thought that JavaScript doesn't like dashes or other certain symbols.
it's just in the doc, and for javascript it's not a symbol or anything but just a string
Using CSS custom properties (variables) ==doc== or for ==JS part==
so #ressBar::before is for the width that is being changed and #ressBar::after is for the text "Loading..."?
the text "Loading ..." is in the ::after,
while the progress bar is in the ::before, so that it appears below.
Putting the text and the progress bar together is a bad idea:
if the progress is zero then the text cannot be displayed in a null space
is there a reason why the calculation for the "width" is under left vs right?
in my code the blue bar is width: 100% of it's parent.
It just "moves" more or less to the right depending on the progress value requested.
the excess part is to the left in negative value of its parent element (#ressBar { which has as rule css: overflow: hidden;
two advantages:
1- you just make the size you want on the parent with no other css change
2- the blue bar has no css problems with the border-radius: 1em; when it size is less than 1em
I don't understand how the JavaScript portion is working. I understand pRessBar but I don't understand your comment referencing 0 <= val <= 0 OR the syntax for setProperty ``` '${val}%' ``
0 <= val <= 0 is a mistake and should be 0 <= val <= 100 that's say val argument should be between 0 and 100
${val}% it's a normal use of arguments in Template literals if val==45 it's made 45% (% is just a character like another)
Related
On my website, I am aligning a body of text precisely as exemplified in the following snippet.
html, body {
width: 100%;
height: 100%;
font-family: arial;
font-size: 48px;
text-transform: uppercase;
}
body {
margin: 0;
background: skyblue;
}
div {
width: 200px;
height: 100vh;
padding-top: calc(100vh - (1.5rem * 1.35));
box-sizing: border-box;
border: solid red 1px;
}
span {
line-height: 1.35;
display: inline-block;
border: solid black 1px;
}
<div><span>This</span> <span>is</span> <span>a</span><span>body</span><span>of</span> <span>text.</span></div>
However, I was hoping to take it one step further. For instance, I want to be able to place the top of the text as close as possible to, say, 60vh from the top of the page while still displaying half of the last line. Below is an example of what I mean in JS.
Note: Just noticed the second snippet does not display properly unless you open it to edit it. If you transfer it to codepen, it should work properly.
const
div = document.querySelector('div'),
span = document.querySelector('span'),
lineHeight = parseFloat(getComputedStyle(span).lineHeight),
target = innerHeight * 0.6,
remainder = (innerHeight - target) / lineHeight % 1 * lineHeight
div.style.paddingTop = target + remainder - lineHeight / 2 + 'px'
html, body {
width: 100%;
height: 100%;
font-family: arial;
font-size: 48px;
text-transform: uppercase;
}
body {
margin: 0;
background: skyblue;
}
div {
width: 200px;
height: 100vh;
position: absolute;
box-sizing: border-box;
border: solid red 1px;
}
span {
line-height: 1.5;
display: inline-block;
border: solid black 1px;
}
<div><span>This</span> <span>is</span> <span>a</span> <span>body</span> <span>of</span> <span>text.</span></div>
Notably, I know you can obviously find the "remainder" using calc, viewport units, and rem, but the rest is what is confusing because I am not great at math and also lacking sleep.
Hence I was hoping that somebody out there, who is better at math than me, would be able to tell me whether or not a pure CSS solution without preprocessors is possible (i.e. using only calc, viewport units, rem units, etc) before I waste any more time thinking about this. I know there are some nifty CSS formulas for fluid typography, but is something like this possible?
[ edit ] I thought about this some more while laying in bed. I do not believe it is possible without being able to calculate the "remainder." And there does not seem to be any way to calculate the "remainder" with only addition, subtraction, multiplication, and division. Please correct me if I am wrong.
The goal is to have the DIV tag be 100% of the document's height and then the text is offset a little bit within the DIV?
I think just adding another tag within the DIV to offset all the text can work. You said you want 60vh. Line Height should also be used when dealing with text height.
html, body {
width: 100%;
height: 100%;
font-family: arial;
font-size: 48px;
text-transform: uppercase;
}
body {
margin: 0;
background: skyblue;
}
div {
width: 200px;
height: 100vh;
box-sizing: border-box;
border: solid red 1px;
}
p
{ margin: 0;
padding-top: 60vh;
margin-top: -0.8em;
line-height: 1.6em;
}
span {
line-height: 1.35;
display: inline-block;
border: solid black 1px;
}
<html>
<body>
<div><p><span>This</span> <span>is</span> <span>a</span><span>body</span><span>of</span> <span>text.</span></p></div>
</body>
</html>
Or is this not quite it?
I have been trying for hours to change the width of the wheel and items, but I cant figure out how to https://jsfiddle.net/ywm3zbc4/105/
I want to change the wheel width to 600px and still use the function to choose where the wheel should land
.wheel {
width: 600px;
}
var wheel = new SpinWheel(20);
Without it breaking compleatly, when running it after changing the width it skips over and doesnt land on "20"
As Inside wheel-wrapper class you have (39 wheel-items) wheel-item. you need to change width at both places wheel-wrapper and wheel-item. you need to divide wheel-wrapper by wheel-item you supposed to want. for example, I have took 2925px width of wheel-wrapper and you had 39 items. As per this, wheel-item's width 75px.
Note: you can change it as per your requirements.
Changes I have made:
.wheel {
width: 470px;
height: 50px;
padding: 10px 9px;
margin: 0 auto;
overflow: hidden;
&-wrapper {
width: 2925px; //changed
}
&-item {
float: left;
width: 75px; //changed
height: 30px;
color: white;
text-align: center;
p {
line-height: 30px;
margin: 0;
}
}
Test link
My Goal:
Here is what I'm trying to accomplish. We have an list of categories that appear on a page. The number of categories is unknown. The description can be pretty much any size... yet we want a uniform look. So, we are using the dotdotdot plugin to put ellipses on the paragraphs. When you hover over the item, it should expand the description and show the full text.
I want that hover to float or overlay whatever is below it. Due to some of my layout items (see my NOTE below) my sccontainer element doesn't have a set height. It's dynamic based on the content... with a max-height set.
When I change that height to AUTO in the hover event (which causes the text to flow down and displays all the content), I lose the background on the sccontainer element.
Some pertinent CSS:
.sccontainer { width: 280px; zoom: 1; float: left; margin: 5px 10px; padding: 0; border: 1px solid #8697a1; -moz-border-radius: 5px; border-radius: 5px; -moz-box-shadow: 0 0 6px #777; -webkit-box-shadow: 0 0 6px #777; box-shadow: 0 0 6px #777; -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=6, Direction=90, Color='#777777')"; filter: progid:DXImageTransform.Microsoft.Shadow(Strength=6, Direction=90, Color='#777777'); position: relative; background: #fff url(http://imagecss.com/images/background.jpg) repeat-x left top; }
.sccontainer .parent { position: absolute; width: 270px; }
.sccontainer .image { margin: 5px; float: left; }
.sccontainer .image img { width: 48px; }
.sccontainer .icon { margin: 0; }
.sccontainer p { margin: 8px; padding: 0; max-height: 145px; }
.sccontainer h1 { line-height: 24px; display: inline-block; vertical-align: middle; width: 200px; height: 48px; padding: 0; margin: 5px 0 0 0; overflow: hidden; }
.sccontainer h1 a { padding: 0; font-size: 24px; color: #fff; font-weight: normal; }
.sccontainer .content { position: relative; height: 210px; padding: 0 5px; font-size: 15px; line-height: 22px; width: 270px; }
.sccontainer a:hover { text-decoration: underline; }
.sccontainer.hover { height: 250px; }
.sccontainer.hover .content { height: auto; }
.sccontainer.hover .content p { min-height: 135px; max-height: none; }
jsFiddle:
Here is a jsFiddle version of what I have right now. You can see this in action, if you hover over the text in the blue box. It's a bit large, so I used jsFiddle instead of putting all the bits here code tags...
http://jsfiddle.net/ztMM5/1/
And here is a mockup of what I'd like to see. Method 5a expands slightly to show the full content.... yets overlaps the red line. None of the other items move around or are affected.
NOTE: Sorry for the size of things. I've trimmed it down about as much as I can. Also, I am modifying an existing intranet website... it's 3rd party, so I have limited control of the source code - hence the table usage. :(
What I've Tried/Researched:
I believe the issue stems from the fact that my sccontainer item is floating, and doesn't have a height specified. That's why the image disappears.
I had a version that kept the background... but the sccontainer box didn't resize like we need... the text just overflowed it... rather ugly.
I don't know enough CSS to make this all work right. I'm not adverse to using jQuery to do more if needed.
I did work on a version that handled most of the hover using the :hover stuff... but it didn't work quite as well as the jQuery approach.
This answer may not solve your specific problem but it may help others with a similar scenario (working with tables makes difficult to render a clean layout in most cases.)
I ran into this issue before and this is how I solved it. It basically relies in an html nested div structure to achieve the expandability of the content without affecting the floating layout of the near elements :
<div id="wrapper" class="cf"><!--wrapper with border and CLEARED-->
<div class="sccontainer"><!--position relative-->
<div class="inner"><!--position absolute-->
<div class="content"><!--position relative-->
<!-- my content here -->
</div>
</div>
</div>
<!-- more containers etc-->
</div><!--END wrapper-->
First, we are going to apply the infamous clear-fix hack to the #wrapper container (use your preferred method):
.cf:after {
visibility:hidden;
display:block;
content:"";
clear:both;
height:0
}
* html .cf {
zoom:1
}
/* IE6 */
*:first-child+html .cf {
zoom:1
}
Then the style for the .sccontainer container :
.sccontainer {
width: 280px; /* or whatever - could be % for responsiveness */
padding-bottom:200px; /* any value to give height without using height ;) */
position: relative;
float: left;
margin: 5px 10px; /* or whatever */
overflow: hidden; /* this is important to keep all same height and big content out of sight */
z-index: 1; /* this is important too, see later */
background: white url("imagebackground.jpg") 0 0 repeat-x; /* need to explain? */
}
Then the .inner container, which actually will help to keep the layout in order if we hover the elements
.inner {
position: absolute; /* please don't move */
width: 100%; /* to fill the whole parent container */
height: 100%; /* same */
}
And the content :
.content {
position: relative;
background: white url("imagebackground.jpg") 0 0 repeat-x; /* not redundant though */
width: 100%; /* helps to fill the gaps with small content */
height: 100%; /* same, specially if using image backgrounds */
/* other styles, etc */
}
NOTE: we should apply same border-radius properties to the three containers and box-shadow to .sccontainer and .content for consistency
Now, what happens when we hover ?
.sccontainer:hover {
overflow: visible; /* show the full content */
z-index: 999; /* place me on top of the others if needed (which lower z-index, remember?) */
}
.sccontainer:hover .content {
height: auto; /* as it really is, including background image */
}
NOTES : this effect will happen regardless if the content's height is smaller than the parent container's height. You may not like the effect mostly if you are using borders and shadows (could be shown as smaller box inside the parent container) so we could add an extra class to .sccontainer like
<div class="sccontainer withhover">
and apply the hover effects only if that class exist like
.sccontainer.withhover:hover {
overflow: visible;
z-index: 999;
}
... and use a bit of jQuery to remove that class for shorter content, so it won't be affected :
jQuery(document).ready(function ($) {
$(".sccontainer").hover(function () {
var $contentHeight = $(this).find(".content").height();
if ($(this).innerHeight() > $contentHeight) {
$(this).removeClass("withhover");
}
});
});
See JSFIDDLE
I'm working on a hobby project of mine -- it's something of a glorified RSS feed reader/grabber. I've been able to get most things working, but for some reason I cannot get the text in a certain span to be drawn above an animated div.
When a feed is grabbed, certain operations are performed before displaying the results. During this time, I keep track of the progress and display them in an animated "progress bar" div. All of the sub-operations each have their own progress bars, and they all work correctly (text on top of bar), but the final progress bar (overall progress) does not layer the text correctly.
I created a simple mock-up in JSFiddle to give an example of my problem.
$('#progress-total-box').bind('click', draw);
function draw() {
if (($('#progress-totalbar-fill').css('width')) == "0px") {
$('#progress-total-box').unbind();
$('#progress-totalbar-fill').animate({width: '100%'}, 2000, function() {
var description = document.createElement('span');
$(description).attr('id', '#progress-total-text');
$(description).html('100%');
$('#progress-totalbar-empty').append(description);
$('#progress-total-box').bind('click', draw);
});
}
else {
$('#progress-total-box').unbind();
$('#progress-totalbar-fill').animate({width: 0}, 2000, function() {
document.getElementById('progress-totalbar-empty').innerHTML = '';
$('#progress-total-box').bind('click', draw);
});
}
}
The style/position/etc is purely for sake of demonstration. In this example, when the grey loading bar div is clicked, it animates its width from 0% to 100% (or vice-versa). When the animation is complete, a new child span is created and appended to the 'empty bar' background div, wherein the total percentage is displayed (100%, in this case).
This span element is intentionally removed when the bar is reset.
Do you guys have any ideas as to what's going wrong, and how I can fix it?
I have encountered this error is present in both Chrome and Firefox.
Thanks in advance!
There are multiple problems here.
First off, you need to remove the # from this line
$(description).attr('id', 'progress-total-text');
The new span, was never getting the css it was supposed.
Second, you need to either change your markup or your css.
In this case, I updated the CSS, but the id name don't make sense anymore
body {
width: 100%;
height: 125px;
margin: 0;
}
#progress-category-box {
position: relative;
width: 100%;
height: 100%;
font-size: 0;
background-color: red;
}
#progress-total-box {
position: relative;
width: 100%;
height: 40px;
top: 32.5%;
float: right;
text-align: center;
background-color: #515A5C;
}
#progress-totalbar-empty {
position: relative;
width: 100%;
height: 100%;
border: 1px solid #97b0b1;
background-color: transparent;
z-index: 3;
}
#progress-totalbar-fill {
position: relative;
width: 0%;
height: 100%;
top: -42px;
border-left: 1px solid #97b0b1;
border-top: 1px solid #97b0b1;
border-bottom: 1px solid #97b0b1;
background-color: #00FF00;
z-index: 2;
}
#progress-total-text {
position: relative;
color: black;
top: 30%;
font-size: 15px;
z-index: 3;
}
Thing is, you were showing the animated div over the text.
So I put the text over the animation and put a transparent background behind it.
I applied the grey background to the container instead. I also changed it's height and applied height:100% to it's children.
Here's a full fiddle
Basically, I want many(>25) divs to be displayed one on top of the other so that only one can be seen at a time. I have the jQuery UI draggable implemented, so once a div is dragged away, the next div is shown. What CSS do I need to make such a stack of divs? jQuery is also available if required.
Thanks!
Try this:
CSS
div.square {
cursor: pointer;
width: 100px;
height: 100px;
border: 2px dashed purple;
position: absolute;
top: 30px;
left: 30px;
font-size: 50px;
line-height: 100px;
text-align: center;
color: white;
}
jQuery + jQueryUI
var count = 25;
var colors = ['red','green','blue','orange','yellow'];
while(count--) {
$('<div/>',{className:'square', text:count}).draggable().css({position:'absolute','z-index':count, text:count, backgroundColor:colors[count % 5]})
.appendTo('body');
}
EDIT:
I just noticed that for some reason in IE and Safari .draggable() overrides the absolute positioning with relative, so you need to set it back to absolute after you made it draggable.
Updated the example above.
http://jsfiddle.net/p9wWA/
You mean something like this?
#relative_container { position: relative; }
#relative_container div { position: absolute; top: 0; left: 0; width: 100px; height: 100px; }
#relative_container div.item_1 { z-index: 100; } /* Higher index means its more on top */