Search code examples
csstextmarginphotoshoppsd

How to measure/convert CSS text margin/padding in the Photoshop?


How to get CSS text margin/padding from the Photoshop?

or

How to convert the distance from/to the text in Photoshop into CSS margin/padding?

Distances from text elements (paragraphs) in Photoshop do not correspond to margins/paddings in the CSS. Distances are measured, for example, using smart guides:

PS screenshot 0

All because the line height is not used in the distances calculation. Therefore, the first recommendation I found is to use the formula:

margin_in_CSS = distance_in_PS - (line-height - font-size) / 2

or shorter:

CSS = PS - (line-height - font-size) / 2

This is the distance from some obvious border (line) to the text element. For the distance between two paragraphs we use, respectively:

CSS = PS - (line-height_1 - font-size_1) / 2 - (line-height_2 - font-size_2) / 2

As the font size increases, it becomes clear that this formula is not enough. The actual height of the line (obtained with the selection tool) in Photoshop is even less than the font size!

PS screenshot 1

Although the photoshop still considers the height of the element to be approximately equal to the font size, which does not affect the distance to it :(. For example, on the Properties tab:

PS screenshot 2

I calculated that the difference between the real height of the line and the font size is about 30% or 15% at the top and bottom of the text (I'm not saying this is 100% true!). And now I use the formula:

CSS = PS - (0.15 * font-size + (line-height - font-size) / 2)

Or between two paragraphs:

CSS = PS - (0.15 * font-size_1 + (line-height_1 - font-size_1) / 2)
         - (0.15 * font-size_2 + (line-height_2 - font-size_2) / 2)

Similarly, we can not rely on the correct definition of the height of a paragraph in several lines by Photoshop. But here the situation is simpler, the real height of the paragraph in the CSS will be:

height = line-height * num_of_lines

The question is, is there a simpler way? О_о

Sorry for my English ^_^


UPDATE, shorter formulas:

text <> border

CSS = PS - (line-height - 0.7 * font-size) / 2

text <> text

CSS = PS - (line-height_1 - 0.7 * font-size_1) / 2
         - (line-height_2 - 0.7 * font-size_2) / 2

UPDATE:

Now a script is being developed for the correct calculation of distances on the Adobe forum (link). At the moment, the script can calculate the distance from the bounding box of the text line with a standard (auto) line-height of 120%.


UPDATE:

It does not matter if you use a pointed text or a paragraph text, the result bounding box height is not equal to the text line-height (leading)

bounding box height


Solution

  • Finally, the script for measuring vertical distance is finished! It can correctly calculate the vertical distance for CSS between layers, one of which or both are text layers.

    Here's the link on Adobe Forums - A script for measuring the distance between two elements?

    // version no CS6 or no effects
    
    var old_units = app.preferences.rulerUnits;    
    app.preferences.rulerUnits = Units.PIXELS;    
    
    try { app.activeDocument.suspendHistory("Get Text Bounds", "var bounds = get_selected_layers_bounds()") } catch(e) { alert(e); }  
    
    try { executeAction( charIDToTypeID( "undo" ), undefined, DialogModes.NO ); } catch(e) { alert(e); }  
    
    app.preferences.rulerUnits = old_units;    
    
    if (bounds)    
        {    
        if (bounds.length == 2)    
            {    
            var distance = 0;
    
            if (bounds[0].bottom <= bounds[1].top) distance = bounds[1].top - bounds[0].bottom;    
            else if (bounds[1].bottom <= bounds[0].top) distance = bounds[0].top - bounds[1].bottom;    
    
            else  alert("Intersecting layers")    
    
            var distance_in_css = distance - (bounds[0].leading - 1.2*bounds[0].size)/2 - (bounds[1].leading - 1.2*bounds[1].size)/2;
    
            alert("distance = " + distance + "\ndistance_in_css = " + distance_in_css);
            }    
        else    
            alert("More then 2 selected layers")     
    
        }    
    else     
        alert("There is no selected layers")     
    
    /////////////////////////////////////////////////////////////////////////////////////////////////    
    function get_selected_layers_bounds()    
        {    
        try {    
            var ref = new ActionReference();    
    
            ref.putProperty( charIDToTypeID( "Prpr" ), stringIDToTypeID( "targetLayers" ) );    
            ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );    
            var desc = executeActionGet(ref);    
    
            if (!desc.hasKey( stringIDToTypeID("targetLayers") ) ) return null;    
    
            var n = 0;    
            try { activeDocument.backgroundLayer } catch (e) { n = 1; }    
    
            desc = desc.getList( stringIDToTypeID("targetLayers"));    
    
            var len = desc.count;    
    
            var selected_bounds = new Array();    
    
            for (var i = 0; i < len; i++)    
                {    
                try     
                    {    
                    var r = new ActionReference();    
                    r.putIndex( charIDToTypeID( "Lyr " ), desc.getReference(i).getIndex() + n);    
    
                    var ret = executeActionGet(r);    
    
                    var size    = 0;
                    var leading = 0;
    
                    if (ret.hasKey(stringIDToTypeID("textKey")))  
                        {  
                        var textStyleRangeList = ret.getObjectValue(stringIDToTypeID("textKey")).getList(charIDToTypeID("Txtt" ));
    
                        if (textStyleRangeList.count > 1) { alert("More than one textStyleRange in layer", "Oops!!"); }
    
                        var textStyle = textStyleRangeList.getObjectValue(0).getObjectValue(charIDToTypeID("TxtS" ));
    
                        var auto_leading = textStyle.getBoolean(stringIDToTypeID("autoLeading"));
    
                        size = textStyle.getUnitDoubleValue(stringIDToTypeID("size"));
                        leading = auto_leading?size*1.2:textStyle.getUnitDoubleValue(stringIDToTypeID("leading"));
    
                        var s = ret.getObjectValue(stringIDToTypeID("textKey")).getString(charIDToTypeID("Txt " ));  
                        s = s.replace(/^./gm, String.fromCharCode(0x2588));  
    
                        var d1 = new ActionDescriptor();  
                        d1.putReference( charIDToTypeID( "null" ), r );  
    
                        var d2 = new ActionDescriptor();  
                        d2.putString( charIDToTypeID( "Txt " ), s);  
    
                        d1.putObject( charIDToTypeID( "T   " ), charIDToTypeID( "TxLr" ), d2 );  
    
                        executeAction( charIDToTypeID( "setd" ), d1, DialogModes.NO );  
    
                        ret = executeActionGet(r);    
                        }  
    
    
                    // var bounds = ret.getObjectValue(stringIDToTypeID("bounds"));  // use this in CS6 or when you want to take into account the effects    
    
                    var bounds = ret.getObjectValue(stringIDToTypeID("boundsNoEffects")); // in CS6 does not work    
    
                    var obj = { 
                              left   : bounds.getUnitDoubleValue(stringIDToTypeID("left")),    
                              top    : bounds.getUnitDoubleValue(stringIDToTypeID("top")),    
                              right  : bounds.getUnitDoubleValue(stringIDToTypeID("right")),    
                              bottom : bounds.getUnitDoubleValue(stringIDToTypeID("bottom")),
                              size   : size,
                              leading: leading,
                              };    
    
                        selected_bounds.push(obj);    
                    }
    
                    catch (e) { alert(e); return null; }    
                }    
    
                return selected_bounds;    
            }    
    
        catch (e) { alert(e); return null; }    
    }
    

    The script should be saved as a *.js or *.jsx file (for example, distance.js) in the Photoshop folder - C:\Program Files\Adobe\Adobe Photoshop CC 2017\Presets\Scripts

    It will be available in the Photoshop menu - File > Scripts > Distance