Dynamically setting CSS property left using width calculation Angular 6 - css

I'm currently building a CSS audio player and I am setting the width of a div to represent the current progress of the audio using a [style] like below, and it works just great:
<div class="player-progress-current" [style.width.%]="(currentTime * 100)/duration"></div>
I also want to draw a little circle at the end of the progress div above by setting the 'left' CSS property of another class. This would be in english:
(Parent Width px) - (Progress Width px)
I've tried using the calc() function but it doesn't like it and the percentage calculated wouldn't know to use the width I think....
<div class="player-progress-handle" [style.left.px]="calc(100% - (currentTime * 100)/duration"></div>
The CSS classes are:
.player-progress-current {
width: 100%;
height: 1px;
background-color: red;
}
.player-progress-handle {
position: relative;
bottom: 1px;
border: 1px solid #f50;
border-radius: 100%;
height: 8px;
width: 8px;
background-color: #f50;
box-sizing: border-box;
margin-top: -4px;
margin-left: -4px;
}
Any ideas how the best way to do this is? I'm sure I can find a hacky way but would like the find the correct way

You might use :after for your handle and get rid of the calculations:
.player-progress-current {
position: relative;
width: 50%;
height: 1px;
margin: 20px 0;
background: red;
}
.player-progress-current:after {
content: '';
position: absolute;
right:-3px; bottom: 1px;
border: 1px solid #f50;
border-radius: 55%;
height: 8px;
width: 8px;
background-color: #f50;
box-sizing: border-box;
}
<div class="player-progress-current" [style.width.%]="(currentTime * 100)/duration"></div>

Related

CSS border in Chrome: strange grey line

I have a problem with a border in Chrome. The green border has some grey lines.
Firefox: not visible -> ok!
Chrome: not visible but visible in the dev tools, mobile phone.
Chrome on my phone: visible
Here is a screenshot that shows my problems!
https://abload.de/img/cssiee7s.jpg
1) When you go to http://www.seelenpuls.at/hpneu/m_biografie_leander_de.php
there are two small grey lines
2) When you go to http://www.seelenpuls.at/hpneu/m_neues_de.php there are even more problems.
3) The menu button has an orange border (mobile only) ... and I don't know why as there is no such color in my CSS.
Please help!
Here's the code. The bold part is the border that causes the problems.
* { padding: 0; margin: 0; }
body
{
font-family: sans-serif, Verdana, Arial;
color: #000000;
background-color: #556B2F;
}
#center {
position: relative;
width: 350px;
height: 630px;
box-sizing: border-box;
margin: 5px auto 0px auto;
}
#logo {
position: absolute;
width: 350px;
height: 220px;
background-color: #ffffff;
box-sizing: border-box;
background-image: url("img/m_bg_c.jpg");
background-repeat: no-repeat;
background-size: 350px 220px;
}
#navi
{
position: absolute;
top: 175px;
width: 60px;
height: 40px;
font-size: 16px;
color: #000000;
background-color: #ffffff;
margin-left: 10px;
}
#header
{
position: absolute;
top: 187px;
width: 238px;
height: 30px;
font-size: 16px;
color: #000000;
left: 85px;
}
#content
{
position: absolute;
top: 218px;
width: 350px;
box-sizing: border-box;
color: #000000;
background-color: #ffffff;
font-size: 14px;
overflow: auto;
padding-left: 5px;
padding-right: 5px;
**border-bottom: 5px solid #556B2F**;
}
Ok so there is a couple of things that are going on in your css.
White lines
For your content div, I would use a width of 100% for mobile devices now, as you scale to tablets and desktops you can change to a more fixed or fluid width. I would also remove the border bottom property. This is not fully extending to the width of the content box and I am unsure if it has to do with the border-sizing property you are using. I would also apply the border-sizing this way so it is applied to every element in your html
* {
box-sizing: border-box;
}
Orange border - this is caused by the :focus pseudo css property of the button you are using, you can remove it this way
button:focus {
outline: none;
}
CSS Normalize or CSS Reset - consider using one of these stylesheets in your website. They help you rendering all elements more consistently through all browsers. This will save you the time of remove the :focus property, like I mentioned above in any project moving forward. Most popular CSS frameworks utilize this to normalize basic styles.
Link to Normalize.css

