Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java	(revision 8774)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java	(revision 8775)
@@ -16,4 +16,5 @@
 import java.util.Collections;
 import java.util.List;
+import java.util.TreeSet;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -31,4 +32,5 @@
 import org.openstreetmap.josm.gui.util.RotationAngle;
 import org.openstreetmap.josm.io.XmlWriter;
+import org.openstreetmap.josm.tools.AlphanumComparator;
 import org.openstreetmap.josm.tools.ColorHelper;
 import org.openstreetmap.josm.tools.Geometry;
@@ -375,4 +377,15 @@
 
         /**
+         * Joins a list of {@code values} into a single string with fields separated by {@code separator}.
+         * @param separator the separator
+         * @param values collection of objects
+         * @return assembled string
+         * @see Utils#join
+         */
+        public static String join_list(final String separator, final List<String> values) {
+            return Utils.join(separator, values);
+        }
+
+        /**
          * Returns the value of the property {@code key}, e.g., {@code prop("width")}.
          * @param env the environment
@@ -444,4 +457,30 @@
             }
             return env.parent.get(key);
+        }
+
+        /**
+         * Gets a list of all non-null values of the key {@code key} from the object's parent(s).
+         *
+         * The values are sorted according to {@link AlphanumComparator}.
+         * @param env the environment
+         * @param key the OSM key
+         * @return a list of non-null values of the key {@code key} from the object's parent(s)
+         */
+        public static List<String> parent_tags(final Environment env, String key) {
+            if (env.parent == null) {
+                if (env.osm != null) {
+                    final Collection<String> tags = new TreeSet<>(AlphanumComparator.getInstance());
+                    // we don't have a matched parent, so just search all referrers
+                    for (OsmPrimitive parent : env.osm.getReferrers()) {
+                        String value = parent.get(key);
+                        if (value != null) {
+                            tags.add(value);
+                        }
+                    }
+                    return new ArrayList<>(tags);
+                }
+                return Collections.emptyList();
+            }
+            return Collections.singletonList(env.parent.get(key));
         }
 
Index: trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.groovy
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.groovy	(revision 8774)
+++ trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.groovy	(revision 8775)
@@ -322,4 +322,31 @@
 
     @Test
+    public void testParentTags() throws Exception {
+        def ds = new DataSet()
+        def n = new org.openstreetmap.josm.data.osm.Node(new LatLon(1, 2))
+        n.put("foo", "bar")
+        def w1 = new Way()
+        w1.put("ref", "x10")
+        def w2 = new Way()
+        w2.put("ref", "x2")
+        def w3 = new Way()
+        ds.addPrimitive(n)
+        ds.addPrimitive(w1)
+        ds.addPrimitive(w2)
+        ds.addPrimitive(w3)
+        w1.addNode(n)
+        w2.addNode(n)
+        w3.addNode(n)
+
+        MapCSSStyleSource source = new MapCSSStyleSource("node[foo=bar] {refs: join_list(\";\", parent_tags(\"ref\"));}")
+        source.loadStyleSource()
+        assert source.rules.size() == 1
+        def e = new Environment(n, new MultiCascade(), Environment.DEFAULT_LAYER, null)
+        assert source.rules.get(0).selector.matches(e)
+        source.rules.get(0).declaration.execute(e)
+        assert e.getCascade(Environment.DEFAULT_LAYER).get("refs", null, String.class) == "x2;x10"
+    }
+
+    @Test
     public void testSiblingSelectorInterpolation() throws Exception {
         def s1 = (Selector.ChildOrParentSelector) getParser(
