How to center the triangle on a popover horizontally - popup

I am using TailwindCSS on my React project and I'm currently creating a custom popover or a tooltip if you will. Everything seems good except I can't seem to center the small triangle outside of the container. It's looking a little bit towards the right even though I set left: 50%.
<span
id='popover-last-seen'
className={classNames(
'absolute opacity-0 inline-block top-full left-1/2 -translate-x-1/2 -translate-y-20 px-3 py-2',
'bg-gray-700 text-xs text-center whitespace-nowrap rounded',
'transition duration-150 ease-in-out',
'after:content-[""] after:absolute after:w-0 after:h-0 after:border-4 after:border-gray-700 after:top-11 after:left-1/2 after:rotate-45'
)}>
<span className='block text-white'>
{standardTime(
timestampToDate(chatee.lastSeen)
)}
</span>
<span className='block text-gray-300 font-thin'>
{standardDateTime(
timestampToDate(chatee.lastSeen),
false
)}
</span>
</span>
I believe the problem here is the after:left-1/2. I tried to do after:right-1/2 and it went slightly towards the left. I'm not sure how to fix this.

According to MDN
When position is set to absolute or fixed, the left property specifies the distance between the element's outer margin of left edge and the inner border of left edge of its containing block. (The containing block is the ancestor to which the element is relatively positioned.)
Which means left: 50% will not center element but his left border will be exactly at the parent's center. You can see it here - as blue element has some width it quite obvious it is not centered
In order to center it your need to move element itself backward on a half of its own width
CSS property for this is transform: translateX(-50%) (where 50% - half of elements width, minus sign stands for moving backward). Tailwind's utility for this is translate-x-1/2
So your triangle should include after:left-1/2 after:-translate-x-1/2 or after:right-1/2 after:translate-x-1/2

Related

Transparent div "above" map blocking dragging

I have a full screen map with a sibling div that appears "above" the map. The div is a full width 3 column flex, the left and right columns contain information panels (green in the diagram), the centre one is empty (pink in the diagram):
As far as the user is concerned, the pink column doesn't exist.
The problem I'm facing is that the center column is blocking drag events on the map, moving the mouse over it changes the pointer from a drag handle to a pointer.
It seems the standard solution for this is to add
pointer-events: none;
to the blocking div. I've tried this and it seems to make no difference, so I'm wondering if there's some Leaflet specific knowledge I'm lacking in regard to this.
Anyone got any ideas? Any suggestions welcome! :)
May be you can giving the center column a class.
for example:
class "center-column"
and put some css rule, like this:
.center-column {
position: relative;
z-index: -10;
}
Turns out it was due to a mistake I made. Since my map was full screen, I've given it's container the following styles:
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
z-index: -5000;
It looks like reducing the z-index of the map to be underneath the panels was the wrong way to do it. Removing the z-index: -5000, and increasing the z-index of the panels resulted in the same display, but without the problem!

Dynamically set div with leaflet side-by-side plugin

I want to set the left margin of a div by the position of the slider from the side-by-side plug in. It looks to be possible as the dividermove event built into the plug-in, but I haven't been able to figure out a method to feed that into the CSS for my div.
In the jsfiddle below, I basically want to dynamically set the left margin #year05 and #year15 using dividermove. I tried setting the #year05 class to inherit left from leaflet-sbs-divider but couldn't get it to work and I imagine is not the proper way to do it.
https://jsfiddle.net/x8r0pvg1/45/
If I understand correctly, you just want to position some text that follows the slider of Leaflet Side-by-Side plugin.
In that case, instead of trying to re-position your text / div on "dividermove" event, a very simple solution would be to append your div into the slider / divider itself, so that when the plugin adjusts the position of the latter, your div follows along automatically:
var yearsEl = document.getElementById('years'); // your div
document.querySelector('.leaflet-sbs-divider').appendChild(yearsEl);
Then you can center your div on the divider with your method of choice, e.g. using CSS:
#years {
width: 200px;
transform: translateX(-50%);
text-align: center;
}
Updated JSFiddle: https://jsfiddle.net/x8r0pvg1/47/

Contents of Block Layout Change Position on Zoom

