Configurable product attribute sort order in Dropdown 2.12

I faced the same attribute options sorting issue at front-end, As I checked this issue and found that while fetching the attribute options, there is no sorting filter added in the query by default in Magento 2.1.2, So to fix this issue need to add the below code to add the ORDER By in function getAttributeOptions on line no 282 in file: vendor/magento/module-configurable-product/Model/ResourceModel/Product/Type/Configurable.php Now, it's working fine for me.

->joinInner(
        ['attribute_opt' => $this->getTable('eav_attribute_option')],
        'attribute_opt.option_id = entity_value.value',
        []
    )->order(
        'attribute_opt.sort_order ASC'
    );

If unable to edit the code then please replace this getAttributeOptions function with code as below:

public function getAttributeOptions($superAttribute, $productId)
{
    $scope  = $this->getScopeResolver()->getScope();
    $select = $this->getConnection()->select()->from(
        ['super_attribute' => $this->getTable('catalog_product_super_attribute')],
        [
            'sku' => 'entity.sku',
            'product_id' => 'product_entity.entity_id',
            'attribute_code' => 'attribute.attribute_code',
            'value_index' => 'entity_value.value',
            'option_title' => $this->getConnection()->getIfNullSql(
                'option_value.value',
                'default_option_value.value'
            ),
            'default_title' => 'default_option_value.value',
        ]
    )->joinInner(
        ['product_entity' => $this->getTable('catalog_product_entity')],
        "product_entity.{$this->getProductEntityLinkField()} = super_attribute.product_id",
        []
    )->joinInner(
        ['product_link' => $this->getTable('catalog_product_super_link')],
        'product_link.parent_id = super_attribute.product_id',
        []
    )->joinInner(
        ['attribute' => $this->getTable('eav_attribute')],
        'attribute.attribute_id = super_attribute.attribute_id',
        []
    )->joinInner(
        ['entity' => $this->getTable('catalog_product_entity')],
        'entity.entity_id = product_link.product_id',
        []
    )->joinInner(
        ['entity_value' => $superAttribute->getBackendTable()],
        implode(
            ' AND ',
            [
                'entity_value.attribute_id = super_attribute.attribute_id',
                'entity_value.store_id = 0',
                "entity_value.{$this->getProductEntityLinkField()} = "
                . "entity.{$this->getProductEntityLinkField()}",
            ]
        ),
        []
    )->joinLeft(
        ['option_value' => $this->getTable('eav_attribute_option_value')],
        implode(
            ' AND ',
            [
                'option_value.option_id = entity_value.value',
                'option_value.store_id = ' . $scope->getId(),
            ]
        ),
        []
    )->joinLeft(
        ['default_option_value' => $this->getTable('eav_attribute_option_value')],
        implode(
            ' AND ',
            [
                'default_option_value.option_id = entity_value.value',
                'default_option_value.store_id = ' . \Magento\Store\Model\Store::DEFAULT_STORE_ID,
            ]
        ),
        []
    )->where(
        'super_attribute.product_id = ?',
        $productId
    )->where(
        'attribute.attribute_id = ?',
        $superAttribute->getAttributeId()
    )->joinInner(
        ['attribute_opt' => $this->getTable('eav_attribute_option')],
        'attribute_opt.option_id = entity_value.value',
        []
    )->order(
        'attribute_opt.sort_order ASC'
    );

    return $this->getConnection()->fetchAll($select);
}

  1. Go to Configurable product page -> Edit Configuration -> Click next -next - next and don't change anything
  2. Then save the product and they should be in order.

In v2.3.x you can sort the order of the attributes by option label in a configurable product drop down selector by extending

Magento\ConfigurableProduct\Model\AttributeOptionProvider

and using

usort($data, function($a, $b) {
    return $a['option_title'] <=> $b['option_title'];
});

To sort the returned option data array $data in method getAttributeOptions() for a specific attribute i.e. color use

/**
* {@inheritdoc}
*/
public function getAttributeOptions(AbstractAttribute $superAttribute, $productId)
{
   $scope  = $this->scopeResolver->getScope();
   $select = $this->optionSelectBuilder->getSelect($superAttribute, $productId, $scope);
   $data = $this->attributeResource->getConnection()->fetchAll($select);

   $sortByOptionTitle=false;

   if ($superAttribute->getSourceModel()) {
       $options = $superAttribute->getSource()->getAllOptions(false);

       $optionLabels = [];
       foreach ($options as $option) {
           $optionLabels[$option['value']] = $option['label'];
       }

       foreach ($data as $key => $value) {
           $optionText = isset($optionLabels[$value['value_index']])
               ? $optionLabels[$value['value_index']]
               : false;
           $data[$key]['default_title'] = $optionText;
           $data[$key]['option_title'] = $optionText;

           if (isset($data[$key]['attribute_code']))
           {
               if ($data[$key]['attribute_code']=='color')
               {
                   $sortByOptionTitle=true;
               }
           }
       }

       if ($sortByOptionTitle)
       {
           usort($data, function($a, $b) {
               return $a['option_title'] <=> $b['option_title'];
           });
       }
   }

   return $data;
}