how to style steep oval shape button - nativescript

I'm trying to design a label or button with some text inside it. I know how to give border radius and make it oval but I need an eye shape wide button or label like exactly below.
i follwed this link https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_shapes_oval with no results like rectangle shapes with round border button below
then,I tried the below code but only the corners are getting rounded.
.boc1 {
border-width: 1;
border-radius: 100;
padding: -2px;
margin: 10% 0 0 0;
padding: 10% 0 10% 0;
height:100%;
width:85%;
}
I hope you are clear about the problem..!

Change border-radius as border-radius:50px;

Use clip-path
XML
<GridLayout>
<StackLayout class="oval"></StackLayout>
<Label class="h2" text="Some text" color="white" verticalAlignment="center"
horizontalAlignment="center"></Label>
</GridLayout>
CSS
.oval {
width: 85%;
background-color: red;
clip-path: ellipse(50% 15% at 50% 50%);
}

Related

Can't make progressbar that works on iOS and Android

I'm trying to make a progress bar that moves across the screen with some text below it.
Here's my template:
<StackLayout v-else id="loadingContainer">
<StackLayout class="progress-bar">
<StackLayout class="progress"></StackLayout>
</StackLayout>
<StackLayout horizontalAlignment="center">
<Label id="progressText" :text="loadingText" />
</StackLayout>
</StackLayout>
and here is the CSS:
.progress-bar {
height: 20px;
width: 100%;
position: relative;
background-color: #f8f8f8;
}
.progress {
position: relative;
height: 100%;
border-radius: 0px 2px 2px 0px;
animation-name: fill;
animation-duration: 2s;
animation-timing-function: ease-in;
animation-fill-mode: forwards;
animation-direction: normal;
width: 0%;
}
#keyframes fill {
0% {
width: 0%;
background-color: #6a2d91;
}
100% {
width: 100%;
background-color: #6a2d91;
}
}
Both display the text as I expect but the progress bar behaves very differently on iOS and Android. Android just shows the progress bar as full the whole time and never animates it. iOS shows the appropriate gray background until the `animation-duration is up and then the bar just shows full, it doesn't animate it. I have keyframes working on this page doing other things but I can't get this figured out.
By default child components in a vertical StackLayout will stretch out to fill the width. You should set horizontalAlignment to left on the progress bar layout, though it gets what you wanted on Android, on iOS horizontalAlignment / verticalAlignment is not respected during animation.
So I would suggest using JavaScript APIs to animate Width / Height, presented by Alex.
You may also use the default Progress and increment the value at internals to achieve similar look.

Nativescript: how to vertically align text inside Label on Android

The text inside label is vertically aligned by default on iOS, however on Android it's not. How to center it vertically on Android (I'm interested in centering text inside Label, not wrapping label inside any other layout to get the same effect)?
To see what I mean run the next code on iOS and Android.
xml:
<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="onLoaded">
<Label text="test" />
</Page>
css:
Label {
width: 60;
height: 60;
text-align: center;
background-color: aquamarine;
border-radius: 30;
}
Set the padding accordingly to the (width - font-size) / 2 (rough approximation may differ for smaller boxes where Capital or small letters has different center point)
e.g.
Label {
width: 60;
height: 60;
border-radius: 30;
text-align:center;
background-color: aquamarine;
padding: 15;
font-size: 20;
}
or example with bigger sizes:
Label {
width: 200;
height: 200;
border-radius: 100;
text-align:center;
background-color: aquamarine;
padding: 80;
font-size: 20;
}
p.s If you wrap your label in StackLayout you won't need height
e.g.
<StackLayout>
<Label text="test" class="title"/>
</StackLayout>
Label {
width: 200;
border-radius: 100;
text-align:center;
background-color: aquamarine;
padding: 80;
font-size: 20;
}
Using padding will screw things up if you're using the same css on iOS. setGravity(17) will also horizontally align the text. If you want to just vertically align the text, and keep the normal behavior for the horizontal alignment, use
this.nativeView.android.setGravity(this.nativeView.android.getGravity() & 0xffffffdf);
this will remove the vertical-align=top flag from the label
I've created this directive that should change the default for labels:
import {AfterViewChecked, Directive, ElementRef, Input} from '#angular/core';
import { Label } from 'ui/label';
#Directive({
selector: 'Label',
})
export class UpdateLabelDirective implements AfterViewChecked {
private get nativeView(): Label {
return this.el.nativeElement;
}
constructor(private readonly el: ElementRef) {}
ngAfterViewChecked(): void {
if (this.nativeView.android && (this.nativeView.android.getGravity() & 0x00000020)) {
this.nativeView.android.setGravity(this.nativeView.android.getGravity() & 0xffffffdf);
}
}
}
Don't think of it as vertically centring your labels text. Instead put your Label in a container and centre it relative to the container.
<StackLayout verticalAlignment="center">
<Label text="test" />
</StackLayout>
This will centre align your Label (vertically) within the StackLayout. You'll also notice the StackLayout will now only take up the vertical space required by its children. If you want it to use up more vertical space you just need to give it a height.
The following creates a three row GridLayout with each row occupying 33.3...% of the screen with their labels centred within them.
<Page xmlns="http://www.nativescript.org/tns.xsd">
<GridLayout rows="*, *, *">
<StackLayout row="0" class="red stack">
<Label text="red" class="label"/>
</StackLayout>
<StackLayout row="1" class="green stack">
<Label text="green" class="label"/>
</StackLayout>
<StackLayout row="2" class="blue stack">
<Label text="blue" class="label"/>
</StackLayout>
</GridLayout>
</Page>
.stack {
height: 100%;
vertical-align: center;
}
.label { text-align: center; }
.red { backgroundColor: red; }
.green { backgroundColor: green; }
.blue { backgroundColor: blue; }
Here's a Playground of the above if you'd like to see it working on your device. Try commenting out the height property in home-page.css (line 13).
You can enable it natively, in the code:
myLabel.android.setGravity(17)
17 is value for Gravity.CENTER constant (https://developer.android.com/reference/android/view/Gravity.html#CENTER)
Most simple solution per css:
line-height: 100%;
Another option is to reconsider why you're trying to vertically align the contents of the label.
I came to this page trying to do the same thing but decided to remove the height css on the label and just let the label be the size of the text and vertically center the label within it's parent
After spent some time digging, I found this solution which will make vertical_center your default setting.
in your AndroidManifest.xml, add the following style
<style name="MyTextViewStyle" parent="android:Widget.TextView">
<item name="android:gravity">center_vertical</item>
</style>
Then apply the style in your theme
<style name="AppTheme" parent="AppThemeBase">
<item name="actionMenuTextColor">#color/ns_white</item>
<item name="android:actionMenuTextColor">#color/ns_white</item>
<item name="android:textViewStyle">#style/MyTextViewStyle</item>
</style>

Rounded CSS border looks pixelated

I need some help to fix my rounded border. It looks so ugly. I want it more smooth, but I can't seem to fix it no matter what. I don't know what I am doing wrong.
Here is a picture of it:
Here is my HTML:
<div class="sidebar">
<!-- User avatar/message/notification/settings buttons -->
<div class="userpanel">
<div class="userpanel-image">
<img src="image.jpg">
</div>
<div class="userpanel-buttons">
<ul>
<li><span class="glyphicon glyphicon-envelope"></span></li>
<li><span class="glyphicon glyphicon-bell"></span></li>
<li><span class="glyphicon glyphicon-cog"></span></li>
</ul>
</div>
</div>
</div>
And here is my CSS:
.sidebar > .userpanel > .userpanel-image img {
border: 1px solid white;
border-radius: 25px;
margin: 3px;
margin-right: 25px;
}
This ultimately depends upon the pixel density of the monitor you are using.
Pixels per inch (PPI) or pixels per centimeter (PPCM) is a measurement of the pixel density (resolution) of an electronic image device, such as a computer monitor or television display, or image digitizing device such as a camera or image scanner. Horizontal and vertical density are usually the same, as most devices have square pixels, but differ on devices that have non-square pixels.
For example, a 15 inch (38 cm) display whose dimensions work out to 12 inches (30.48 cm) wide by 9 inches (22.86 cm) high, capable of a maximum 1024×768 (or XGA) pixel resolution, can display around 85 PPI in both the horizontal and vertical directions. This figure is determined by dividing the width (or height) of the display area in pixels by the width (or height) of the display area in inches. It is possible for a display to have different horizontal and vertical PPI measurements (e.g., a typical 4:3 ratio CRT monitor showing a 1280×1024 mode computer display at maximum size, which is a 5:4 ratio, not quite the same as 4:3). The apparent PPI of a monitor depends upon the screen resolution (that is, the number of pixels) and the size of the screen in use; a monitor in 800×600 mode has a lower PPI than does the same monitor in a 1024×768 or 1280×960 mode.
Monitors with a higher pixel density will tend to smooth curves much better visually.
There's really nothing you can generally do to improve the pixel density display via HTML/CSS or really, anything. You merely have to learn to live with the quality of your monitor or upgrade it.
In some cases, applying a slight 1px box-shadow the same color as your circle can assist in the monitor anti-aliasing. However, that's not 100% successful either.
You're definetly not doing anything wrong.
Maybe that just because the border is too thin. Try to change border: 1px solid white; to 2px, 3px, or whatever you like. Give it try.
For me this looks best:
.userpanel-image {
width: 100px;
height: 100px;
border-radius: 100%;
box-shadow: 0 0 1px 1px white;
overflow: hidden;
}
.userpanel-image img {
width: 98px;
height: 98px;
}
Unfortunately i had the same problem several times. I think this might be a render problem which cant be solved 100%. Maybe you can use the workaround i used for my "border-problem" to make it look sharper (I did not test it on every single browser so u might have to check that out)
body {background:black;}
div {
width:100px;
height:100px;
display:block;
background:#fff;
border-radius:100%;
padding:2px;
}
img {
display:block;
border-radius:100%;
display:block;
width:100px;
height:100px;
}
<div>
<img src="https://unsplash.it/100" alt="">
</div>
Usually when I'm faced with this problem, I just reduce the contrast of the colors to help ease the pixelated anti-aliasing (as I mentioned in my comment). This is not always an option however. The real problem you are facing is that the browser will apply a certain amount of anti-aliasing to prevent complete jaggedness and you don't really have control over the intensity of that anti-aliasing that's applied. Here's an alternative that you can use to help take control of the appearance. You can use box-shadow to supplement or replace your existing border:
body {
background: #223;
padding-bottom: 25px;
text-align: center;
color: white;
}
div {
margin-top: 25px;
}
img {
display:inline-block;
border-radius: 50%;
border: 1px solid white;
vertical-align: middle;
}
div + div img {
box-shadow: 0 0 1px 0 white;
}
div + div + div img {
box-shadow: 0 0 0 1px white;
border: none;
}
<div>border only: <img src="//placehold.it/50/933/FFF"></div>
<div>border + box-shadow: <img src="//placehold.it/50/933/FFF">
<div>box-shadow only: <img src="//placehold.it/50/933/FFF">

Creating an irregular border with CSS overlapping colours

How would you go about creating an irregular border with variable colours like the one in the screenshot?
I considered creating a border image in a graphics editor and then using border-image property as described in the docs.
However, this technique would not allow me to achieve the effect of multiple background colours (grey and white in the screenshot) entering the border "waves".
Another solution would be to just produce the whole background white and grey in say Photoshop, and the just use it on the website. I really wanted to avoid this for performance reasons, and would prefer to just produce a grey, checked pattern fragment and repeat it.
Moreover, as you can see in the screenshot, the dark fragment is an image from a carousel - the images will all come in different colours so applying a border-image to the carousel container is not a solution either.
I would appreciate some advice. Thanks.
Using SVG:
You can do this using SVG. I would say it is pretty complex because the approach uses patterns for the repeating circles, a mask with the pattern as its fill to produce the transparent cuts. This mask is then applied to the image to produce the full effect. This in my opinion is the closest to what you want and also has good browser support. It works fine in IE10+, Edge, Firefox, Chrome, Opera and Safari.
There are a couple of points to note though - (1) You would have to somehow get your carousel work with SVG image because otherwise mask will have no effect (2) the radius of circles change as the width of the container change and so you'd either have to use a fixed size container (or) assign width of the container to the viewBox attribute using JS (or find some setting to prevent the radius change from happening, I don't know of any) .
.masked {
position: relative;
height: 175px;
width: 100%;
background: linear-gradient(60deg, #EEE 35%, white 35.5%), linear-gradient(300deg, #EEE 35%, white 35.5%);
background-size: 51% 100%;
background-repeat: no-repeat;
background-position: 0% 0%, 100% 0%;
padding-top: 100px;
}
.masked svg {
position: absolute;
top: 0px;
left: 0px;
height: 100px;
width: 100%;
}
path {
fill: #fff;
}
image {
mask: url("#mask");
}
<div class='masked'>
<svg viewBox='0 0 1200 100' preserveAspectRatio='none'>
<defs>
<pattern id="circles" patternUnits="userSpaceOnUse" width="10" height="100">
<path d="M0,0 L10,0 10,95 A5,5 0 0,0 0,95 L0,0" />
</pattern>
<mask id="mask">
<rect height="100%" width="100%" fill="url(#circles)" />
</mask>
</defs>
<image xlink:href='http://lorempixel.com/1200/100/nature/1' x="0" y="0" height="100%" width="100%" />
</svg>
Lorem Ipsum Dolor Sit Amet...
</div>
Using CSS:
This can be done using CSS masks but unfortunately the browser support for this feature is terrible. It is currently supported only in WebKit powered browsers. If other browsers need not be supported then this is a wonderful option. All that we need to do is create a radial gradient (that repeats in X axis) for the mask like in the below snippet, give it the required size and position it accordingly.
.masked {
position: relative;
height: 175px;
width: 100%;
background: linear-gradient(60deg, #EEE 35%, white 35.5%), linear-gradient(300deg, #EEE 35%, white 35.5%);
background-size: 51% 100%;
background-repeat: no-repeat;
background-position: 0% 0%, 100% 0%;
padding-top: 80px;
}
.masked:before {
position: absolute;
content: '';
top: 0px;
height: 80px;
width: 100%;
background: url(http://lorempixel.com/1000/100/nature/1);
-webkit-mask-image: linear-gradient(to bottom, black, black), radial-gradient(circle at 50% 100%, transparent 50%, black 55%);
-webkit-mask-size: 100% calc(100% - 12px), 12px 12px;
-webkit-mask-position: 0% 0%, 0px 68px;
-webkit-mask-repeat: repeat-x;
}
<div class="masked">Lorem Ipsum Dolor Sit Amet</div>

html/css Tranparency in image link not clickable

I have a .png image of a star. The area around the star is transparent. Here is an example of my code
<a href='nextPage.html'><img src='starImage.png' border='0'></a>
How do I get only the star part of the image to be clickable?
-or-
How do I get the transparent parts of the image to not be clickable?
You need to use an area shape map
<a href='nextPage.html'><img src='starImage.png' border='0'usemap="#Map" /></a>
<map name="Map" id="Map">
<area shape="poly" coords="54,52,55,52,94,77,118,42,179,63,174,119,105,128,50,122,31,84,54,53" href="#" />
</map>
this is only an example.
You must use the area shape map tool on dreamweaver and draw the polygon of area u need.
you need to use an imagemap check out this site to help you do it...
http://www.image-maps.com/
For more information about what an image map is see this wikipedia article.
Image map
In fact we can make the parent element position:relative, and use z-index to place the link area over the image.
Something like:
div.imageArea {
position: relative;
width: 150px;
height: 150px;
z-index: 2;
}
div.imageArea a {
position: relative;
display: inline-block;
width: 100%;
height: 100%;
background: transparent no-repeat url('images/starImage.png') 0 0;
z-index: 3;
}

Resources