Index: trunk/src/org/openstreetmap/josm/gui/mappaint/BoxTextElemStyle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/BoxTextElemStyle.java	(revision 8086)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/BoxTextElemStyle.java	(revision 8087)
@@ -119,5 +119,5 @@
 
         HorizontalTextAlignment hAlign = HorizontalTextAlignment.RIGHT;
-        Keyword hAlignKW = c.get("text-anchor-horizontal", Keyword.RIGHT, Keyword.class);
+        Keyword hAlignKW = c.get(TEXT_ANCHOR_HORIZONTAL, Keyword.RIGHT, Keyword.class);
         if ("left".equals(hAlignKW.val)) {
             hAlign = HorizontalTextAlignment.LEFT;
@@ -128,5 +128,5 @@
         }
         VerticalTextAlignment vAlign = VerticalTextAlignment.BOTTOM;
-        String vAlignStr = c.get("text-anchor-vertical", Keyword.BOTTOM, Keyword.class).val;
+        String vAlignStr = c.get(TEXT_ANCHOR_VERTICAL, Keyword.BOTTOM, Keyword.class).val;
         if ("above".equals(vAlignStr)) {
             vAlign = VerticalTextAlignment.ABOVE;
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyle.java	(revision 8086)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyle.java	(revision 8087)
@@ -14,6 +14,12 @@
 public abstract class ElemStyle implements StyleKeys {
 
-    protected static final String[] ICON_KEYS = {"icon-image", "icon-width", "icon-height", "icon-opacity", "icon-offset-x", "icon-offset-y"};
-    protected static final String[] REPEAT_IMAGE_KEYS = {"repeat-image", "repeat-image-width", "repeat-image-height", "repeat-image-opacity", null, null};
+    protected static final int ICON_IMAGE_IDX = 0;
+    protected static final int ICON_WIDTH_IDX = 1;
+    protected static final int ICON_HEIGHT_IDX = 2;
+    protected static final int ICON_OPACITY_IDX = 3;
+    protected static final int ICON_OFFSET_X_IDX = 4;
+    protected static final int ICON_OFFSET_Y_IDX = 5;
+    public static final String[] ICON_KEYS = {ICON_IMAGE, ICON_WIDTH, ICON_HEIGHT, ICON_OPACITY, ICON_OFFSET_X, ICON_OFFSET_Y};
+    public static final String[] REPEAT_IMAGE_KEYS = {REPEAT_IMAGE, REPEAT_IMAGE_WIDTH, REPEAT_IMAGE_HEIGHT, REPEAT_IMAGE_OPACITY, null, null};
 
     public float major_z_index;
@@ -31,5 +37,5 @@
 
     protected ElemStyle(Cascade c, float default_major_z_index) {
-        major_z_index = c.get("major-z-index", default_major_z_index, Float.class);
+        major_z_index = c.get(MAJOR_Z_INDEX, default_major_z_index, Float.class);
         z_index = c.get(Z_INDEX, 0f, Float.class);
         object_z_index = c.get(OBJECT_Z_INDEX, 0f, Float.class);
@@ -177,12 +183,12 @@
 
     protected static Font getFont(Cascade c, String s) {
-        String name = c.get("font-family", getDefaultFontName(), String.class);
-        float size = c.get("font-size", getDefaultFontSize(), Float.class);
+        String name = c.get(FONT_FAMILY, getDefaultFontName(), String.class);
+        float size = c.get(FONT_SIZE, getDefaultFontSize(), Float.class);
         int weight = Font.PLAIN;
-        if ("bold".equalsIgnoreCase(c.get("font-weight", null, String.class))) {
+        if ("bold".equalsIgnoreCase(c.get(FONT_WEIGHT, null, String.class))) {
             weight = Font.BOLD;
         }
         int style = Font.PLAIN;
-        if ("italic".equalsIgnoreCase(c.get("font-style", null, String.class))) {
+        if ("italic".equalsIgnoreCase(c.get(FONT_STYLE, null, String.class))) {
             style = Font.ITALIC;
         }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java	(revision 8086)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java	(revision 8087)
@@ -40,5 +40,5 @@
     private BasicStroke dashesLine;
 
-    protected enum LineType {
+    public enum LineType {
         NORMAL("", 3f),
         CASING("casing-", 2f),
@@ -214,5 +214,5 @@
 
         Integer cap = null;
-        Keyword capKW = c.get(type.prefix + "linecap", null, Keyword.class);
+        Keyword capKW = c.get(type.prefix + LINECAP, null, Keyword.class);
         if (capKW != null) {
             if ("none".equals(capKW.val)) {
@@ -229,5 +229,5 @@
 
         Integer join = null;
-        Keyword joinKW = c.get(type.prefix + "linejoin", null, Keyword.class);
+        Keyword joinKW = c.get(type.prefix + LINEJOIN, null, Keyword.class);
         if (joinKW != null) {
             if ("round".equals(joinKW.val)) {
@@ -243,5 +243,5 @@
         }
 
-        float miterlimit = c.get(type.prefix + "miterlimit", 10f, Float.class);
+        float miterlimit = c.get(type.prefix + MITERLIMIT, 10f, Float.class);
         if (miterlimit < 1f) {
             miterlimit = 10f;
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/StyleKeys.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/StyleKeys.java	(revision 8086)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/StyleKeys.java	(revision 8087)
@@ -12,5 +12,18 @@
     String FILL_IMAGE = "fill-image";
     String FILL_OPACITY = "fill-opacity";
+    String FONT_FAMILY = "font-family";
+    String FONT_SIZE = "font-size";
+    String FONT_STYLE = "font-style";
+    String FONT_WEIGHT = "font-weight";
     String ICON_IMAGE = "icon-image";
+    String ICON_HEIGHT = "icon-height";
+    String ICON_OFFSET_X = "icon-offset-x";
+    String ICON_OFFSET_Y = "icon-offset-y";
+    String ICON_OPACITY = "icon-opacity";
+    String ICON_WIDTH = "icon-width";
+    String LINECAP = "linecap";
+    String LINEJOIN = "linejoin";
+    String MAJOR_Z_INDEX = "major-z-index";
+    String MITERLIMIT = "miterlimit";
     String MODIFIER = "modifier";
     String OBJECT_Z_INDEX = "object-z-index";
@@ -18,19 +31,26 @@
     String OPACITY = "opacity";
     String REAL_WIDTH = "real-width";
+    String REPEAT_IMAGE = "repeat-image";
+    String REPEAT_IMAGE_ALIGN = "repeat-image-align";
+    String REPEAT_IMAGE_HEIGHT = "repeat-image-height";
+    String REPEAT_IMAGE_OFFSET = "repeat-image-offset";
+    String REPEAT_IMAGE_OPACITY = "repeat-image-opacity";
+    String REPEAT_IMAGE_PHASE = "repeat-image-phase";
+    String REPEAT_IMAGE_SPACING = "repeat-image-spacing";
+    String REPEAT_IMAGE_WIDTH = "repeat-image-width";
+    String TEXT = "text";
+    String TEXT_ANCHOR_HORIZONTAL = "text-anchor-horizontal";
+    String TEXT_ANCHOR_VERTICAL = "text-anchor-vertical";
+    String TEXT_COLOR = "text-color";
+    String TEXT_HALO_COLOR = "text-halo-color";
+    String TEXT_HALO_OPACITY = "text-halo-opacity";
+    String TEXT_HALO_RADIUS = "text-halo-radius";
+    String TEXT_OFFSET = "text-offset";
+    String TEXT_OFFSET_X = "text-offset-x";
+    String TEXT_OFFSET_Y = "text-offset-y";
+    String TEXT_OPACITY = "text-opacity";
     String TEXT_POSITION = "text-position";
-    String TEXT = "text";
     String WIDTH = "width";
     String Z_INDEX = "z-index";
-    String REPEAT_IMAGE = "repeat-image";
-    String REPEAT_IMAGE_OFFSET = "repeat-image-offset";
-    String REPEAT_IMAGE_SPACING = "repeat-image-spacing";
-    String REPEAT_IMAGE_PHASE = "repeat-image-phase";
-    String REPEAT_IMAGE_ALIGN = "repeat-image-align";
 
-    int ICON_IMAGE_IDX = 0;
-    int ICON_WIDTH_IDX = 1;
-    int ICON_HEIGHT_IDX = 2;
-    int ICON_OPACITY_IDX = 3;
-    int ICON_OFFSET_X_IDX = 4;
-    int ICON_OFFSET_Y_IDX = 5;
 }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/TextElement.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/TextElement.java	(revision 8086)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/TextElement.java	(revision 8087)
@@ -127,5 +127,5 @@
         float xOffset = 0;
         float yOffset = 0;
-        float[] offset = c.get("text-offset", null, float[].class);
+        float[] offset = c.get(TEXT_OFFSET, null, float[].class);
         if (offset != null) {
             if (offset.length == 1) {
@@ -136,13 +136,13 @@
             }
         }
-        xOffset = c.get("text-offset-x", xOffset, Float.class);
-        yOffset = c.get("text-offset-y", yOffset, Float.class);
-
-        Color color = c.get("text-color", defaultTextColor, Color.class);
-        float alpha = c.get("text-opacity", 1f, Float.class);
+        xOffset = c.get(TEXT_OFFSET_X, xOffset, Float.class);
+        yOffset = c.get(TEXT_OFFSET_Y, yOffset, Float.class);
+
+        Color color = c.get(TEXT_COLOR, defaultTextColor, Color.class);
+        float alpha = c.get(TEXT_OPACITY, 1f, Float.class);
         color = new Color(color.getRed(), color.getGreen(),
                 color.getBlue(), Utils.color_float2int(alpha));
 
-        Float haloRadius = c.get("text-halo-radius", null, Float.class);
+        Float haloRadius = c.get(TEXT_HALO_RADIUS, null, Float.class);
         if (haloRadius != null && haloRadius <= 0) {
             haloRadius = null;
@@ -150,6 +150,6 @@
         Color haloColor = null;
         if (haloRadius != null) {
-            haloColor = c.get("text-halo-color", Utils.complement(color), Color.class);
-            float haloAlpha = c.get("text-halo-opacity", 1f, Float.class);
+            haloColor = c.get(TEXT_HALO_COLOR, Utils.complement(color), Color.class);
+            float haloAlpha = c.get(TEXT_HALO_OPACITY, 1f, Float.class);
             haloColor = new Color(haloColor.getRed(), haloColor.getGreen(),
                     haloColor.getBlue(), Utils.color_float2int(haloAlpha));
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj	(revision 8086)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj	(revision 8087)
@@ -38,7 +38,7 @@
  * (a) the preprocessor and (b) the main mapcss parser.
  *
- * The preprocessor handles @media syntax. Basically this allows
- * to write one style for different versions of JOSM (or different editors).
- * When the @media condition is not fulfilled, it should simply skip over
+ * The preprocessor handles @supports and @media syntax (@media is deprecated).
+ * Basically this allows to write one style for different versions of JOSM (or different editors).
+ * When the @supports condition is not fulfilled, it should simply skip over
  * the whole section and not attempt to parse the possibly unknown
  * grammar. It preserves whitespace and comments, in order to keep the
@@ -100,5 +100,7 @@
 {
     < PP_AND: "and" >
+|   < PP_OR: "or" >
 |   < PP_NOT: "not" >
+|   < PP_SUPPORTS: "@supports" >
 |   < PP_MEDIA: "@media" >
 |   < PP_NEWLINECHAR: "\n" | "\r" | "\f" >
@@ -244,7 +246,9 @@
 {
     (
-        (t=<PP_AND> | t=<PP_NOT> | t=<UINT> | t=<STRING> | t=<REGEX> | t=<LPAR> | t=<RPAR> | t=<COMMA> | t=<COLON> | t=<IDENT> | t=<PP_SOMETHING_ELSE>) { if (write) sb.append(t.image); }
+        (t=<PP_AND> | t=<PP_OR> | t=<PP_NOT> | t=<UINT> | t=<STRING> | t=<REGEX> | t=<LPAR> | t=<RPAR> | t=<COMMA> | t=<COLON> | t=<IDENT> | t=<PP_SOMETHING_ELSE>) { if (write) sb.append(t.image); }
         |
             pp_w1()
+        |
+            pp_supports(!write)
         |
             pp_media(!write)
@@ -254,4 +258,88 @@
 }
 
+/**
+ * Parses an @supports rule.
+ *
+ * @param ignore if the content of this rule should be ignored
+ * (because we are already inside a @supports block that didn't pass)
+ */
+void pp_supports(boolean ignore):
+{
+    boolean pass;
+}
+{
+    <PP_SUPPORTS> pp_w()
+    pass=pp_supports_condition()
+    <LBRACE>
+    pp_black_box(pass && !ignore)
+    <RBRACE>
+}
+
+/**
+ * Parses the condition of the @supports rule.
+ *
+ * Unlike other parsing rules, grabs trailing whitespace.
+ * @return true, if the condition is fulfilled
+ */
+boolean pp_supports_condition():
+{
+    boolean pass;
+    boolean q;
+}
+{
+    (
+        <PP_NOT> pp_w() q=pp_supports_condition_in_parens() { pass = !q; } pp_w()
+    |
+        LOOKAHEAD(pp_supports_condition_in_parens() pp_w() <PP_AND>)
+        pass=pp_supports_condition_in_parens() pp_w()
+        ( <PP_AND> pp_w() q=pp_supports_condition_in_parens() { pass = pass && q; } pp_w() )+
+    |
+        LOOKAHEAD(pp_supports_condition_in_parens() pp_w() <PP_OR>)
+        pass=pp_supports_condition_in_parens() pp_w()
+        ( <PP_OR> pp_w() q=pp_supports_condition_in_parens() { pass = pass || q; } pp_w() )+
+    |
+        pass=pp_supports_condition_in_parens() pp_w()
+    )
+    { return pass; }
+}
+
+/**
+ * Parses something in parenthesis inside the condition of the @supports rule.
+ *
+ * @return true, if the condition is fulfilled
+ */
+boolean pp_supports_condition_in_parens():
+{
+    boolean pass;
+}
+{
+    (
+        LOOKAHEAD(pp_supports_declaration_condition())
+        pass=pp_supports_declaration_condition()
+    |
+        <LPAR> pp_w() pass=pp_supports_condition() <RPAR>
+    )
+    { return pass; }
+}
+
+/**
+ * Parse an @supports declaration condition, e.&nbsp;g. a single (key:value) or (key) statement.
+ *
+ * The parsing rule {@link #literal()} from the main mapcss parser is reused here.
+ *
+ * @return true if the condition is fulfilled
+ */
+boolean pp_supports_declaration_condition():
+{
+    Token t;
+    String feature;
+    Object val = null;
+}
+{
+    <LPAR> pp_w() t=<IDENT> { feature = t.image; } pp_w() ( <COLON> pp_w() val=literal() )? <RPAR>
+    { return this.sheet.evalSupportsDeclCondition(feature, val); }
+}
+
+// deprecated
 void pp_media(boolean ignore):
 {
@@ -270,4 +358,5 @@
 }
 
+// deprecated
 boolean pp_media_query():
 {
@@ -302,4 +391,5 @@
  * @return true if the condition is fulfilled
  */
+// deprecated
 boolean pp_media_expression():
 {
@@ -310,5 +400,5 @@
 {
     <LPAR> pp_w() t=<IDENT> { feature = t.image; } pp_w() ( <COLON> pp_w() val=literal() )? <RPAR>
-    { return this.sheet.evalMediaExpression(feature, val); }
+    { return this.sheet.evalSupportsDeclCondition(feature, val); }
 }
 
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java	(revision 8086)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java	(revision 8087)
@@ -9,4 +9,5 @@
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.reflect.Field;
 import java.nio.charset.StandardCharsets;
 import java.text.MessageFormat;
@@ -33,6 +34,8 @@
 import org.openstreetmap.josm.gui.mappaint.Cascade;
 import org.openstreetmap.josm.gui.mappaint.Environment;
+import org.openstreetmap.josm.gui.mappaint.LineElemStyle;
 import org.openstreetmap.josm.gui.mappaint.MultiCascade;
 import org.openstreetmap.josm.gui.mappaint.Range;
+import org.openstreetmap.josm.gui.mappaint.StyleKeys;
 import org.openstreetmap.josm.gui.mappaint.StyleSetting;
 import org.openstreetmap.josm.gui.mappaint.StyleSetting.BooleanStyleSetting;
@@ -81,4 +84,36 @@
      */
     public final static ReadWriteLock STYLE_SOURCE_LOCK = new ReentrantReadWriteLock();
+
+    /**
+     * Set of all supported MapCSS keys.
+     */
+    public static final Set<String> SUPPORTED_KEYS = new HashSet<>();
+    static {
+        Field[] declaredFields = StyleKeys.class.getDeclaredFields();
+        for (Field f : declaredFields) {
+            try {
+                SUPPORTED_KEYS.add((String) f.get(null));
+                if (!f.getName().toLowerCase().replace("_", "-").equals(f.get(null))) {
+                    throw new RuntimeException(f.getName());
+                }
+            } catch (IllegalArgumentException | IllegalAccessException ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+        for (LineElemStyle.LineType lt : LineElemStyle.LineType.values()) {
+            SUPPORTED_KEYS.add(lt.prefix + StyleKeys.COLOR);
+            SUPPORTED_KEYS.add(lt.prefix + StyleKeys.DASHES);
+            SUPPORTED_KEYS.add(lt.prefix + StyleKeys.DASHES_BACKGROUND_COLOR);
+            SUPPORTED_KEYS.add(lt.prefix + StyleKeys.DASHES_BACKGROUND_OPACITY);
+            SUPPORTED_KEYS.add(lt.prefix + StyleKeys.DASHES_OFFSET);
+            SUPPORTED_KEYS.add(lt.prefix + StyleKeys.LINECAP);
+            SUPPORTED_KEYS.add(lt.prefix + StyleKeys.LINEJOIN);
+            SUPPORTED_KEYS.add(lt.prefix + StyleKeys.MITERLIMIT);
+            SUPPORTED_KEYS.add(lt.prefix + StyleKeys.OFFSET);
+            SUPPORTED_KEYS.add(lt.prefix + StyleKeys.OPACITY);
+            SUPPORTED_KEYS.add(lt.prefix + StyleKeys.REAL_WIDTH);
+            SUPPORTED_KEYS.add(lt.prefix + StyleKeys.WIDTH);
+        }
+    }
 
     /**
@@ -484,6 +519,7 @@
     }
 
-    public boolean evalMediaExpression(String feature, Object val) {
+    public boolean evalSupportsDeclCondition(String feature, Object val) {
         if (feature == null) return false;
+        if (SUPPORTED_KEYS.contains(feature)) return true;
         switch (feature) {
             case "user-agent":
