3

A map that I am building with OpenLayers 3 has some buttons, which may or may not be available depending on some other things. So I want to keep the unavailable buttons hidden, and others will use their space. The available options can change, so sometimes a button may become (in)visible.

There are some tutorials for creating custom controls with OpenLayers 3. The problem is that all samples I have seen use absolute positioning for the controls. One needs to know how many controls will be visible, and hard-code the coordinates in CSS. Or change the coordinates using Javascript. I.e., from the above link:

.rotate-north {
  top: 65px;
  left: .5em;
}

I have tried just setting the element with position:relative, but then they appear below the map, as the controls are added to the page after the map. So, one could use relative positioning with negative coordinates, but then if the map changes size you have to rewrite the coordinates in Javascript.

.ol-control.left-top {
  position: relative;
  top: -400px; /*map height*/
}

Is there a way to elegantly implement relative-positioned custom controls with OpenLayers 3, ideally with only CSS?

I guess I am trying to get a similar functionality as in the Google Maps API:

map.controls[google.maps.ControlPosition.LEFT_TOP].push(controlDiv);
Jose Gómez
  • 3,110
  • 2
  • 32
  • 54
  • 1
    It's obscure about the conditions, but maybe you could use CSS `calc`. – Jonatas Walker Jun 20 '16 at 10:56
  • Thanks; that's a reasonable idea to check. Note, though, that calc can use relative values only on the parent element, not on a different element. I will check later if this would be applicable to OpenLayers 3 controls. In any case, one can always use viewport-related measures (vw/vh). The other issue with calc and vh is that they are not supported by Android before version 4.4, which currently is a deal breaker for me. – Jose Gómez Jun 20 '16 at 11:40

1 Answers1

2

Though it is not a good solution for my use case, since it is not supported by Android 4.3 and earlier, one could use CSS calc as suggested by @Jonatas:

html:

<div class="parent">
  <div class="map"></div>
  <div class="control"><button>CONTROL</button></div>
</div>

css:

.map {
  width: 100%;
  height: calc(100vh - 2em);
  background-color: green;
}

.control {
  position: relative;
  left: .5em;
  top: calc(-100vh + 2em + .5em);
}

This would probably have to use viewport units (also not supported by Android 4.3 and earlier), as calc can only calculate values based on the parent element.

jsfiddle: https://jsfiddle.net/adlerhn/zjt53nmf/

Jose Gómez
  • 3,110
  • 2
  • 32
  • 54