(How) can I return the most specific row on a join?
This makes some assumptions but it will do:

SELECT
    prd.id, prd.height, prd.fabric,
    MAX(pri.price) AS price
FROM
    products AS prd
  JOIN
    prices AS pri
      ON  (prd.height &gt;= pri.min_ht OR pri.min_ht IS NULL)
      AND (prd.fabric =  pri.fabric OR pri.fabric IS NULL) 
GROUP BY
    prd.id ;


The above assumes that the more details a pricing has, the higher the price is. Since that is not the case, a different, more general approach:

SELECT
    prd.id, prd.height, prd.fabric,
    pri.price
FROM
    products AS prd
  , LATERAL
    ( SELECT p.price
      FROM prices AS p
      WHERE (prd.height &gt; p.min_ht OR p.min_ht IS NULL)
        AND (prd.fabric = p.fabric OR p.fabric IS NULL) 
      ORDER BY
          ((p.min_ht IS NOT NULL)::int + (p.fabric IS NOT NULL)::int) DESC
      LIMIT 1
    ) AS pri ;


Tested at SQL-Fiddle