IE Workaround? border-radius + background-color + border = bleeding background [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
It seems something like this has been addressed before, but most of what I'm finding is for the more generic issue that doesn't pertain to most browsers today. I'm encountering the known IE issue where using border-radius with a border and a background (a color in my case) results in the background bleeding beyond the border.
I'm wondering if there is a workaround that actually can mask this issue... Some of the things I've tried:
<meta http-equiv="X-UA-Compatible" content="IE=10" />
overflow:hidden on the parent
background-clip:border-box
adding .1 to the border-radius
None of these have worked. Is there another workaround (other than "use images") while I wait for yon IE team to fix things?
I've created a fiddle that illustrates this well and documents what I've found in more detail.
I have experienced this before.
I recommend instead styling the border with CSS generated content, in a manner such as this:
.redcircle::after {
content:'';
display:block;
left:0;
top:0;
right:0;
bottom:0;
border-radius:100px;
border:10px solid yellow;
position:absolute;
pointer-events: none; //ensures no clicks propogate if this is desired
}
You can crate an ::before or ::after CSS Pseudo and make your background: red; on them. Set your width, height and border-radius on 100% and for example don't change z-index to -1, you can see his get the inside width and hight and don't bleeding out.
Screenshot from Explorer 9 on Vista
And now for example (how its look without z-index play):
body {
background: white;
}
.bluebox {
background: blue;
width: 200px;
height: 200px;
}
.redcircle {
position: absolute;
left: 140px;
top: 40px;
text-align: center;
height: 100px;
width: 100px;
border-radius: 100px;
font-size: 100px;
line-height: 100px;
color: black;
border: 10px solid yellow;
}
.redcircle::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 100%;
background: red;
}
<div class="bluebox">
<div class="redcircle">
!
</div>
</div>
And this one for using:
body {
background: white;
}
.bluebox {
background: blue;
width: 200px;
height: 200px;
}
.redcircle {
z-index: 1;
position: absolute;
left: 140px;
top: 40px;
text-align: center;
height: 100px;
width: 100px;
border-radius: 100px;
font-size: 100px;
line-height: 100px;
color: black;
border: 10px solid yellow;
}
.redcircle::before {
z-index: -1;
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 100%;
background: red;
}
<div class="bluebox">
<div class="redcircle">
!
</div>
</div>
Fiddle Demo
Borrowing from Zeev's answer, which moves the background-color to a :before or :after (which only substitutes a subpixel gap for a subpixel bleed, and across more browsers), and Phil's answer, which moves the border to an :after (which didn't really fix the problem).
Move the background-color to a :before as suggested by Zeev, but give it padding equal to the border-width minus two (or use calc()). Then give it negative top and left positioning with that same amount.
Then move the border to the :after but give it negative top and left positioning equal to the border-width.
This creates an oversized background and recenters it below the content. Then it creates an oversized border and centers it around the content. You could probably oversize the background to other degrees and get the same result. The point is to make it bigger than the hole inside the border, but smaller than the outside of the border. This, naturally, would fail with thin borders, though.
body {
background: white;
}
.bluebox {
background: blue;
width: 200px;
height: 200px;
}
.redcircle {
z-index: 1;
position: absolute;
left: 150px;
top: 50px;
text-align: center;
height: 100px;
width: 100px;
border-radius: 100px;
font-size: 100px;
line-height: 100px;
color: black;
}
.redcircle::before,
.redcircle::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
border-radius: 100%;
}
.redcircle::before {
z-index: -1;
background: red;
top: -8px;
left: -8px;
padding: 8px;
}
.redcircle::after {
top: -10px;
left: -10px;
border: 10px solid yellow;
}
<div class="bluebox">
<div class="redcircle">
!
</div>
</div>
background-clip fixes this issue:
.bluebox {
background-clip: padding-box;
}