I need to fit a Label and a Hbox within block layout.
<l:BlockLayout id="BlockLayout">
<l:BlockLayoutRow>
<l:BlockLayoutCell width="100%">
<Label
class="sapUiTinyMargin"
text="Hello All"
>
<Hbox>
</Hbox>
</l:BlockLayoutCell>
</l:BlockLayoutRow>
</l:BlockLayout>
Every time I press Ctrl++ / - to zoom in or out, the block layout contents change their position. E.g.: Label shifts right on zoom out and in on zoom in.
What should I do to stop this?
The thing is: BlockLayout is a responsive UI5 element. It is like a flexbox, and it will always try to adjust its elements to "optimize" (so it thinks) the space it has.
I am not fully aware of what you really want to do, but my advice will be to not use BlockLayout and try to place manually (css) your elements (since it looks you don't like the responsiveness of the elements...
Some properties like: justifyContent="SpaceBetween" justifyContent="SpaceArround" alignItems="Center".
Might be useful to you, I'm not sure.

Leaflet.js shrink getBounds()

Leafletjs has a function pad(x) for increasing the latLng bounds. How do I shrink it? I've tried putting a negative number in there with little success.
I'm basically trying to see if a marker is within the current view, and if not center on that marker. But some markers can be plotted right on the edge of view and still be classed as in view. I'm trying to add inner padding on the current viewport bounds to avoid this.
if(!map.getBounds().pad(-1.5).contains(marker.getLatLng()))
You can use the paddingTopLeft, paddingBottomRight or padding options of L.Map's fitBounds method:
Sets the amount of padding in the top left corner of a map container that shouldn't be accounted for when setting the view to fit bounds. Useful if you have some control overlays on the map like a sidebar and you don't want them to obscure objects you're zooming to.
http://leafletjs.com/reference.html#map-paddingtopleft
map.fitBounds(layer, {'padding': [n, n]})
The negative value range for pad() is 0 to -0.5.
https://github.com/Leaflet/Leaflet/issues/5741
edit: link basically states that pad takes in a ratio of 1 not a typical percentage value. So to decrease the bounds by 50% (which would visually make it 0, because the left bounds would go in 50% to the middle, and the right bounds would also go in 50% to the middle, etc) the parameter value would be pad(-0.5) NOT pad(-50)
to increase add a positive ratio.

square Facebook pictures

Using Graph API I can get small, large, medium pictures. Or I can get small square picture.
But how can I get large square picture? Is there any service I can use?
Simple, I just found this out.
Example,
https://graph.facebook.com/friends_Id/picture?width=200&height=200
tada~
Oddly enough, Facebook itself doesn't use a bigger square image even though they show a bigger squared profile picture on the new timeline pictures. If you take a closer look they take a larger rectangular image and reposition it inside an HTML element as Michael proposed above.
I would expect that at some point the positioning data they use for this will be released via the API but I am not aware of that data being available yet. I've had times where this would have been helpful also and have thus far either just centered the image or used the top portion. Not ideal though since FB already allows for and tracks custom positioning of the most important "square" of the image via their "icon" creator.
There is no way to do this officially, here's a silly hack. The following code will make sure the image is no wider/taller than 120 pixels. If it is, then the image will overflow outside the element:
<div style="width: 120px; height: 120px; overflow: hidden; display: inline-block;">
<img src="{$image}" align="absmiddle" width=120 style="min-width: 120px; min-height: 120px;" />
</div>
You can specify the picture size you want with the type argument, which should be one of square (50x50), small (50 pixels wide, variable height), and large (about 200 pixels wide, variable height).
From the Graph API Reference. Those are the only three sizes available. You can use a bigger version of the 50x50 image but it'll obviously look dithered.
Nowadays Graph actually could return you square image of any size. They cache most common sizes (like 100x100, 128x128) and return the closest size by the following request (hover to see)
As the other answers already stated, in facebook the square pictures are only in 50x50 resolution.
A simple CSS hack does the trick though:
Query the large image, wrap the img-tag with a div and apply this CSS to the div:
img#facebook_img {
width: YOUR_WIDTH;
}
div#wrapper {
height: YOUR_HEIGHT;
overflow: hidden;
}
If YOUR_WIDTH and YOUR_HEIGHT are the same you get your square image and the ratio is preserved.
None of the answers worked perfectly for me, having come across profile pictures of various dimensions (some with a greater height than expected, some with a smaller height) which ended up either stretched or non-centered.
In the end I used a div element instead of an img and set the image through a background-image style attribute rather than through its src attribute.
CSS file:
.profile-pic {
background-repeat: no-repeat;
background-position: center;
background-size: cover;
height: 120px;
width: 120px;
border: solid 1px #ddd;
}
HTML:
<div style="background-image:url(https://graph.facebook.com/123/picture?width=120&height=120);" class="profile-pic"></div>
Replace 120px in the above (occurs twice in the CSS and twice in the HTML fragment) with your desired dimensions.