CSS Border with a botton

Can I achieve a custom CSS border with a button at one end which looks like this
Without url(some image link)?
Note: I want so because when I want to change color, I have to manipulate image.
I have achieved using image JS Fiddle
#stretch {
border-image: url(http://akitech.org/img/border.png) 30 30 stretch;
}
The easiest way is to use CSS pseudo-elements to create the decoration (the circle at the left) and to mask the chamfer at the right of the border (the angle at which the border-right would otherwise meet):
div {
border: 10px solid transparent;
width: 250px;
padding: 10px 20px;
position: relative;
/* this property has to be set to change the border-color: */
border-bottom-color: #f90;
}
/* common shared styles: */
div::before,
div::after {
/* to ensure the pseudo-elements are rendered: */
content: '';
/* for positioning: */
position: absolute;
/* positioning the element with its uppermost edge
against the bottom of the element, against the
upper side of the bottom-border: */
top: 100%;
/* again, set to change the color of the ends: */
background-color: #f90;
}
div::before {
/* position against the left edge: */
left: 0;
/* move the pseudo element 10px up, and
10px left: */
margin: -10px 0 0 -10px;
height: 30px;
width: 30px;
/* making the pseudo-element a circle: */
border-radius: 50%;
}
/* masking the chamfer of the border-bottom's
right-most edge: */
div::after {
left: 100%;
/* making the height/width the same width
as the border itself: */
height: 10px;
width: 10px;
}
div {
border: 10px solid transparent;
width: 250px;
padding: 10px 20px;
position: relative;
border-bottom-color: #f90;
}
div::before,
div::after {
content: '';
position: absolute;
top: 100%;
background-color: #f90;
}
div::before {
left: 0;
margin: -10px 0 0 -10px;
height: 30px;
width: 30px;
border-radius: 50%;
}
div::after {
left: 100%;
height: 10px;
width: 10px;
}
<div id="stretch">Here, the image is stretched to fill the area.</div>
In order to have these borders adapt to the length of the text, either the elements you want to have custom-bordered must themselves be able to contract to the width of the text, either using float:
div {
border: 10px solid transparent;
position: relative;
border-bottom-color: #f90;
padding-left: 20px;
/* forces the element to take up only that space required by
its (non-floated) contents: */
float: left;
/* forces the floated elements to the next line: */
clear: left;
}
div {
border: 10px solid transparent;
position: relative;
border-bottom-color: #f90;
padding-left: 20px;
float: left;
clear: left;
}
div::before,
div::after {
content: '';
position: absolute;
top: 100%;
background-color: #f90;
}
div::before {
left: 0;
margin: -10px 0 0 -10px;
height: 30px;
width: 30px;
border-radius: 50%;
}
div::after {
left: 100%;
height: 10px;
width: 10px;
}
<div>text</div>
<div>longer text</div>
<div>much longer text</div>
<div>much much much longer text</div>
Or, possibly more simply, use display: inline-block:
div {
border: 10px solid transparent;
position: relative;
border-bottom-color: #f90;
padding-left: 20px;
display: inline-block;
}
div {
border: 10px solid transparent;
position: relative;
border-bottom-color: #f90;
padding-left: 20px;
display: inline-block;
}
div::before,
div::after {
content: '';
position: absolute;
top: 100%;
background-color: #f90;
}
div::before {
left: 0;
margin: -10px 0 0 -10px;
height: 30px;
width: 30px;
border-radius: 50%;
}
div::after {
left: 100%;
height: 10px;
width: 10px;
}
<div>text</div>
<div>longer text</div>
<div>much longer text</div>
<div>much much much longer text</div>
Or display: inline (these don't automatically force new-lines between elements, obviously):
div {
border: 10px solid transparent;
position: relative;
border-bottom-color: #f90;
padding-left: 20px;
display: inline;
}
div {
border: 10px solid transparent;
position: relative;
border-bottom-color: #f90;
padding-left: 20px;
display: inline;
}
div::before,
div::after {
content: '';
position: absolute;
top: 100%;
background-color: #f90;
}
div::before {
left: 0;
margin: -10px 0 0 -10px;
height: 30px;
width: 30px;
border-radius: 50%;
}
div::after {
left: 100%;
height: 10px;
width: 10px;
}
<div>text</div>
<div>longer text</div>
<div>much longer text</div>
<div>much much much longer text</div>
summary:
for simplist way to this question, should not using svg, pure css can draw the shape author expected very well cause it's a combination of cycle(border radius)+rect(thicker line), let's refer to the David's answer should be the easiest and most clean way to draw that shape under text.
//below is my debugging history and tries (i searched out many ways to approach it);
//though not good answers
I use background css attribute (not OP wanted) Op used border-image also valid.
<div class="custom-border" >SOME TEXT HERE</div>
<style>
.custom-border{
padding-left:20px;
width:200px;
background:url(http://img1.wikia.nocookie.net/__cb20140224040010/shantae/images/b/bc/HGH_border_bottom.png) 0px 5px no-repeat;
background-size:contain;
height:150px;
}
</style>
later I realized OP might dislike using image traditional way, I re understand the
question is asking how to draw that shape in pure css and place it under the text and the responsive should be as flexible as the traditional way the svg shape will auto strech with the text placed on it.
after that, I've find some way to generate svg and place under text
see if it works for no image solution or you can get it improved based on fiddle
http://jsfiddle.net/hahatey/hsfxS/1464/
during the process, i've found this useful tool of generating svg from below reference url: http://svg-edit.googlecode.com/svn/branches/2.6/editor/svg-editor.html
But the flaw is it's still a fixed width solution, the line svg won't auto stretch.
Have found a unclean way to improve auto stretch though not in pure css responsive way.
but auto strech can be done by dynamically change below line
<rect stroke="#ff0000" id="svg_2" height="8" width="100%" y="27" x="40" stroke-width="5" fill="#FF0000"/>
where width="100%" or fixed value => width="function return value"; //
// during this try, i found a little bug, jquery seems unable to select svg or element inside svg? however svg element tag attribute can be written in backend languge so still valid.
//3.44
Another way without touching the inner "rect' element below "svg" tag, is to add a container to the whole thing, and using function to dynamically
assign width for the container;
like my attempt in this
fiddle: http://jsfiddle.net/hahatey/hsfxS/1468/
so at least the width can be dynamically calculated out by a function to calculate the text length of the upper text so the line will be able to strech if the calculation is accurate enough. There could be other ways to do svg auto strech with the text using pure css if other ppl find it.
Thanks.
5.02// since the author didn't say how complex the content is inside the container,
I've created a demo in pure css triggered effct --- auto strech the shape along with the text above it in below fiddle. but i said it sure has many limitations though looks similar.
http://jsfiddle.net/hahatey/a9z1kyx7/
my upper fiddle is only able to align correctly for singleline auto strech
I'm wondering if complex content (more than one line, there maybe a lot of block,inline mixed tag element inside which increases complexity for alignment) can also use css to do such decoration width auto adjustment without touching javascript or backend language.

How to change content flow?

In this jsfiddle, I'm trying to create a bookmark shape. There is only one triangle which needs to change its positioning.
<div id = "bookmark">
<div id = "rectangle"></div>
<div id = "triangle-topleft"></div>
<div id = "triangle-topright"></div>
</div>
I could easily use relative positioning and shift it, but I don't want to do it this way. I want a more malleable solution.
Instead of the shapes flowing from top to bottom. I want the last shape to flow left to right. So there are 3 shapes, the first two are in the perfect place, but the third one needs to be placed to the right of the second shape, instead of underneath it.
What CSS can I use to do this?
Add float:left; to #triangle-topleft and margin-left:100px; to #triangle-topright
#triangle-topleft {
position: static;
width: 0;
height: 0;
border-top: 100px solid black;
border-right: 100px solid transparent;
float:left;
}
#triangle-topright {
position: relative;
width: 0;
height: 0;
border-top: 100px solid black;
border-left: 100px solid transparent;
margin-left:100px;
}
jsFiddle example
First of all you do not have to declare position: static; as it is already static by default (Unless you are using responsive design where you need to reset the property value at certain point of resolution), secondly, assign position: relative; to your #bookmark and make the second triangle position: absolute;
Demo
#bookmark{
width: 200px;
position: relative;
}
#rectangle {
width: 200px;
height: 300px;
background: black;
}
#triangle-topleft {
width: 0;
height: 0;
border-top: 100px solid black;
border-right: 100px solid transparent;
}
#triangle-topright {
position: absolute;
right: 0;
width: 0;
height: 0;
border-top: 100px solid black;
border-left: 100px solid transparent;
bottom: 0;
}
Note: Make sure you do not make your first triangle position: absolute; else you need to reposition the triangles. But this is the best method you can get, as you've wrapped absolute inside a relative container.
You can also take a look at this awesome thing - Font Awesome - Bookmark, you can resize this to whatever size you want to.
The thing you are trying can be also achieved by using :before and :after pseudo along with content property. So you can get rid of the extra triangle elements.
As I said, you can create this thing with a single element.
#bookmark{
width: 200px;
position: relative;
height: 300px;
background: black;
}
#bookmark:before {
width: 0;
height: 0;
border-top: 100px solid black;
border-right: 100px solid transparent;
display: block;
content: "";
position: absolute;
bottom: -100px;
}
#bookmark:after {
position: absolute;
right: 0;
width: 0;
height: 0;
border-top: 100px solid black;
border-left: 100px solid transparent;
bottom: -100px;
display: block;
content: "";
}
Here, am using :before and :after pseudo, with display: block; and content: ""; which are essential to get this thing work, also am positioning both the elements using absolute with a value set to -100
Demo (Using single element)
Note: :before and :after pseudo can fail in older versions of IE,
but you can always use polyfills to use CSS 3 properties, also, for
more information on browser support, you can check this out.
You can just add float: left to #triangle-topleft and margin-left: 100px to #triangle-topright.
To remove unnecessary markup, you could also use :before and :after pseudo-elements instead of #triangle-*.
Add display:inline-block to both triangle shapes. They're stacking because they are defaulting to display:block.
It suffices to just add float:left to #triangle-topleft and #triangle-topright.
See the fiddle: http://jsfiddle.net/nfxYE/

Nested div vertical align problem

I am trying to vertically center one div (containing a search bar) inside another (a top banner). I was under the impression that to do so you did the following:
#banner {
height: 35px;
width: 100%;
}
#searchbar {
height: 15px;
position: relative;
top: 50%;
margin-top: -7.5px; /* half of the height */
}
This works fine until you add the margin-top at which point it is applied to the #banner as well.
Is there an alternative way to do this, or am I just doing it wrong?
Here's a jsFiddle of my actual code.
I use line-height with the value being the same as height of parent div.
As seen here: http://jsfiddle.net/vkJ78/24/
CSS:
#banner {
background-color: #770E17;
height: 35px;
width: 100%;
border-bottom: 1px solid #333;
}
#src {
width: 300px;
height: 15px;
border: 1px solid #333;
padding: 3px;
}
#srcdiv {
width: 308px;
margin: 0px auto;
position: relative;
line-height: 35px;
}
EDIT: Per recommendation from NGLN, this will also fix horizontal centering, #srcdiv and #src having equal widths.
You have to add overflow: hidden to #banner. To clear the float, I guess.
Then, modify the negative margin to margin-top: -11px in #srcdiv (you have to sum the div height, the border, and the padding for the total height)
http://jsfiddle.net/vkJ78/1/
Give margin:0px and padding:0px and remove margin-top
body {
margin:0px;
padding:0px;
}

Resources